blob: 04d2dc7097a1a5915dbbe84305f7b78e0c858765 [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
Kailang Yangdf694da2005-12-05 19:42:22 +010044/* for GPIO Poll */
45#define GPIO_MASK 0x03
46
Takashi Iwai4a79ba32009-04-22 16:31:35 +020047/* extra amp-initialization sequence types */
48enum {
49 ALC_INIT_NONE,
50 ALC_INIT_DEFAULT,
51 ALC_INIT_GPIO1,
52 ALC_INIT_GPIO2,
53 ALC_INIT_GPIO3,
54};
55
David Henningsson73bdd592013-04-15 15:44:14 +020056enum {
57 ALC_HEADSET_MODE_UNKNOWN,
58 ALC_HEADSET_MODE_UNPLUGGED,
59 ALC_HEADSET_MODE_HEADSET,
60 ALC_HEADSET_MODE_MIC,
61 ALC_HEADSET_MODE_HEADPHONE,
62};
63
64enum {
65 ALC_HEADSET_TYPE_UNKNOWN,
66 ALC_HEADSET_TYPE_CTIA,
67 ALC_HEADSET_TYPE_OMTP,
68};
69
Hui Wangc7b60a82015-12-28 11:35:25 +080070enum {
71 ALC_KEY_MICMUTE_INDEX,
72};
73
Kailang Yangda00c242010-03-19 11:23:45 +010074struct alc_customize_define {
75 unsigned int sku_cfg;
76 unsigned char port_connectivity;
77 unsigned char check_sum;
78 unsigned char customization;
79 unsigned char external_amp;
80 unsigned int enable_pcbeep:1;
81 unsigned int platform_type:1;
82 unsigned int swap:1;
83 unsigned int override:1;
David Henningsson90622912010-10-14 14:50:18 +020084 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
Kailang Yangda00c242010-03-19 11:23:45 +010085};
86
Linus Torvalds1da177e2005-04-16 15:20:36 -070087struct alc_spec {
Takashi Iwai08c189f2012-12-19 15:22:24 +010088 struct hda_gen_spec gen; /* must be at head */
Takashi Iwai23d30f22012-05-07 17:17:32 +020089
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 /* codec parameterization */
Takashi Iwaia9111322011-05-02 11:30:18 +020091 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 unsigned int num_mixers;
Takashi Iwai45bdd1c2009-02-06 16:11:25 +010093 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Kailang Yangda00c242010-03-19 11:23:45 +010095 struct alc_customize_define cdefine;
Takashi Iwai08c189f2012-12-19 15:22:24 +010096 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
97
Takashi Iwai08fb0d02013-01-10 17:33:58 +010098 /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
99 int mute_led_polarity;
100 hda_nid_t mute_led_nid;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +0800101 hda_nid_t cap_mute_led_nid;
Takashi Iwai08fb0d02013-01-10 17:33:58 +0100102
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100103 unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
Takashi Iwai0f32fd192014-11-19 12:16:14 +0100104 unsigned int gpio_mute_led_mask;
105 unsigned int gpio_mic_led_mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +0100106
David Henningsson73bdd592013-04-15 15:44:14 +0200107 hda_nid_t headset_mic_pin;
108 hda_nid_t headphone_mic_pin;
109 int current_headset_mode;
110 int current_headset_type;
111
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100112 /* hooks */
113 void (*init_hook)(struct hda_codec *codec);
Takashi Iwai83012a72012-08-24 18:38:08 +0200114#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500115 void (*power_hook)(struct hda_codec *codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100116#endif
Takashi Iwai1c716152011-04-07 10:37:16 +0200117 void (*shutup)(struct hda_codec *codec);
Takashi Iwai70a09762015-12-15 14:59:58 +0100118 void (*reboot_notify)(struct hda_codec *codec);
Takashi Iwaid922b512011-04-28 12:18:53 +0200119
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200120 int init_amp;
Takashi Iwaid433a672010-09-20 15:11:54 +0200121 int codec_variant; /* flag for other variants */
Kailang Yang97a26572013-11-29 00:35:26 -0500122 unsigned int has_alc5505_dsp:1;
123 unsigned int no_depop_delay:1;
Takashi Iwaie64f14f2009-01-20 18:32:55 +0100124
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200125 /* for PLL fix */
126 hda_nid_t pll_nid;
127 unsigned int pll_coef_idx, pll_coef_bit;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200128 unsigned int coef0;
David Henningsson33f4acd2015-01-07 15:50:13 +0100129 struct input_dev *kb_dev;
Hui Wangc7b60a82015-12-28 11:35:25 +0800130 u8 alc_mute_keycode_map[1];
Kailang Yangdf694da2005-12-05 19:42:22 +0100131};
132
Takashi Iwai23f0c042009-02-26 13:03:58 +0100133/*
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200134 * COEF access helper functions
135 */
136
137static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
138 unsigned int coef_idx)
139{
140 unsigned int val;
141
142 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
143 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
144 return val;
145}
146
147#define alc_read_coef_idx(codec, coef_idx) \
148 alc_read_coefex_idx(codec, 0x20, coef_idx)
149
150static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
151 unsigned int coef_idx, unsigned int coef_val)
152{
153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
154 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
155}
156
157#define alc_write_coef_idx(codec, coef_idx, coef_val) \
158 alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
159
Takashi Iwai98b24882014-08-18 13:47:50 +0200160static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
161 unsigned int coef_idx, unsigned int mask,
162 unsigned int bits_set)
163{
164 unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
165
166 if (val != -1)
167 alc_write_coefex_idx(codec, nid, coef_idx,
168 (val & ~mask) | bits_set);
169}
170
171#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \
172 alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
173
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200174/* a special bypass for COEF 0; read the cached value at the second time */
175static unsigned int alc_get_coef0(struct hda_codec *codec)
176{
177 struct alc_spec *spec = codec->spec;
178
179 if (!spec->coef0)
180 spec->coef0 = alc_read_coef_idx(codec, 0);
181 return spec->coef0;
182}
183
Takashi Iwai54db6c32014-08-18 15:11:19 +0200184/* coef writes/updates batch */
185struct coef_fw {
186 unsigned char nid;
187 unsigned char idx;
188 unsigned short mask;
189 unsigned short val;
190};
191
192#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
193 { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
194#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
195#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
196#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
197
198static void alc_process_coef_fw(struct hda_codec *codec,
199 const struct coef_fw *fw)
200{
201 for (; fw->nid; fw++) {
202 if (fw->mask == (unsigned short)-1)
203 alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
204 else
205 alc_update_coefex_idx(codec, fw->nid, fw->idx,
206 fw->mask, fw->val);
207 }
208}
209
Takashi Iwaif2a227c2014-08-18 13:35:22 +0200210/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200211 * Append the given mixer and verb elements for the later use
212 * The mixer array is referred in build_controls(), and init_verbs are
213 * called in init().
Takashi Iwaid88897e2008-10-31 15:01:37 +0100214 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200215static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
Takashi Iwaid88897e2008-10-31 15:01:37 +0100216{
217 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
218 return;
219 spec->mixers[spec->num_mixers++] = mix;
220}
221
Takashi Iwaid88897e2008-10-31 15:01:37 +0100222/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200223 * GPIO setup tables, used in initialization
Kailang Yangdf694da2005-12-05 19:42:22 +0100224 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200225/* Enable GPIO mask and set output */
Takashi Iwaia9111322011-05-02 11:30:18 +0200226static const struct hda_verb alc_gpio1_init_verbs[] = {
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200227 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
228 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
229 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
230 { }
231};
232
Takashi Iwaia9111322011-05-02 11:30:18 +0200233static const struct hda_verb alc_gpio2_init_verbs[] = {
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200234 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
235 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
236 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
237 { }
238};
239
Takashi Iwaia9111322011-05-02 11:30:18 +0200240static const struct hda_verb alc_gpio3_init_verbs[] = {
Kailang Yangbdd148a2007-05-08 15:19:08 +0200241 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
242 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
243 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
244 { }
245};
246
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200247/*
248 * Fix hardware PLL issue
249 * On some codecs, the analog PLL gating control must be off while
250 * the default value is 1.
251 */
252static void alc_fix_pll(struct hda_codec *codec)
253{
254 struct alc_spec *spec = codec->spec;
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200255
Takashi Iwai98b24882014-08-18 13:47:50 +0200256 if (spec->pll_nid)
257 alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
258 1 << spec->pll_coef_bit, 0);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200259}
260
261static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
262 unsigned int coef_idx, unsigned int coef_bit)
263{
264 struct alc_spec *spec = codec->spec;
265 spec->pll_nid = nid;
266 spec->pll_coef_idx = coef_idx;
267 spec->pll_coef_bit = coef_bit;
268 alc_fix_pll(codec);
269}
270
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100271/* update the master volume per volume-knob's unsol event */
Takashi Iwai1a4f69d2014-09-11 15:22:46 +0200272static void alc_update_knob_master(struct hda_codec *codec,
273 struct hda_jack_callback *jack)
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100274{
275 unsigned int val;
276 struct snd_kcontrol *kctl;
277 struct snd_ctl_elem_value *uctl;
278
279 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
280 if (!kctl)
281 return;
282 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
283 if (!uctl)
284 return;
Takashi Iwai2ebab402016-02-09 10:23:52 +0100285 val = snd_hda_codec_read(codec, jack->nid, 0,
Takashi Iwaicf5a2272012-02-20 16:31:07 +0100286 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
287 val &= HDA_AMP_VOLMASK;
288 uctl->value.integer.value[0] = val;
289 uctl->value.integer.value[1] = val;
290 kctl->put(kctl, uctl);
291 kfree(uctl);
292}
293
David Henningsson29adc4b2012-09-25 11:31:00 +0200294static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100295{
David Henningsson29adc4b2012-09-25 11:31:00 +0200296 /* For some reason, the res given from ALC880 is broken.
297 Here we adjust it properly. */
298 snd_hda_jack_unsol_event(codec, res >> 2);
Takashi Iwaif21d78e2012-01-19 12:10:29 +0100299}
300
Kailang Yang394c97f2014-11-12 17:38:08 +0800301/* Change EAPD to verb control */
302static void alc_fill_eapd_coef(struct hda_codec *codec)
303{
304 int coef;
305
306 coef = alc_get_coef0(codec);
307
Takashi Iwai7639a062015-03-03 10:07:24 +0100308 switch (codec->core.vendor_id) {
Kailang Yang394c97f2014-11-12 17:38:08 +0800309 case 0x10ec0262:
310 alc_update_coef_idx(codec, 0x7, 0, 1<<5);
311 break;
312 case 0x10ec0267:
313 case 0x10ec0268:
314 alc_update_coef_idx(codec, 0x7, 0, 1<<13);
315 break;
316 case 0x10ec0269:
317 if ((coef & 0x00f0) == 0x0010)
318 alc_update_coef_idx(codec, 0xd, 0, 1<<14);
319 if ((coef & 0x00f0) == 0x0020)
320 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
321 if ((coef & 0x00f0) == 0x0030)
322 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
323 break;
324 case 0x10ec0280:
325 case 0x10ec0284:
326 case 0x10ec0290:
327 case 0x10ec0292:
328 alc_update_coef_idx(codec, 0x4, 1<<15, 0);
329 break;
Kailang Yang42314302016-02-03 15:03:50 +0800330 case 0x10ec0225:
Kailang Yang394c97f2014-11-12 17:38:08 +0800331 case 0x10ec0233:
Kailang Yangd197dfc2018-04-25 15:31:52 +0800332 case 0x10ec0235:
Kailang Yang61ae3fb2017-10-20 15:06:34 +0800333 case 0x10ec0236:
Kailang Yang394c97f2014-11-12 17:38:08 +0800334 case 0x10ec0255:
Kailang Yang4344aec2014-12-17 17:39:05 +0800335 case 0x10ec0256:
Kailang Yang2435d6b2017-12-05 15:38:24 +0800336 case 0x10ec0257:
Kailang Yang394c97f2014-11-12 17:38:08 +0800337 case 0x10ec0282:
338 case 0x10ec0283:
339 case 0x10ec0286:
340 case 0x10ec0288:
Kailang Yang7d727862016-05-24 16:46:07 +0800341 case 0x10ec0295:
Kailang Yang506b62c2014-12-18 17:07:44 +0800342 case 0x10ec0298:
Kailang Yangf6e94c22017-01-04 14:49:07 +0800343 case 0x10ec0299:
Kailang Yang394c97f2014-11-12 17:38:08 +0800344 alc_update_coef_idx(codec, 0x10, 1<<9, 0);
345 break;
346 case 0x10ec0285:
347 case 0x10ec0293:
348 alc_update_coef_idx(codec, 0xa, 1<<13, 0);
349 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800350 case 0x10ec0234:
351 case 0x10ec0274:
352 case 0x10ec0294:
Kailang Yang6fbae352016-05-30 16:44:20 +0800353 case 0x10ec0700:
354 case 0x10ec0701:
355 case 0x10ec0703:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +0800356 alc_update_coef_idx(codec, 0x10, 1<<15, 0);
357 break;
Kailang Yang394c97f2014-11-12 17:38:08 +0800358 case 0x10ec0662:
359 if ((coef & 0x00f0) == 0x0030)
360 alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
361 break;
362 case 0x10ec0272:
363 case 0x10ec0273:
364 case 0x10ec0663:
365 case 0x10ec0665:
366 case 0x10ec0670:
367 case 0x10ec0671:
368 case 0x10ec0672:
369 alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
370 break;
371 case 0x10ec0668:
372 alc_update_coef_idx(codec, 0x7, 3<<13, 0);
373 break;
374 case 0x10ec0867:
375 alc_update_coef_idx(codec, 0x4, 1<<10, 0);
376 break;
377 case 0x10ec0888:
378 if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
379 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
380 break;
381 case 0x10ec0892:
382 alc_update_coef_idx(codec, 0x7, 1<<5, 0);
383 break;
384 case 0x10ec0899:
385 case 0x10ec0900:
386 alc_update_coef_idx(codec, 0x7, 1<<1, 0);
387 break;
388 }
389}
390
Kailang Yangf9423e72008-05-27 12:32:25 +0200391/* additional initialization for ALC888 variants */
392static void alc888_coef_init(struct hda_codec *codec)
393{
Kailang Yang1df88742014-10-29 16:10:13 +0800394 switch (alc_get_coef0(codec) & 0x00f0) {
395 /* alc888-VA */
396 case 0x00:
397 /* alc888-VB */
398 case 0x10:
399 alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
400 break;
401 }
Jaroslav Kysela87a8c372009-07-23 10:58:29 +0200402}
403
Takashi Iwai3fb4a502010-01-19 15:46:37 +0100404/* turn on/off EAPD control (only if available) */
405static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
406{
407 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
408 return;
409 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
410 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
411 on ? 2 : 0);
412}
413
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200414/* turn on/off EAPD controls of the codec */
415static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
416{
417 /* We currently only handle front, HP */
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200418 static hda_nid_t pins[] = {
Hui Wangaf95b412015-03-26 17:14:55 +0800419 0x0f, 0x10, 0x14, 0x15, 0x17, 0
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200420 };
421 hda_nid_t *p;
422 for (p = pins; *p; p++)
423 set_eapd(codec, *p, on);
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200424}
425
Takashi Iwai1c716152011-04-07 10:37:16 +0200426/* generic shutup callback;
427 * just turning off EPAD and a little pause for avoiding pop-noise
428 */
429static void alc_eapd_shutup(struct hda_codec *codec)
430{
Kailang Yang97a26572013-11-29 00:35:26 -0500431 struct alc_spec *spec = codec->spec;
432
Takashi Iwai1c716152011-04-07 10:37:16 +0200433 alc_auto_setup_eapd(codec, false);
Kailang Yang97a26572013-11-29 00:35:26 -0500434 if (!spec->no_depop_delay)
435 msleep(200);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200436 snd_hda_shutup_pins(codec);
Takashi Iwai1c716152011-04-07 10:37:16 +0200437}
438
Takashi Iwai1d045db2011-07-07 18:23:21 +0200439/* generic EAPD initialization */
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200440static void alc_auto_init_amp(struct hda_codec *codec, int type)
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200441{
Kailang Yang394c97f2014-11-12 17:38:08 +0800442 alc_fill_eapd_coef(codec);
Takashi Iwai39fa84e2011-06-27 15:28:57 +0200443 alc_auto_setup_eapd(codec, true);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200444 switch (type) {
445 case ALC_INIT_GPIO1:
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200446 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
447 break;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200448 case ALC_INIT_GPIO2:
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200449 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
450 break;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200451 case ALC_INIT_GPIO3:
Kailang Yangbdd148a2007-05-08 15:19:08 +0200452 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
453 break;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200454 case ALC_INIT_DEFAULT:
Takashi Iwai7639a062015-03-03 10:07:24 +0100455 switch (codec->core.vendor_id) {
Kailang Yangc9b58002007-10-16 14:30:01 +0200456 case 0x10ec0260:
Takashi Iwai98b24882014-08-18 13:47:50 +0200457 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
Kailang Yangc9b58002007-10-16 14:30:01 +0200458 break;
Kailang Yangc9b58002007-10-16 14:30:01 +0200459 case 0x10ec0880:
460 case 0x10ec0882:
461 case 0x10ec0883:
462 case 0x10ec0885:
Kailang Yang1df88742014-10-29 16:10:13 +0800463 alc_update_coef_idx(codec, 7, 0, 0x2030);
Kailang Yangc9b58002007-10-16 14:30:01 +0200464 break;
Kailang Yangf9423e72008-05-27 12:32:25 +0200465 case 0x10ec0888:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200466 alc888_coef_init(codec);
Kailang Yangf9423e72008-05-27 12:32:25 +0200467 break;
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200468 }
Kailang Yangbc9f98a2007-04-12 13:06:07 +0200469 break;
470 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200471}
Kailang Yangea1fb292008-08-26 12:58:38 +0200472
Takashi Iwai1d045db2011-07-07 18:23:21 +0200473
474/*
475 * Realtek SSID verification
476 */
477
David Henningsson90622912010-10-14 14:50:18 +0200478/* Could be any non-zero and even value. When used as fixup, tells
479 * the driver to ignore any present sku defines.
480 */
481#define ALC_FIXUP_SKU_IGNORE (2)
482
Takashi Iwai23d30f22012-05-07 17:17:32 +0200483static void alc_fixup_sku_ignore(struct hda_codec *codec,
484 const struct hda_fixup *fix, int action)
485{
486 struct alc_spec *spec = codec->spec;
487 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
488 spec->cdefine.fixup = 1;
489 spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
490 }
491}
492
Mengdong Linb5c66112013-11-29 00:35:35 -0500493static void alc_fixup_no_depop_delay(struct hda_codec *codec,
494 const struct hda_fixup *fix, int action)
495{
496 struct alc_spec *spec = codec->spec;
497
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500498 if (action == HDA_FIXUP_ACT_PROBE) {
Mengdong Linb5c66112013-11-29 00:35:35 -0500499 spec->no_depop_delay = 1;
Mengdong Lin84d2dc32013-12-02 22:26:03 -0500500 codec->depop_delay = 0;
501 }
Mengdong Linb5c66112013-11-29 00:35:35 -0500502}
503
Kailang Yangda00c242010-03-19 11:23:45 +0100504static int alc_auto_parse_customize_define(struct hda_codec *codec)
505{
506 unsigned int ass, tmp, i;
Takashi Iwai7fb56222010-03-22 17:09:47 +0100507 unsigned nid = 0;
Kailang Yangda00c242010-03-19 11:23:45 +0100508 struct alc_spec *spec = codec->spec;
509
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200510 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
511
David Henningsson90622912010-10-14 14:50:18 +0200512 if (spec->cdefine.fixup) {
513 ass = spec->cdefine.sku_cfg;
514 if (ass == ALC_FIXUP_SKU_IGNORE)
515 return -1;
516 goto do_sku;
517 }
518
Takashi Iwai5100cd02014-02-15 10:03:19 +0100519 if (!codec->bus->pci)
520 return -1;
Takashi Iwai7639a062015-03-03 10:07:24 +0100521 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwaib6cbe512010-07-28 17:43:36 +0200522 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
Kailang Yangda00c242010-03-19 11:23:45 +0100523 goto do_sku;
524
525 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100526 if (codec->core.vendor_id == 0x10ec0260)
Kailang Yangda00c242010-03-19 11:23:45 +0100527 nid = 0x17;
528 ass = snd_hda_codec_get_pincfg(codec, nid);
529
530 if (!(ass & 1)) {
Takashi Iwai4e76a882014-02-25 12:21:03 +0100531 codec_info(codec, "%s: SKU not ready 0x%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100532 codec->core.chip_name, ass);
Kailang Yangda00c242010-03-19 11:23:45 +0100533 return -1;
534 }
535
536 /* check sum */
537 tmp = 0;
538 for (i = 1; i < 16; i++) {
539 if ((ass >> i) & 1)
540 tmp++;
541 }
542 if (((ass >> 16) & 0xf) != tmp)
543 return -1;
544
545 spec->cdefine.port_connectivity = ass >> 30;
546 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
547 spec->cdefine.check_sum = (ass >> 16) & 0xf;
548 spec->cdefine.customization = ass >> 8;
549do_sku:
550 spec->cdefine.sku_cfg = ass;
551 spec->cdefine.external_amp = (ass & 0x38) >> 3;
552 spec->cdefine.platform_type = (ass & 0x4) >> 2;
553 spec->cdefine.swap = (ass & 0x2) >> 1;
554 spec->cdefine.override = ass & 0x1;
555
Takashi Iwai4e76a882014-02-25 12:21:03 +0100556 codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100557 nid, spec->cdefine.sku_cfg);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100558 codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
Kailang Yangda00c242010-03-19 11:23:45 +0100559 spec->cdefine.port_connectivity);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100560 codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
561 codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
562 codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
563 codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
564 codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
565 codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
566 codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
Kailang Yangda00c242010-03-19 11:23:45 +0100567
568 return 0;
569}
570
Takashi Iwai08c189f2012-12-19 15:22:24 +0100571/* return the position of NID in the list, or -1 if not found */
572static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
573{
574 int i;
575 for (i = 0; i < nums; i++)
576 if (list[i] == nid)
577 return i;
578 return -1;
579}
Takashi Iwai1d045db2011-07-07 18:23:21 +0200580/* return true if the given NID is found in the list */
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200581static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
582{
Takashi Iwai21268962011-07-07 15:01:13 +0200583 return find_idx_in_nid_list(nid, list, nums) >= 0;
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200584}
585
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200586/* check subsystem ID and set up device-specific initialization;
587 * return 1 if initialized, 0 if invalid SSID
588 */
589/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
590 * 31 ~ 16 : Manufacture ID
591 * 15 ~ 8 : SKU ID
592 * 7 ~ 0 : Assembly ID
593 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
594 */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100595static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200596{
597 unsigned int ass, tmp, i;
598 unsigned nid;
599 struct alc_spec *spec = codec->spec;
600
David Henningsson90622912010-10-14 14:50:18 +0200601 if (spec->cdefine.fixup) {
602 ass = spec->cdefine.sku_cfg;
603 if (ass == ALC_FIXUP_SKU_IGNORE)
604 return 0;
605 goto do_sku;
606 }
607
Takashi Iwai7639a062015-03-03 10:07:24 +0100608 ass = codec->core.subsystem_id & 0xffff;
Takashi Iwai5100cd02014-02-15 10:03:19 +0100609 if (codec->bus->pci &&
610 ass != codec->bus->pci->subsystem_device && (ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200611 goto do_sku;
612
613 /* invalid SSID, check the special NID pin defcfg instead */
614 /*
Sasha Alexandrdef319f2009-06-16 16:00:15 -0400615 * 31~30 : port connectivity
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200616 * 29~21 : reserve
617 * 20 : PCBEEP input
618 * 19~16 : Check sum (15:1)
619 * 15~1 : Custom
620 * 0 : override
621 */
622 nid = 0x1d;
Takashi Iwai7639a062015-03-03 10:07:24 +0100623 if (codec->core.vendor_id == 0x10ec0260)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200624 nid = 0x17;
625 ass = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai4e76a882014-02-25 12:21:03 +0100626 codec_dbg(codec,
627 "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
Takashi Iwaicb6605c2009-04-28 13:03:19 +0200628 ass, nid);
Kailang Yang6227cdc2010-02-25 08:36:52 +0100629 if (!(ass & 1))
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200630 return 0;
631 if ((ass >> 30) != 1) /* no physical connection */
632 return 0;
633
634 /* check sum */
635 tmp = 0;
636 for (i = 1; i < 16; i++) {
637 if ((ass >> i) & 1)
638 tmp++;
639 }
640 if (((ass >> 16) & 0xf) != tmp)
641 return 0;
642do_sku:
Takashi Iwai4e76a882014-02-25 12:21:03 +0100643 codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
Takashi Iwai7639a062015-03-03 10:07:24 +0100644 ass & 0xffff, codec->core.vendor_id);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200645 /*
646 * 0 : override
647 * 1 : Swap Jack
648 * 2 : 0 --> Desktop, 1 --> Laptop
649 * 3~5 : External Amplifier control
650 * 7~6 : Reserved
651 */
652 tmp = (ass & 0x38) >> 3; /* external Amp control */
653 switch (tmp) {
654 case 1:
655 spec->init_amp = ALC_INIT_GPIO1;
656 break;
657 case 3:
658 spec->init_amp = ALC_INIT_GPIO2;
659 break;
660 case 7:
661 spec->init_amp = ALC_INIT_GPIO3;
662 break;
663 case 5:
Takashi Iwai5a8cfb42010-11-26 17:11:18 +0100664 default:
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200665 spec->init_amp = ALC_INIT_DEFAULT;
666 break;
667 }
668
669 /* is laptop or Desktop and enable the function "Mute internal speaker
670 * when the external headphone out jack is plugged"
671 */
672 if (!(ass & 0x8000))
673 return 1;
674 /*
675 * 10~8 : Jack location
676 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
677 * 14~13: Resvered
678 * 15 : 1 --> enable the function "Mute internal speaker
679 * when the external headphone out jack is plugged"
680 */
Takashi Iwai08c189f2012-12-19 15:22:24 +0100681 if (!spec->gen.autocfg.hp_pins[0] &&
682 !(spec->gen.autocfg.line_out_pins[0] &&
683 spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
Takashi Iwai01d48252009-10-06 13:21:54 +0200684 hda_nid_t nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200685 tmp = (ass >> 11) & 0x3; /* HP to chassis */
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100686 nid = ports[tmp];
Takashi Iwai08c189f2012-12-19 15:22:24 +0100687 if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
688 spec->gen.autocfg.line_outs))
Takashi Iwai3af9ee62011-06-27 12:34:01 +0200689 return 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +0100690 spec->gen.autocfg.hp_pins[0] = nid;
Kailang Yangc9b58002007-10-16 14:30:01 +0200691 }
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200692 return 1;
693}
Kailang Yangea1fb292008-08-26 12:58:38 +0200694
Takashi Iwai3e6179b2011-07-08 16:55:13 +0200695/* Check the validity of ALC subsystem-id
696 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
697static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200698{
Takashi Iwai58c57cf2014-01-07 18:22:49 +0100699 if (!alc_subsystem_id(codec, ports)) {
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200700 struct alc_spec *spec = codec->spec;
Takashi Iwai4e76a882014-02-25 12:21:03 +0100701 codec_dbg(codec,
702 "realtek: Enable default setup for auto mode as fallback\n");
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200703 spec->init_amp = ALC_INIT_DEFAULT;
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200704 }
Takashi Iwai21268962011-07-07 15:01:13 +0200705}
Takashi Iwai1a1455d2011-04-28 17:36:18 +0200706
Takashi Iwai41e41f12005-06-08 14:48:49 +0200707/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200708 */
709
David Henningsson9d36a7d2014-10-07 10:18:42 +0200710static void alc_fixup_inv_dmic(struct hda_codec *codec,
711 const struct hda_fixup *fix, int action)
Takashi Iwai125821a2012-06-22 14:30:29 +0200712{
713 struct alc_spec *spec = codec->spec;
Takashi Iwai668d1e92012-11-29 14:10:17 +0100714
David Henningsson9d36a7d2014-10-07 10:18:42 +0200715 spec->gen.inv_dmic_split = 1;
Takashi Iwai6e72aa52012-06-25 10:52:25 +0200716}
717
Takashi Iwai603c4012008-07-30 15:01:44 +0200718
Takashi Iwai67d634c2009-11-16 15:35:59 +0100719#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100720/* additional beep mixers; the actual parameters are overwritten at build */
Takashi Iwaia9111322011-05-02 11:30:18 +0200721static const struct snd_kcontrol_new alc_beep_mixer[] = {
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100722 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
Jaroslav Kysela123c07a2009-10-21 14:48:23 +0200723 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100724 { } /* end */
725};
Takashi Iwai67d634c2009-11-16 15:35:59 +0100726#endif
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100727
Takashi Iwai2eab6942012-12-18 15:30:41 +0100728static int alc_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729{
730 struct alc_spec *spec = codec->spec;
Takashi Iwai666a70d2012-12-17 20:29:29 +0100731 int i, err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
Takashi Iwai08c189f2012-12-19 15:22:24 +0100733 err = snd_hda_gen_build_controls(codec);
734 if (err < 0)
735 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736
737 for (i = 0; i < spec->num_mixers; i++) {
738 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
739 if (err < 0)
740 return err;
741 }
Takashi Iwai2134ea42008-01-10 16:53:55 +0100742
Takashi Iwai67d634c2009-11-16 15:35:59 +0100743#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100744 /* create beep controls if needed */
745 if (spec->beep_amp) {
Takashi Iwaia9111322011-05-02 11:30:18 +0200746 const struct snd_kcontrol_new *knew;
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100747 for (knew = alc_beep_mixer; knew->name; knew++) {
748 struct snd_kcontrol *kctl;
749 kctl = snd_ctl_new1(knew, codec);
750 if (!kctl)
751 return -ENOMEM;
752 kctl->private_value = spec->beep_amp;
Jaroslav Kysela5e26dfd2009-12-10 13:57:01 +0100753 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100754 if (err < 0)
755 return err;
756 }
757 }
Takashi Iwai67d634c2009-11-16 15:35:59 +0100758#endif
Takashi Iwai45bdd1c2009-02-06 16:11:25 +0100759
Takashi Iwai1727a772013-01-10 09:52:52 +0100760 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
Takashi Iwai420b0fe2012-03-12 12:35:27 +0100761 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762}
763
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200764
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765/*
Takashi Iwaiae6b8132006-03-03 16:47:17 +0100766 * Common callbacks
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200767 */
Takashi Iwai16ded522005-06-10 19:58:24 +0200768
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769static int alc_init(struct hda_codec *codec)
770{
771 struct alc_spec *spec = codec->spec;
Takashi Iwaie9edcee2005-06-13 14:16:38 +0200772
Takashi Iwai546bb672012-03-07 08:37:19 +0100773 if (spec->init_hook)
774 spec->init_hook(codec);
Kailang Yang526af6e2012-03-07 08:25:20 +0100775
Kailang Yang595a6a52019-04-26 16:35:41 +0800776 snd_hda_gen_init(codec);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200777 alc_fix_pll(codec);
Takashi Iwai4a79ba32009-04-22 16:31:35 +0200778 alc_auto_init_amp(codec, spec->init_amp);
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +0200779
Takashi Iwai1727a772013-01-10 09:52:52 +0100780 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
Takashi Iwaie08a0072006-09-07 17:52:14 +0200781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 return 0;
783}
784
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100785static inline void alc_shutup(struct hda_codec *codec)
786{
Takashi Iwai1c716152011-04-07 10:37:16 +0200787 struct alc_spec *spec = codec->spec;
788
789 if (spec && spec->shutup)
790 spec->shutup(codec);
Takashi Iwai9bfb2842013-07-24 14:31:50 +0200791 else
792 snd_hda_shutup_pins(codec);
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100793}
794
Takashi Iwai70a09762015-12-15 14:59:58 +0100795static void alc_reboot_notify(struct hda_codec *codec)
796{
797 struct alc_spec *spec = codec->spec;
798
799 if (spec && spec->reboot_notify)
800 spec->reboot_notify(codec);
801 else
802 alc_shutup(codec);
803}
804
805/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
806static void alc_d3_at_reboot(struct hda_codec *codec)
807{
808 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
809 snd_hda_codec_write(codec, codec->core.afg, 0,
810 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
811 msleep(10);
812}
813
Takashi Iwai8a02c0c2014-02-10 18:09:45 +0100814#define alc_free snd_hda_gen_free
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
Takashi Iwai83012a72012-08-24 18:38:08 +0200816#ifdef CONFIG_PM
Daniel T Chenc97259d2009-12-27 18:52:08 -0500817static void alc_power_eapd(struct hda_codec *codec)
818{
Takashi Iwai691f1fc2011-04-07 10:31:43 +0200819 alc_auto_setup_eapd(codec, false);
Daniel T Chenc97259d2009-12-27 18:52:08 -0500820}
821
Takashi Iwai68cb2b52012-07-02 15:20:37 +0200822static int alc_suspend(struct hda_codec *codec)
Hector Martinf5de24b2009-12-20 22:51:31 +0100823{
824 struct alc_spec *spec = codec->spec;
Takashi Iwaia4e09aa2009-12-27 11:22:24 +0100825 alc_shutup(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100826 if (spec && spec->power_hook)
Daniel T Chenc97259d2009-12-27 18:52:08 -0500827 spec->power_hook(codec);
Hector Martinf5de24b2009-12-20 22:51:31 +0100828 return 0;
829}
830#endif
831
Takashi Iwai2a439522011-07-26 09:52:50 +0200832#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100833static int alc_resume(struct hda_codec *codec)
834{
Kailang Yang97a26572013-11-29 00:35:26 -0500835 struct alc_spec *spec = codec->spec;
836
837 if (!spec->no_depop_delay)
838 msleep(150); /* to avoid pop noise */
Takashi Iwaie044c392008-10-27 16:56:24 +0100839 codec->patch_ops.init(codec);
Takashi Iwaieeecd9d2015-02-25 15:18:50 +0100840 regcache_sync(codec->core.regmap);
Takashi Iwai9e5341b2010-09-21 09:57:06 +0200841 hda_call_check_power_status(codec, 0x01);
Takashi Iwaie044c392008-10-27 16:56:24 +0100842 return 0;
843}
Takashi Iwaie044c392008-10-27 16:56:24 +0100844#endif
845
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846/*
847 */
Takashi Iwaia9111322011-05-02 11:30:18 +0200848static const struct hda_codec_ops alc_patch_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 .build_controls = alc_build_controls,
Takashi Iwai08c189f2012-12-19 15:22:24 +0100850 .build_pcms = snd_hda_gen_build_pcms,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 .init = alc_init,
852 .free = alc_free,
David Henningsson29adc4b2012-09-25 11:31:00 +0200853 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai2a439522011-07-26 09:52:50 +0200854#ifdef CONFIG_PM
Takashi Iwaie044c392008-10-27 16:56:24 +0100855 .resume = alc_resume,
Hector Martinf5de24b2009-12-20 22:51:31 +0100856 .suspend = alc_suspend,
Takashi Iwaifce52a32013-01-07 12:42:48 +0100857 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +0200858#endif
Takashi Iwai70a09762015-12-15 14:59:58 +0100859 .reboot_notify = alc_reboot_notify,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860};
861
David Henningsson29adc4b2012-09-25 11:31:00 +0200862
Takashi Iwaided255b2015-10-01 17:59:43 +0200863#define alc_codec_rename(codec, name) snd_hda_codec_set_name(codec, name)
Kailang Yangc027ddc2010-03-19 11:33:06 +0100864
Takashi Iwai2fa522b2005-05-12 14:51:12 +0200865/*
Kailang Yang4b016932013-11-28 11:55:09 +0100866 * Rename codecs appropriately from COEF value or subvendor id
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200867 */
868struct alc_codec_rename_table {
869 unsigned int vendor_id;
870 unsigned short coef_mask;
871 unsigned short coef_bits;
872 const char *name;
873};
874
Kailang Yang4b016932013-11-28 11:55:09 +0100875struct alc_codec_rename_pci_table {
876 unsigned int codec_vendor_id;
877 unsigned short pci_subvendor;
878 unsigned short pci_subdevice;
879 const char *name;
880};
881
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200882static struct alc_codec_rename_table rename_tbl[] = {
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800883 { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200884 { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
885 { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
886 { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
887 { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
888 { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
889 { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
890 { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
Kailang Yangadcc70b2012-05-25 08:08:38 +0200891 { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800892 { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200893 { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
894 { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
895 { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
896 { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
897 { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
898 { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
899 { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
900 { } /* terminator */
901};
902
Kailang Yang4b016932013-11-28 11:55:09 +0100903static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
904 { 0x10ec0280, 0x1028, 0, "ALC3220" },
905 { 0x10ec0282, 0x1028, 0, "ALC3221" },
906 { 0x10ec0283, 0x1028, 0, "ALC3223" },
Kailang Yang193177d2014-04-23 16:06:13 +0800907 { 0x10ec0288, 0x1028, 0, "ALC3263" },
Kailang Yang4b016932013-11-28 11:55:09 +0100908 { 0x10ec0292, 0x1028, 0, "ALC3226" },
Kailang Yang193177d2014-04-23 16:06:13 +0800909 { 0x10ec0293, 0x1028, 0, "ALC3235" },
Kailang Yang4b016932013-11-28 11:55:09 +0100910 { 0x10ec0255, 0x1028, 0, "ALC3234" },
911 { 0x10ec0668, 0x1028, 0, "ALC3661" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800912 { 0x10ec0275, 0x1028, 0, "ALC3260" },
913 { 0x10ec0899, 0x1028, 0, "ALC3861" },
Kailang Yang2c674fa2015-05-05 15:02:42 +0800914 { 0x10ec0298, 0x1028, 0, "ALC3266" },
Kailang Yang61ae3fb2017-10-20 15:06:34 +0800915 { 0x10ec0236, 0x1028, 0, "ALC3204" },
Kailang Yang82324502015-05-25 17:16:49 +0800916 { 0x10ec0256, 0x1028, 0, "ALC3246" },
Kailang Yang42314302016-02-03 15:03:50 +0800917 { 0x10ec0225, 0x1028, 0, "ALC3253" },
Kailang Yang7d727862016-05-24 16:46:07 +0800918 { 0x10ec0295, 0x1028, 0, "ALC3254" },
Kailang Yangf6e94c22017-01-04 14:49:07 +0800919 { 0x10ec0299, 0x1028, 0, "ALC3271" },
Kailang Yange6e5f7a2014-06-06 16:46:43 +0800920 { 0x10ec0670, 0x1025, 0, "ALC669X" },
921 { 0x10ec0676, 0x1025, 0, "ALC679X" },
922 { 0x10ec0282, 0x1043, 0, "ALC3229" },
923 { 0x10ec0233, 0x1043, 0, "ALC3236" },
924 { 0x10ec0280, 0x103c, 0, "ALC3228" },
925 { 0x10ec0282, 0x103c, 0, "ALC3227" },
926 { 0x10ec0286, 0x103c, 0, "ALC3242" },
927 { 0x10ec0290, 0x103c, 0, "ALC3241" },
928 { 0x10ec0668, 0x103c, 0, "ALC3662" },
929 { 0x10ec0283, 0x17aa, 0, "ALC3239" },
930 { 0x10ec0292, 0x17aa, 0, "ALC3232" },
Kailang Yang4b016932013-11-28 11:55:09 +0100931 { } /* terminator */
932};
933
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200934static int alc_codec_rename_from_preset(struct hda_codec *codec)
935{
936 const struct alc_codec_rename_table *p;
Kailang Yang4b016932013-11-28 11:55:09 +0100937 const struct alc_codec_rename_pci_table *q;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200938
939 for (p = rename_tbl; p->vendor_id; p++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100940 if (p->vendor_id != codec->core.vendor_id)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200941 continue;
Takashi Iwai1bb7e432011-10-17 16:50:59 +0200942 if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200943 return alc_codec_rename(codec, p->name);
944 }
Kailang Yang4b016932013-11-28 11:55:09 +0100945
Takashi Iwai5100cd02014-02-15 10:03:19 +0100946 if (!codec->bus->pci)
947 return 0;
Kailang Yang4b016932013-11-28 11:55:09 +0100948 for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
Takashi Iwai7639a062015-03-03 10:07:24 +0100949 if (q->codec_vendor_id != codec->core.vendor_id)
Kailang Yang4b016932013-11-28 11:55:09 +0100950 continue;
951 if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
952 continue;
953 if (!q->pci_subdevice ||
954 q->pci_subdevice == codec->bus->pci->subsystem_device)
955 return alc_codec_rename(codec, q->name);
956 }
957
Takashi Iwaie16fb6d2011-10-17 16:39:09 +0200958 return 0;
959}
960
Takashi Iwaie4770622011-07-08 11:11:35 +0200961
962/*
Takashi Iwai1d045db2011-07-07 18:23:21 +0200963 * Digital-beep handlers
964 */
965#ifdef CONFIG_SND_HDA_INPUT_BEEP
966#define set_beep_amp(spec, nid, idx, dir) \
967 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
968
969static const struct snd_pci_quirk beep_white_list[] = {
Duncan Roe71100052012-10-10 14:19:50 +0200970 SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
W. Trevor Kinga4b7f212014-03-29 17:47:24 -0700971 SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +0200972 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
Takashi Iwai8554ee42013-02-25 09:54:43 +0100973 SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +0200974 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
975 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
976 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
Takashi Iwai78f8baf2012-03-06 14:02:32 +0100977 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
Takashi Iwai1d045db2011-07-07 18:23:21 +0200978 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
979 {}
980};
981
982static inline int has_cdefine_beep(struct hda_codec *codec)
983{
984 struct alc_spec *spec = codec->spec;
985 const struct snd_pci_quirk *q;
986 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
987 if (q)
988 return q->value;
989 return spec->cdefine.enable_pcbeep;
990}
991#else
992#define set_beep_amp(spec, nid, idx, dir) /* NOP */
993#define has_cdefine_beep(codec) 0
994#endif
995
996/* parse the BIOS configuration and set up the alc_spec */
997/* return 1 if successful, 0 if the proper config is not found,
998 * or a negative error code
999 */
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001000static int alc_parse_auto_config(struct hda_codec *codec,
1001 const hda_nid_t *ignore_nids,
1002 const hda_nid_t *ssid_nids)
Takashi Iwai1d045db2011-07-07 18:23:21 +02001003{
1004 struct alc_spec *spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001005 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001006 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001007
Takashi Iwai53c334a2011-08-23 18:27:14 +02001008 err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1009 spec->parse_flags);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001010 if (err < 0)
1011 return err;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001012
1013 if (ssid_nids)
1014 alc_ssid_check(codec, ssid_nids);
1015
Takashi Iwai08c189f2012-12-19 15:22:24 +01001016 err = snd_hda_gen_parse_auto_config(codec, cfg);
1017 if (err < 0)
1018 return err;
Takashi Iwai070cff42012-02-21 12:54:17 +01001019
Takashi Iwai1d045db2011-07-07 18:23:21 +02001020 return 1;
1021}
1022
Takashi Iwai3de95172012-05-07 18:03:15 +02001023/* common preparation job for alc_spec */
1024static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1025{
1026 struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1027 int err;
1028
1029 if (!spec)
1030 return -ENOMEM;
1031 codec->spec = spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001032 snd_hda_gen_spec_init(&spec->gen);
1033 spec->gen.mixer_nid = mixer_nid;
1034 spec->gen.own_eapd_ctl = 1;
Takashi Iwai1098b7c2012-12-17 20:03:15 +01001035 codec->single_adc_amp = 1;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001036 /* FIXME: do we need this for all Realtek codec models? */
1037 codec->spdif_status_reset = 1;
Takashi Iwai225068a2015-05-29 10:42:14 +02001038 codec->patch_ops = alc_patch_ops;
Takashi Iwai3de95172012-05-07 18:03:15 +02001039
1040 err = alc_codec_rename_from_preset(codec);
1041 if (err < 0) {
1042 kfree(spec);
1043 return err;
1044 }
1045 return 0;
1046}
1047
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001048static int alc880_parse_auto_config(struct hda_codec *codec)
1049{
1050 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02001051 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001052 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1053}
1054
Takashi Iwai1d045db2011-07-07 18:23:21 +02001055/*
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001056 * ALC880 fix-ups
1057 */
1058enum {
Takashi Iwai411225a2012-02-20 17:48:19 +01001059 ALC880_FIXUP_GPIO1,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001060 ALC880_FIXUP_GPIO2,
1061 ALC880_FIXUP_MEDION_RIM,
Takashi Iwaidc6af522012-02-17 16:18:59 +01001062 ALC880_FIXUP_LG,
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001063 ALC880_FIXUP_LG_LW25,
Takashi Iwaif02aab52012-02-17 16:33:56 +01001064 ALC880_FIXUP_W810,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001065 ALC880_FIXUP_EAPD_COEF,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001066 ALC880_FIXUP_TCL_S700,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001067 ALC880_FIXUP_VOL_KNOB,
1068 ALC880_FIXUP_FUJITSU,
Takashi Iwaiba533812012-02-20 16:36:52 +01001069 ALC880_FIXUP_F1734,
Takashi Iwai817de922012-02-20 17:20:48 +01001070 ALC880_FIXUP_UNIWILL,
Takashi Iwai967b88c2012-02-20 17:31:02 +01001071 ALC880_FIXUP_UNIWILL_DIG,
Takashi Iwai96e225f2012-02-20 17:41:51 +01001072 ALC880_FIXUP_Z71V,
Takashi Iwai487a5882013-11-07 07:29:30 +01001073 ALC880_FIXUP_ASUS_W5A,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001074 ALC880_FIXUP_3ST_BASE,
1075 ALC880_FIXUP_3ST,
1076 ALC880_FIXUP_3ST_DIG,
1077 ALC880_FIXUP_5ST_BASE,
1078 ALC880_FIXUP_5ST,
1079 ALC880_FIXUP_5ST_DIG,
1080 ALC880_FIXUP_6ST_BASE,
1081 ALC880_FIXUP_6ST,
1082 ALC880_FIXUP_6ST_DIG,
Takashi Iwai53971452013-01-23 18:21:37 +01001083 ALC880_FIXUP_6ST_AUTOMUTE,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001084};
1085
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001086/* enable the volume-knob widget support on NID 0x21 */
1087static void alc880_fixup_vol_knob(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001088 const struct hda_fixup *fix, int action)
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001089{
Takashi Iwai1727a772013-01-10 09:52:52 +01001090 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwai62f949b2014-09-11 14:06:53 +02001091 snd_hda_jack_detect_enable_callback(codec, 0x21,
1092 alc_update_knob_master);
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001093}
1094
Takashi Iwai1727a772013-01-10 09:52:52 +01001095static const struct hda_fixup alc880_fixups[] = {
Takashi Iwai411225a2012-02-20 17:48:19 +01001096 [ALC880_FIXUP_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001097 .type = HDA_FIXUP_VERBS,
Takashi Iwai411225a2012-02-20 17:48:19 +01001098 .v.verbs = alc_gpio1_init_verbs,
1099 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001100 [ALC880_FIXUP_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001101 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001102 .v.verbs = alc_gpio2_init_verbs,
1103 },
1104 [ALC880_FIXUP_MEDION_RIM] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001105 .type = HDA_FIXUP_VERBS,
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001106 .v.verbs = (const struct hda_verb[]) {
1107 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1108 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1109 { }
1110 },
1111 .chained = true,
1112 .chain_id = ALC880_FIXUP_GPIO2,
1113 },
Takashi Iwaidc6af522012-02-17 16:18:59 +01001114 [ALC880_FIXUP_LG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001115 .type = HDA_FIXUP_PINS,
1116 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaidc6af522012-02-17 16:18:59 +01001117 /* disable bogus unused pins */
1118 { 0x16, 0x411111f0 },
1119 { 0x18, 0x411111f0 },
1120 { 0x1a, 0x411111f0 },
1121 { }
1122 }
1123 },
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001124 [ALC880_FIXUP_LG_LW25] = {
1125 .type = HDA_FIXUP_PINS,
1126 .v.pins = (const struct hda_pintbl[]) {
1127 { 0x1a, 0x0181344f }, /* line-in */
1128 { 0x1b, 0x0321403f }, /* headphone */
1129 { }
1130 }
1131 },
Takashi Iwaif02aab52012-02-17 16:33:56 +01001132 [ALC880_FIXUP_W810] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001133 .type = HDA_FIXUP_PINS,
1134 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001135 /* disable bogus unused pins */
1136 { 0x17, 0x411111f0 },
1137 { }
1138 },
1139 .chained = true,
1140 .chain_id = ALC880_FIXUP_GPIO2,
1141 },
Takashi Iwai27e917f2012-02-17 17:49:54 +01001142 [ALC880_FIXUP_EAPD_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001143 .type = HDA_FIXUP_VERBS,
Takashi Iwai27e917f2012-02-17 17:49:54 +01001144 .v.verbs = (const struct hda_verb[]) {
1145 /* change to EAPD mode */
1146 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1147 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
1148 {}
1149 },
1150 },
Takashi Iwaib9368f52012-02-17 17:54:44 +01001151 [ALC880_FIXUP_TCL_S700] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001152 .type = HDA_FIXUP_VERBS,
Takashi Iwaib9368f52012-02-17 17:54:44 +01001153 .v.verbs = (const struct hda_verb[]) {
1154 /* change to EAPD mode */
1155 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1156 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
1157 {}
1158 },
1159 .chained = true,
1160 .chain_id = ALC880_FIXUP_GPIO2,
1161 },
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001162 [ALC880_FIXUP_VOL_KNOB] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001163 .type = HDA_FIXUP_FUNC,
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001164 .v.func = alc880_fixup_vol_knob,
1165 },
1166 [ALC880_FIXUP_FUJITSU] = {
1167 /* override all pins as BIOS on old Amilo is broken */
Takashi Iwai1727a772013-01-10 09:52:52 +01001168 .type = HDA_FIXUP_PINS,
1169 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001170 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001171 { 0x15, 0x99030120 }, /* speaker */
1172 { 0x16, 0x99030130 }, /* bass speaker */
1173 { 0x17, 0x411111f0 }, /* N/A */
1174 { 0x18, 0x411111f0 }, /* N/A */
1175 { 0x19, 0x01a19950 }, /* mic-in */
1176 { 0x1a, 0x411111f0 }, /* N/A */
1177 { 0x1b, 0x411111f0 }, /* N/A */
1178 { 0x1c, 0x411111f0 }, /* N/A */
1179 { 0x1d, 0x411111f0 }, /* N/A */
1180 { 0x1e, 0x01454140 }, /* SPDIF out */
1181 { }
1182 },
1183 .chained = true,
1184 .chain_id = ALC880_FIXUP_VOL_KNOB,
1185 },
Takashi Iwaiba533812012-02-20 16:36:52 +01001186 [ALC880_FIXUP_F1734] = {
1187 /* almost compatible with FUJITSU, but no bass and SPDIF */
Takashi Iwai1727a772013-01-10 09:52:52 +01001188 .type = HDA_FIXUP_PINS,
1189 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaibb148bd2015-08-13 18:02:39 +02001190 { 0x14, 0x0121401f }, /* HP */
Takashi Iwaiba533812012-02-20 16:36:52 +01001191 { 0x15, 0x99030120 }, /* speaker */
1192 { 0x16, 0x411111f0 }, /* N/A */
1193 { 0x17, 0x411111f0 }, /* N/A */
1194 { 0x18, 0x411111f0 }, /* N/A */
1195 { 0x19, 0x01a19950 }, /* mic-in */
1196 { 0x1a, 0x411111f0 }, /* N/A */
1197 { 0x1b, 0x411111f0 }, /* N/A */
1198 { 0x1c, 0x411111f0 }, /* N/A */
1199 { 0x1d, 0x411111f0 }, /* N/A */
1200 { 0x1e, 0x411111f0 }, /* N/A */
1201 { }
1202 },
1203 .chained = true,
1204 .chain_id = ALC880_FIXUP_VOL_KNOB,
1205 },
Takashi Iwai817de922012-02-20 17:20:48 +01001206 [ALC880_FIXUP_UNIWILL] = {
1207 /* need to fix HP and speaker pins to be parsed correctly */
Takashi Iwai1727a772013-01-10 09:52:52 +01001208 .type = HDA_FIXUP_PINS,
1209 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai817de922012-02-20 17:20:48 +01001210 { 0x14, 0x0121411f }, /* HP */
1211 { 0x15, 0x99030120 }, /* speaker */
1212 { 0x16, 0x99030130 }, /* bass speaker */
1213 { }
1214 },
1215 },
Takashi Iwai967b88c2012-02-20 17:31:02 +01001216 [ALC880_FIXUP_UNIWILL_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001217 .type = HDA_FIXUP_PINS,
1218 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai967b88c2012-02-20 17:31:02 +01001219 /* disable bogus unused pins */
1220 { 0x17, 0x411111f0 },
1221 { 0x19, 0x411111f0 },
1222 { 0x1b, 0x411111f0 },
1223 { 0x1f, 0x411111f0 },
1224 { }
1225 }
1226 },
Takashi Iwai96e225f2012-02-20 17:41:51 +01001227 [ALC880_FIXUP_Z71V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001228 .type = HDA_FIXUP_PINS,
1229 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai96e225f2012-02-20 17:41:51 +01001230 /* set up the whole pins as BIOS is utterly broken */
1231 { 0x14, 0x99030120 }, /* speaker */
1232 { 0x15, 0x0121411f }, /* HP */
1233 { 0x16, 0x411111f0 }, /* N/A */
1234 { 0x17, 0x411111f0 }, /* N/A */
1235 { 0x18, 0x01a19950 }, /* mic-in */
1236 { 0x19, 0x411111f0 }, /* N/A */
1237 { 0x1a, 0x01813031 }, /* line-in */
1238 { 0x1b, 0x411111f0 }, /* N/A */
1239 { 0x1c, 0x411111f0 }, /* N/A */
1240 { 0x1d, 0x411111f0 }, /* N/A */
1241 { 0x1e, 0x0144111e }, /* SPDIF */
1242 { }
1243 }
1244 },
Takashi Iwai487a5882013-11-07 07:29:30 +01001245 [ALC880_FIXUP_ASUS_W5A] = {
1246 .type = HDA_FIXUP_PINS,
1247 .v.pins = (const struct hda_pintbl[]) {
1248 /* set up the whole pins as BIOS is utterly broken */
1249 { 0x14, 0x0121411f }, /* HP */
1250 { 0x15, 0x411111f0 }, /* N/A */
1251 { 0x16, 0x411111f0 }, /* N/A */
1252 { 0x17, 0x411111f0 }, /* N/A */
1253 { 0x18, 0x90a60160 }, /* mic */
1254 { 0x19, 0x411111f0 }, /* N/A */
1255 { 0x1a, 0x411111f0 }, /* N/A */
1256 { 0x1b, 0x411111f0 }, /* N/A */
1257 { 0x1c, 0x411111f0 }, /* N/A */
1258 { 0x1d, 0x411111f0 }, /* N/A */
1259 { 0x1e, 0xb743111e }, /* SPDIF out */
1260 { }
1261 },
1262 .chained = true,
1263 .chain_id = ALC880_FIXUP_GPIO1,
1264 },
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001265 [ALC880_FIXUP_3ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001266 .type = HDA_FIXUP_PINS,
1267 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001268 { 0x14, 0x01014010 }, /* line-out */
1269 { 0x15, 0x411111f0 }, /* N/A */
1270 { 0x16, 0x411111f0 }, /* N/A */
1271 { 0x17, 0x411111f0 }, /* N/A */
1272 { 0x18, 0x01a19c30 }, /* mic-in */
1273 { 0x19, 0x0121411f }, /* HP */
1274 { 0x1a, 0x01813031 }, /* line-in */
1275 { 0x1b, 0x02a19c40 }, /* front-mic */
1276 { 0x1c, 0x411111f0 }, /* N/A */
1277 { 0x1d, 0x411111f0 }, /* N/A */
1278 /* 0x1e is filled in below */
1279 { 0x1f, 0x411111f0 }, /* N/A */
1280 { }
1281 }
1282 },
1283 [ALC880_FIXUP_3ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001284 .type = HDA_FIXUP_PINS,
1285 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001286 { 0x1e, 0x411111f0 }, /* N/A */
1287 { }
1288 },
1289 .chained = true,
1290 .chain_id = ALC880_FIXUP_3ST_BASE,
1291 },
1292 [ALC880_FIXUP_3ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001293 .type = HDA_FIXUP_PINS,
1294 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001295 { 0x1e, 0x0144111e }, /* SPDIF */
1296 { }
1297 },
1298 .chained = true,
1299 .chain_id = ALC880_FIXUP_3ST_BASE,
1300 },
1301 [ALC880_FIXUP_5ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001302 .type = HDA_FIXUP_PINS,
1303 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001304 { 0x14, 0x01014010 }, /* front */
1305 { 0x15, 0x411111f0 }, /* N/A */
1306 { 0x16, 0x01011411 }, /* CLFE */
1307 { 0x17, 0x01016412 }, /* surr */
1308 { 0x18, 0x01a19c30 }, /* mic-in */
1309 { 0x19, 0x0121411f }, /* HP */
1310 { 0x1a, 0x01813031 }, /* line-in */
1311 { 0x1b, 0x02a19c40 }, /* front-mic */
1312 { 0x1c, 0x411111f0 }, /* N/A */
1313 { 0x1d, 0x411111f0 }, /* N/A */
1314 /* 0x1e is filled in below */
1315 { 0x1f, 0x411111f0 }, /* N/A */
1316 { }
1317 }
1318 },
1319 [ALC880_FIXUP_5ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001320 .type = HDA_FIXUP_PINS,
1321 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001322 { 0x1e, 0x411111f0 }, /* N/A */
1323 { }
1324 },
1325 .chained = true,
1326 .chain_id = ALC880_FIXUP_5ST_BASE,
1327 },
1328 [ALC880_FIXUP_5ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001329 .type = HDA_FIXUP_PINS,
1330 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001331 { 0x1e, 0x0144111e }, /* SPDIF */
1332 { }
1333 },
1334 .chained = true,
1335 .chain_id = ALC880_FIXUP_5ST_BASE,
1336 },
1337 [ALC880_FIXUP_6ST_BASE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001338 .type = HDA_FIXUP_PINS,
1339 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001340 { 0x14, 0x01014010 }, /* front */
1341 { 0x15, 0x01016412 }, /* surr */
1342 { 0x16, 0x01011411 }, /* CLFE */
1343 { 0x17, 0x01012414 }, /* side */
1344 { 0x18, 0x01a19c30 }, /* mic-in */
1345 { 0x19, 0x02a19c40 }, /* front-mic */
1346 { 0x1a, 0x01813031 }, /* line-in */
1347 { 0x1b, 0x0121411f }, /* HP */
1348 { 0x1c, 0x411111f0 }, /* N/A */
1349 { 0x1d, 0x411111f0 }, /* N/A */
1350 /* 0x1e is filled in below */
1351 { 0x1f, 0x411111f0 }, /* N/A */
1352 { }
1353 }
1354 },
1355 [ALC880_FIXUP_6ST] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001356 .type = HDA_FIXUP_PINS,
1357 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001358 { 0x1e, 0x411111f0 }, /* N/A */
1359 { }
1360 },
1361 .chained = true,
1362 .chain_id = ALC880_FIXUP_6ST_BASE,
1363 },
1364 [ALC880_FIXUP_6ST_DIG] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001365 .type = HDA_FIXUP_PINS,
1366 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001367 { 0x1e, 0x0144111e }, /* SPDIF */
1368 { }
1369 },
1370 .chained = true,
1371 .chain_id = ALC880_FIXUP_6ST_BASE,
1372 },
Takashi Iwai53971452013-01-23 18:21:37 +01001373 [ALC880_FIXUP_6ST_AUTOMUTE] = {
1374 .type = HDA_FIXUP_PINS,
1375 .v.pins = (const struct hda_pintbl[]) {
1376 { 0x1b, 0x0121401f }, /* HP with jack detect */
1377 { }
1378 },
1379 .chained_before = true,
1380 .chain_id = ALC880_FIXUP_6ST_BASE,
1381 },
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001382};
1383
1384static const struct snd_pci_quirk alc880_fixup_tbl[] = {
Takashi Iwaif02aab52012-02-17 16:33:56 +01001385 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
Takashi Iwai487a5882013-11-07 07:29:30 +01001386 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
Takashi Iwai96e225f2012-02-20 17:41:51 +01001387 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001388 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
David Henningsson6538de02014-06-10 10:52:50 +02001389 SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwai29e3fdc2012-02-20 17:56:57 +01001390 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
Takashi Iwai27e917f2012-02-17 17:49:54 +01001391 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
Takashi Iwai967b88c2012-02-20 17:31:02 +01001392 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
Takashi Iwaiba533812012-02-20 16:36:52 +01001393 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
Takashi Iwai817de922012-02-20 17:20:48 +01001394 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
Takashi Iwai7833c7e2012-02-20 17:11:38 +01001395 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
Takashi Iwaif02aab52012-02-17 16:33:56 +01001396 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001397 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
Takashi Iwai53971452013-01-23 18:21:37 +01001398 SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
Takashi Iwaia1615742015-08-13 18:05:06 +02001399 SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001400 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
Takashi Iwaiba533812012-02-20 16:36:52 +01001401 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
Takashi Iwaicf5a2272012-02-20 16:31:07 +01001402 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
Takashi Iwaidc6af522012-02-17 16:18:59 +01001403 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1404 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1405 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
Takashi Iwaidb8a38e2013-08-09 12:34:42 +02001406 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
Takashi Iwaib9368f52012-02-17 17:54:44 +01001407 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001408
1409 /* Below is the copied entries from alc880_quirks.c.
1410 * It's not quite sure whether BIOS sets the correct pin-config table
1411 * on these machines, thus they are kept to be compatible with
1412 * the old static quirks. Once when it's confirmed to work without
1413 * these overrides, it'd be better to remove.
1414 */
1415 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1416 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1417 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1418 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1419 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1420 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1421 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1422 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1423 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1424 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1425 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1426 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1427 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1428 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1429 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1430 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1431 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1432 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1433 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1434 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1435 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1436 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1437 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1438 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1439 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1440 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1441 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1442 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1443 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1444 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1445 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1446 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1447 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1448 /* default Intel */
1449 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1450 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1451 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1452 {}
1453};
1454
Takashi Iwai1727a772013-01-10 09:52:52 +01001455static const struct hda_model_fixup alc880_fixup_models[] = {
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001456 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1457 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1458 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1459 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1460 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1461 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
Takashi Iwai53971452013-01-23 18:21:37 +01001462 {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
Takashi Iwaiee3b2962011-11-15 14:26:54 +01001463 {}
1464};
1465
1466
1467/*
Takashi Iwai1d045db2011-07-07 18:23:21 +02001468 * OK, here we have finally the patch for ALC880
1469 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001470static int patch_alc880(struct hda_codec *codec)
1471{
1472 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001473 int err;
1474
Takashi Iwai3de95172012-05-07 18:03:15 +02001475 err = alc_alloc_spec(codec, 0x0b);
1476 if (err < 0)
1477 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001478
Takashi Iwai3de95172012-05-07 18:03:15 +02001479 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01001480 spec->gen.need_dac_fix = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001481 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001482
Takashi Iwai225068a2015-05-29 10:42:14 +02001483 codec->patch_ops.unsol_event = alc880_unsol_event;
1484
Takashi Iwai1727a772013-01-10 09:52:52 +01001485 snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001486 alc880_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001487 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001488
Takashi Iwai67b6ec32012-02-20 18:20:42 +01001489 /* automatic parse from the BIOS config */
1490 err = alc880_parse_auto_config(codec);
1491 if (err < 0)
1492 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001493
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001494 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001495 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001496
Takashi Iwai1727a772013-01-10 09:52:52 +01001497 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001498
Takashi Iwai1d045db2011-07-07 18:23:21 +02001499 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001500
1501 error:
1502 alc_free(codec);
1503 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001504}
1505
1506
1507/*
1508 * ALC260 support
1509 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001510static int alc260_parse_auto_config(struct hda_codec *codec)
1511{
Takashi Iwai1d045db2011-07-07 18:23:21 +02001512 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001513 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1514 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001515}
1516
Takashi Iwai1d045db2011-07-07 18:23:21 +02001517/*
1518 * Pin config fixes
1519 */
1520enum {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001521 ALC260_FIXUP_HP_DC5750,
1522 ALC260_FIXUP_HP_PIN_0F,
1523 ALC260_FIXUP_COEF,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001524 ALC260_FIXUP_GPIO1,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001525 ALC260_FIXUP_GPIO1_TOGGLE,
1526 ALC260_FIXUP_REPLACER,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001527 ALC260_FIXUP_HP_B1900,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001528 ALC260_FIXUP_KN1,
Takashi Iwai39aedee2013-01-10 17:10:40 +01001529 ALC260_FIXUP_FSC_S7020,
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001530 ALC260_FIXUP_FSC_S7020_JWSE,
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001531 ALC260_FIXUP_VAIO_PINS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001532};
1533
Takashi Iwai20f7d922012-02-16 12:35:16 +01001534static void alc260_gpio1_automute(struct hda_codec *codec)
1535{
1536 struct alc_spec *spec = codec->spec;
1537 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001538 spec->gen.hp_jack_present);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001539}
1540
1541static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001542 const struct hda_fixup *fix, int action)
Takashi Iwai20f7d922012-02-16 12:35:16 +01001543{
1544 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001545 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai20f7d922012-02-16 12:35:16 +01001546 /* although the machine has only one output pin, we need to
1547 * toggle GPIO1 according to the jack state
1548 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01001549 spec->gen.automute_hook = alc260_gpio1_automute;
1550 spec->gen.detect_hp = 1;
1551 spec->gen.automute_speaker = 1;
1552 spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
Takashi Iwai62f949b2014-09-11 14:06:53 +02001553 snd_hda_jack_detect_enable_callback(codec, 0x0f,
Takashi Iwai08c189f2012-12-19 15:22:24 +01001554 snd_hda_gen_hp_automute);
Takashi Iwaic9ce6b22012-12-18 18:12:44 +01001555 snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
Takashi Iwai20f7d922012-02-16 12:35:16 +01001556 }
1557}
1558
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001559static void alc260_fixup_kn1(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001560 const struct hda_fixup *fix, int action)
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001561{
1562 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01001563 static const struct hda_pintbl pincfgs[] = {
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001564 { 0x0f, 0x02214000 }, /* HP/speaker */
1565 { 0x12, 0x90a60160 }, /* int mic */
1566 { 0x13, 0x02a19000 }, /* ext mic */
1567 { 0x18, 0x01446000 }, /* SPDIF out */
1568 /* disable bogus I/O pins */
1569 { 0x10, 0x411111f0 },
1570 { 0x11, 0x411111f0 },
1571 { 0x14, 0x411111f0 },
1572 { 0x15, 0x411111f0 },
1573 { 0x16, 0x411111f0 },
1574 { 0x17, 0x411111f0 },
1575 { 0x19, 0x411111f0 },
1576 { }
1577 };
1578
1579 switch (action) {
Takashi Iwai1727a772013-01-10 09:52:52 +01001580 case HDA_FIXUP_ACT_PRE_PROBE:
1581 snd_hda_apply_pincfgs(codec, pincfgs);
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001582 break;
Takashi Iwai1727a772013-01-10 09:52:52 +01001583 case HDA_FIXUP_ACT_PROBE:
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001584 spec->init_amp = ALC_INIT_NONE;
1585 break;
1586 }
1587}
1588
Takashi Iwai39aedee2013-01-10 17:10:40 +01001589static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1590 const struct hda_fixup *fix, int action)
1591{
1592 struct alc_spec *spec = codec->spec;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001593 if (action == HDA_FIXUP_ACT_PROBE)
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001594 spec->init_amp = ALC_INIT_NONE;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001595}
1596
1597static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1598 const struct hda_fixup *fix, int action)
1599{
1600 struct alc_spec *spec = codec->spec;
1601 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaif811c3c2013-03-07 18:32:59 +01001602 spec->gen.add_jack_modes = 1;
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001603 spec->gen.hp_mic = 1;
Takashi Iwaie6e0ee52013-02-18 17:04:20 +01001604 }
Takashi Iwai39aedee2013-01-10 17:10:40 +01001605}
1606
Takashi Iwai1727a772013-01-10 09:52:52 +01001607static const struct hda_fixup alc260_fixups[] = {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001608 [ALC260_FIXUP_HP_DC5750] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001609 .type = HDA_FIXUP_PINS,
1610 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001611 { 0x11, 0x90130110 }, /* speaker */
1612 { }
1613 }
1614 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001615 [ALC260_FIXUP_HP_PIN_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001616 .type = HDA_FIXUP_PINS,
1617 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaica8f0422012-02-16 11:51:19 +01001618 { 0x0f, 0x01214000 }, /* HP */
1619 { }
1620 }
1621 },
1622 [ALC260_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001623 .type = HDA_FIXUP_VERBS,
Takashi Iwaica8f0422012-02-16 11:51:19 +01001624 .v.verbs = (const struct hda_verb[]) {
Ronan Marquete30cf2d2014-06-01 18:38:53 +02001625 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1626 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001627 { }
1628 },
Takashi Iwaica8f0422012-02-16 11:51:19 +01001629 },
Takashi Iwai15317ab2012-02-16 12:02:53 +01001630 [ALC260_FIXUP_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001631 .type = HDA_FIXUP_VERBS,
Takashi Iwai15317ab2012-02-16 12:02:53 +01001632 .v.verbs = alc_gpio1_init_verbs,
1633 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001634 [ALC260_FIXUP_GPIO1_TOGGLE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001635 .type = HDA_FIXUP_FUNC,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001636 .v.func = alc260_fixup_gpio1_toggle,
1637 .chained = true,
1638 .chain_id = ALC260_FIXUP_HP_PIN_0F,
1639 },
1640 [ALC260_FIXUP_REPLACER] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001641 .type = HDA_FIXUP_VERBS,
Takashi Iwai20f7d922012-02-16 12:35:16 +01001642 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai192a98e2014-06-02 15:16:07 +02001643 { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1644 { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 },
Takashi Iwai20f7d922012-02-16 12:35:16 +01001645 { }
1646 },
1647 .chained = true,
1648 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1649 },
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001650 [ALC260_FIXUP_HP_B1900] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001651 .type = HDA_FIXUP_FUNC,
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001652 .v.func = alc260_fixup_gpio1_toggle,
1653 .chained = true,
1654 .chain_id = ALC260_FIXUP_COEF,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001655 },
1656 [ALC260_FIXUP_KN1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001657 .type = HDA_FIXUP_FUNC,
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001658 .v.func = alc260_fixup_kn1,
1659 },
Takashi Iwai39aedee2013-01-10 17:10:40 +01001660 [ALC260_FIXUP_FSC_S7020] = {
1661 .type = HDA_FIXUP_FUNC,
1662 .v.func = alc260_fixup_fsc_s7020,
1663 },
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001664 [ALC260_FIXUP_FSC_S7020_JWSE] = {
1665 .type = HDA_FIXUP_FUNC,
1666 .v.func = alc260_fixup_fsc_s7020_jwse,
1667 .chained = true,
1668 .chain_id = ALC260_FIXUP_FSC_S7020,
1669 },
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001670 [ALC260_FIXUP_VAIO_PINS] = {
1671 .type = HDA_FIXUP_PINS,
1672 .v.pins = (const struct hda_pintbl[]) {
1673 /* Pin configs are missing completely on some VAIOs */
1674 { 0x0f, 0x01211020 },
1675 { 0x10, 0x0001003f },
1676 { 0x11, 0x411111f0 },
1677 { 0x12, 0x01a15930 },
1678 { 0x13, 0x411111f0 },
1679 { 0x14, 0x411111f0 },
1680 { 0x15, 0x411111f0 },
1681 { 0x16, 0x411111f0 },
1682 { 0x17, 0x411111f0 },
1683 { 0x18, 0x411111f0 },
1684 { 0x19, 0x411111f0 },
1685 { }
1686 }
1687 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001688};
1689
1690static const struct snd_pci_quirk alc260_fixup_tbl[] = {
Takashi Iwai15317ab2012-02-16 12:02:53 +01001691 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001692 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
Takashi Iwai15317ab2012-02-16 12:02:53 +01001693 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001694 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
Takashi Iwai0a1c4fa2012-02-16 12:42:30 +01001695 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
Takashi Iwaid08c5ef2013-11-22 08:06:36 +01001696 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
Takashi Iwai0f5a5b82013-11-21 09:12:52 +01001697 SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
Takashi Iwai39aedee2013-01-10 17:10:40 +01001698 SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
Takashi Iwaib1f58082012-02-16 12:45:03 +01001699 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
Takashi Iwai118cb4a2012-04-19 07:33:27 +02001700 SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
Takashi Iwai20f7d922012-02-16 12:35:16 +01001701 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
Takashi Iwaica8f0422012-02-16 11:51:19 +01001702 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02001703 {}
1704};
1705
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001706static const struct hda_model_fixup alc260_fixup_models[] = {
1707 {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1708 {.id = ALC260_FIXUP_COEF, .name = "coef"},
1709 {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1710 {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1711 {}
1712};
1713
Takashi Iwai1d045db2011-07-07 18:23:21 +02001714/*
1715 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001716static int patch_alc260(struct hda_codec *codec)
1717{
1718 struct alc_spec *spec;
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001719 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001720
Takashi Iwai3de95172012-05-07 18:03:15 +02001721 err = alc_alloc_spec(codec, 0x07);
1722 if (err < 0)
1723 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001724
Takashi Iwai3de95172012-05-07 18:03:15 +02001725 spec = codec->spec;
Takashi Iwaiea46c3c2013-01-15 18:45:53 +01001726 /* as quite a few machines require HP amp for speaker outputs,
1727 * it's easier to enable it unconditionally; even if it's unneeded,
1728 * it's almost harmless.
1729 */
1730 spec->gen.prefer_hp_amp = 1;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001731 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001732
Takashi Iwai225068a2015-05-29 10:42:14 +02001733 spec->shutup = alc_eapd_shutup;
1734
Takashi Iwai5ebd3bb2013-02-19 18:23:31 +01001735 snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1736 alc260_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01001737 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001738
Takashi Iwaic3c2c9e2012-02-16 12:59:55 +01001739 /* automatic parse from the BIOS config */
1740 err = alc260_parse_auto_config(codec);
1741 if (err < 0)
1742 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001743
Takashi Iwai7504b6c2013-03-18 11:25:51 +01001744 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02001745 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02001746
Takashi Iwai1727a772013-01-10 09:52:52 +01001747 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01001748
Takashi Iwai1d045db2011-07-07 18:23:21 +02001749 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02001750
1751 error:
1752 alc_free(codec);
1753 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02001754}
1755
1756
1757/*
1758 * ALC882/883/885/888/889 support
1759 *
1760 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1761 * configuration. Each pin widget can choose any input DACs and a mixer.
1762 * Each ADC is connected from a mixer of all inputs. This makes possible
1763 * 6-channel independent captures.
1764 *
1765 * In addition, an independent DAC for the multi-playback (not used in this
1766 * driver yet).
1767 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02001768
1769/*
1770 * Pin config fixes
1771 */
1772enum {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001773 ALC882_FIXUP_ABIT_AW9D_MAX,
1774 ALC882_FIXUP_LENOVO_Y530,
1775 ALC882_FIXUP_PB_M5210,
1776 ALC882_FIXUP_ACER_ASPIRE_7736,
1777 ALC882_FIXUP_ASUS_W90V,
Marton Balint8f239212012-03-05 21:33:23 +01001778 ALC889_FIXUP_CD,
David Henningssonb2c53e22014-01-01 14:01:34 +01001779 ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001780 ALC889_FIXUP_VAIO_TT,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01001781 ALC888_FIXUP_EEE1601,
Takashi Iwai177943a2011-11-09 12:55:18 +01001782 ALC882_FIXUP_EAPD,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01001783 ALC883_FIXUP_EAPD,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01001784 ALC883_FIXUP_ACER_EAPD,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001785 ALC882_FIXUP_GPIO1,
1786 ALC882_FIXUP_GPIO2,
Takashi Iwaieb844d52011-11-09 18:03:07 +01001787 ALC882_FIXUP_GPIO3,
Takashi Iwai68ef0562011-11-09 18:24:44 +01001788 ALC889_FIXUP_COEF,
1789 ALC882_FIXUP_ASUS_W2JC,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01001790 ALC882_FIXUP_ACER_ASPIRE_4930G,
1791 ALC882_FIXUP_ACER_ASPIRE_8930G,
1792 ALC882_FIXUP_ASPIRE_8930G_VERBS,
Takashi Iwai56710872011-11-14 17:42:11 +01001793 ALC885_FIXUP_MACPRO_GPIO,
Takashi Iwai02a237b2012-02-13 15:25:07 +01001794 ALC889_FIXUP_DAC_ROUTE,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001795 ALC889_FIXUP_MBP_VREF,
1796 ALC889_FIXUP_IMAC91_VREF,
Adrien Vergée7729a42014-01-24 14:56:14 -05001797 ALC889_FIXUP_MBA11_VREF,
Takashi Iwai0756f092013-12-04 13:59:45 +01001798 ALC889_FIXUP_MBA21_VREF,
Takashi Iwaic20f31e2014-02-03 11:02:10 +01001799 ALC889_FIXUP_MP11_VREF,
Mario Kleiner9f660a12015-12-22 00:45:43 +01001800 ALC889_FIXUP_MP41_VREF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02001801 ALC882_FIXUP_INV_DMIC,
Takashi Iwaie427c232012-07-29 10:04:08 +02001802 ALC882_FIXUP_NO_PRIMARY_HP,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01001803 ALC887_FIXUP_ASUS_BASS,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001804 ALC887_FIXUP_BASS_CHMAP,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001805};
1806
Takashi Iwai68ef0562011-11-09 18:24:44 +01001807static void alc889_fixup_coef(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001808 const struct hda_fixup *fix, int action)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001809{
Takashi Iwai1727a772013-01-10 09:52:52 +01001810 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai68ef0562011-11-09 18:24:44 +01001811 return;
Kailang Yang1df88742014-10-29 16:10:13 +08001812 alc_update_coef_idx(codec, 7, 0, 0x2030);
Takashi Iwai68ef0562011-11-09 18:24:44 +01001813}
1814
Takashi Iwai56710872011-11-14 17:42:11 +01001815/* toggle speaker-output according to the hp-jack state */
1816static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1817{
1818 unsigned int gpiostate, gpiomask, gpiodir;
1819
Takashi Iwai7639a062015-03-03 10:07:24 +01001820 gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001821 AC_VERB_GET_GPIO_DATA, 0);
1822
1823 if (!muted)
1824 gpiostate |= (1 << pin);
1825 else
1826 gpiostate &= ~(1 << pin);
1827
Takashi Iwai7639a062015-03-03 10:07:24 +01001828 gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001829 AC_VERB_GET_GPIO_MASK, 0);
1830 gpiomask |= (1 << pin);
1831
Takashi Iwai7639a062015-03-03 10:07:24 +01001832 gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001833 AC_VERB_GET_GPIO_DIRECTION, 0);
1834 gpiodir |= (1 << pin);
1835
1836
Takashi Iwai7639a062015-03-03 10:07:24 +01001837 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001838 AC_VERB_SET_GPIO_MASK, gpiomask);
Takashi Iwai7639a062015-03-03 10:07:24 +01001839 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001840 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1841
1842 msleep(1);
1843
Takashi Iwai7639a062015-03-03 10:07:24 +01001844 snd_hda_codec_write(codec, codec->core.afg, 0,
Takashi Iwai56710872011-11-14 17:42:11 +01001845 AC_VERB_SET_GPIO_DATA, gpiostate);
1846}
1847
1848/* set up GPIO at initialization */
1849static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001850 const struct hda_fixup *fix, int action)
Takashi Iwai56710872011-11-14 17:42:11 +01001851{
Takashi Iwai1727a772013-01-10 09:52:52 +01001852 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai56710872011-11-14 17:42:11 +01001853 return;
1854 alc882_gpio_mute(codec, 0, 0);
1855 alc882_gpio_mute(codec, 1, 0);
1856}
1857
Takashi Iwai02a237b2012-02-13 15:25:07 +01001858/* Fix the connection of some pins for ALC889:
1859 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1860 * work correctly (bko#42740)
1861 */
1862static void alc889_fixup_dac_route(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001863 const struct hda_fixup *fix, int action)
Takashi Iwai02a237b2012-02-13 15:25:07 +01001864{
Takashi Iwai1727a772013-01-10 09:52:52 +01001865 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001866 /* fake the connections during parsing the tree */
Takashi Iwai02a237b2012-02-13 15:25:07 +01001867 hda_nid_t conn1[2] = { 0x0c, 0x0d };
1868 hda_nid_t conn2[2] = { 0x0e, 0x0f };
1869 snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1870 snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1871 snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1872 snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
Takashi Iwai1727a772013-01-10 09:52:52 +01001873 } else if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwaief8d60f2012-02-17 10:12:38 +01001874 /* restore the connections */
1875 hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1876 snd_hda_override_conn_list(codec, 0x14, 5, conn);
1877 snd_hda_override_conn_list(codec, 0x15, 5, conn);
1878 snd_hda_override_conn_list(codec, 0x18, 5, conn);
1879 snd_hda_override_conn_list(codec, 0x1a, 5, conn);
Takashi Iwai02a237b2012-02-13 15:25:07 +01001880 }
1881}
1882
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001883/* Set VREF on HP pin */
1884static void alc889_fixup_mbp_vref(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001885 const struct hda_fixup *fix, int action)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001886{
1887 struct alc_spec *spec = codec->spec;
Mario Kleiner9f660a12015-12-22 00:45:43 +01001888 static hda_nid_t nids[3] = { 0x14, 0x15, 0x19 };
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001889 int i;
1890
Takashi Iwai1727a772013-01-10 09:52:52 +01001891 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001892 return;
1893 for (i = 0; i < ARRAY_SIZE(nids); i++) {
1894 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1895 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1896 continue;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001897 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001898 val |= AC_PINCTL_VREF_80;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001899 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01001900 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001901 break;
1902 }
1903}
1904
Takashi Iwai0756f092013-12-04 13:59:45 +01001905static void alc889_fixup_mac_pins(struct hda_codec *codec,
1906 const hda_nid_t *nids, int num_nids)
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001907{
1908 struct alc_spec *spec = codec->spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001909 int i;
1910
Takashi Iwai0756f092013-12-04 13:59:45 +01001911 for (i = 0; i < num_nids; i++) {
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001912 unsigned int val;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01001913 val = snd_hda_codec_get_pin_target(codec, nids[i]);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001914 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02001915 snd_hda_set_pin_ctl(codec, nids[i], val);
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001916 }
Takashi Iwai08c189f2012-12-19 15:22:24 +01001917 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01001918}
1919
Takashi Iwai0756f092013-12-04 13:59:45 +01001920/* Set VREF on speaker pins on imac91 */
1921static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1922 const struct hda_fixup *fix, int action)
1923{
1924 static hda_nid_t nids[2] = { 0x18, 0x1a };
1925
1926 if (action == HDA_FIXUP_ACT_INIT)
1927 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1928}
1929
Adrien Vergée7729a42014-01-24 14:56:14 -05001930/* Set VREF on speaker pins on mba11 */
1931static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1932 const struct hda_fixup *fix, int action)
1933{
1934 static hda_nid_t nids[1] = { 0x18 };
1935
1936 if (action == HDA_FIXUP_ACT_INIT)
1937 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1938}
1939
Takashi Iwai0756f092013-12-04 13:59:45 +01001940/* Set VREF on speaker pins on mba21 */
1941static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1942 const struct hda_fixup *fix, int action)
1943{
1944 static hda_nid_t nids[2] = { 0x18, 0x19 };
1945
1946 if (action == HDA_FIXUP_ACT_INIT)
1947 alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1948}
1949
Takashi Iwaie427c232012-07-29 10:04:08 +02001950/* Don't take HP output as primary
Fernando Luis Vázquez Caod9111492013-02-12 16:49:46 +09001951 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1952 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
Takashi Iwaie427c232012-07-29 10:04:08 +02001953 */
1954static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01001955 const struct hda_fixup *fix, int action)
Takashi Iwaie427c232012-07-29 10:04:08 +02001956{
1957 struct alc_spec *spec = codec->spec;
Takashi Iwaida96fb52013-07-29 16:54:36 +02001958 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08c189f2012-12-19 15:22:24 +01001959 spec->gen.no_primary_hp = 1;
Takashi Iwaida96fb52013-07-29 16:54:36 +02001960 spec->gen.no_multi_io = 1;
1961 }
Takashi Iwaie427c232012-07-29 10:04:08 +02001962}
1963
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01001964static void alc_fixup_bass_chmap(struct hda_codec *codec,
1965 const struct hda_fixup *fix, int action);
1966
Takashi Iwai1727a772013-01-10 09:52:52 +01001967static const struct hda_fixup alc882_fixups[] = {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001968 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001969 .type = HDA_FIXUP_PINS,
1970 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001971 { 0x15, 0x01080104 }, /* side */
1972 { 0x16, 0x01011012 }, /* rear */
1973 { 0x17, 0x01016011 }, /* clfe */
1974 { }
1975 }
1976 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001977 [ALC882_FIXUP_LENOVO_Y530] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001978 .type = HDA_FIXUP_PINS,
1979 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02001980 { 0x15, 0x99130112 }, /* rear int speakers */
1981 { 0x16, 0x99130111 }, /* subwoofer */
1982 { }
1983 }
1984 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001985 [ALC882_FIXUP_PB_M5210] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01001986 .type = HDA_FIXUP_PINCTLS,
1987 .v.pins = (const struct hda_pintbl[]) {
1988 { 0x19, PIN_VREF50 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02001989 {}
1990 }
1991 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001992 [ALC882_FIXUP_ACER_ASPIRE_7736] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001993 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02001994 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02001995 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01001996 [ALC882_FIXUP_ASUS_W90V] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01001997 .type = HDA_FIXUP_PINS,
1998 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5cdf7452011-10-26 23:04:08 +02001999 { 0x16, 0x99130110 }, /* fix sequence for CLFE */
2000 { }
2001 }
2002 },
Marton Balint8f239212012-03-05 21:33:23 +01002003 [ALC889_FIXUP_CD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002004 .type = HDA_FIXUP_PINS,
2005 .v.pins = (const struct hda_pintbl[]) {
Marton Balint8f239212012-03-05 21:33:23 +01002006 { 0x1c, 0x993301f0 }, /* CD */
2007 { }
2008 }
2009 },
David Henningssonb2c53e22014-01-01 14:01:34 +01002010 [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2011 .type = HDA_FIXUP_PINS,
2012 .v.pins = (const struct hda_pintbl[]) {
2013 { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2014 { }
2015 },
2016 .chained = true,
2017 .chain_id = ALC889_FIXUP_CD,
2018 },
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002019 [ALC889_FIXUP_VAIO_TT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002020 .type = HDA_FIXUP_PINS,
2021 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002022 { 0x17, 0x90170111 }, /* hidden surround speaker */
2023 { }
2024 }
2025 },
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002026 [ALC888_FIXUP_EEE1601] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002027 .type = HDA_FIXUP_VERBS,
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002028 .v.verbs = (const struct hda_verb[]) {
2029 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2030 { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 },
2031 { }
2032 }
Takashi Iwai177943a2011-11-09 12:55:18 +01002033 },
2034 [ALC882_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002035 .type = HDA_FIXUP_VERBS,
Takashi Iwai177943a2011-11-09 12:55:18 +01002036 .v.verbs = (const struct hda_verb[]) {
2037 /* change to EAPD mode */
2038 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2039 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2040 { }
2041 }
2042 },
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002043 [ALC883_FIXUP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002044 .type = HDA_FIXUP_VERBS,
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002045 .v.verbs = (const struct hda_verb[]) {
2046 /* change to EAPD mode */
2047 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2048 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2049 { }
2050 }
2051 },
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002052 [ALC883_FIXUP_ACER_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002053 .type = HDA_FIXUP_VERBS,
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002054 .v.verbs = (const struct hda_verb[]) {
2055 /* eanable EAPD on Acer laptops */
2056 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2057 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2058 { }
2059 }
2060 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002061 [ALC882_FIXUP_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002062 .type = HDA_FIXUP_VERBS,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002063 .v.verbs = alc_gpio1_init_verbs,
2064 },
2065 [ALC882_FIXUP_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002066 .type = HDA_FIXUP_VERBS,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002067 .v.verbs = alc_gpio2_init_verbs,
2068 },
Takashi Iwaieb844d52011-11-09 18:03:07 +01002069 [ALC882_FIXUP_GPIO3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002070 .type = HDA_FIXUP_VERBS,
Takashi Iwaieb844d52011-11-09 18:03:07 +01002071 .v.verbs = alc_gpio3_init_verbs,
2072 },
Takashi Iwai68ef0562011-11-09 18:24:44 +01002073 [ALC882_FIXUP_ASUS_W2JC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002074 .type = HDA_FIXUP_VERBS,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002075 .v.verbs = alc_gpio1_init_verbs,
2076 .chained = true,
2077 .chain_id = ALC882_FIXUP_EAPD,
2078 },
2079 [ALC889_FIXUP_COEF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002080 .type = HDA_FIXUP_FUNC,
Takashi Iwai68ef0562011-11-09 18:24:44 +01002081 .v.func = alc889_fixup_coef,
2082 },
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002083 [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002084 .type = HDA_FIXUP_PINS,
2085 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002086 { 0x16, 0x99130111 }, /* CLFE speaker */
2087 { 0x17, 0x99130112 }, /* surround speaker */
2088 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002089 },
2090 .chained = true,
2091 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002092 },
2093 [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002094 .type = HDA_FIXUP_PINS,
2095 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002096 { 0x16, 0x99130111 }, /* CLFE speaker */
2097 { 0x1b, 0x99130112 }, /* surround speaker */
2098 { }
2099 },
2100 .chained = true,
2101 .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2102 },
2103 [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2104 /* additional init verbs for Acer Aspire 8930G */
Takashi Iwai1727a772013-01-10 09:52:52 +01002105 .type = HDA_FIXUP_VERBS,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002106 .v.verbs = (const struct hda_verb[]) {
2107 /* Enable all DACs */
2108 /* DAC DISABLE/MUTE 1? */
2109 /* setting bits 1-5 disables DAC nids 0x02-0x06
2110 * apparently. Init=0x38 */
2111 { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2112 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2113 /* DAC DISABLE/MUTE 2? */
2114 /* some bit here disables the other DACs.
2115 * Init=0x4900 */
2116 { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2117 { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2118 /* DMIC fix
2119 * This laptop has a stereo digital microphone.
2120 * The mics are only 1cm apart which makes the stereo
2121 * useless. However, either the mic or the ALC889
2122 * makes the signal become a difference/sum signal
2123 * instead of standard stereo, which is annoying.
2124 * So instead we flip this bit which makes the
2125 * codec replicate the sum signal to both channels,
2126 * turning it into a normal mono mic.
2127 */
2128 /* DMIC_CONTROL? Init value = 0x0001 */
2129 { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2130 { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2131 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2132 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2133 { }
Takashi Iwai038d4fe2012-04-11 17:18:12 +02002134 },
2135 .chained = true,
2136 .chain_id = ALC882_FIXUP_GPIO1,
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002137 },
Takashi Iwai56710872011-11-14 17:42:11 +01002138 [ALC885_FIXUP_MACPRO_GPIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002139 .type = HDA_FIXUP_FUNC,
Takashi Iwai56710872011-11-14 17:42:11 +01002140 .v.func = alc885_fixup_macpro_gpio,
2141 },
Takashi Iwai02a237b2012-02-13 15:25:07 +01002142 [ALC889_FIXUP_DAC_ROUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002143 .type = HDA_FIXUP_FUNC,
Takashi Iwai02a237b2012-02-13 15:25:07 +01002144 .v.func = alc889_fixup_dac_route,
2145 },
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002146 [ALC889_FIXUP_MBP_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002147 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002148 .v.func = alc889_fixup_mbp_vref,
2149 .chained = true,
2150 .chain_id = ALC882_FIXUP_GPIO1,
2151 },
2152 [ALC889_FIXUP_IMAC91_VREF] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002153 .type = HDA_FIXUP_FUNC,
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002154 .v.func = alc889_fixup_imac91_vref,
2155 .chained = true,
2156 .chain_id = ALC882_FIXUP_GPIO1,
2157 },
Adrien Vergée7729a42014-01-24 14:56:14 -05002158 [ALC889_FIXUP_MBA11_VREF] = {
2159 .type = HDA_FIXUP_FUNC,
2160 .v.func = alc889_fixup_mba11_vref,
2161 .chained = true,
2162 .chain_id = ALC889_FIXUP_MBP_VREF,
2163 },
Takashi Iwai0756f092013-12-04 13:59:45 +01002164 [ALC889_FIXUP_MBA21_VREF] = {
2165 .type = HDA_FIXUP_FUNC,
2166 .v.func = alc889_fixup_mba21_vref,
2167 .chained = true,
2168 .chain_id = ALC889_FIXUP_MBP_VREF,
2169 },
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002170 [ALC889_FIXUP_MP11_VREF] = {
2171 .type = HDA_FIXUP_FUNC,
2172 .v.func = alc889_fixup_mba11_vref,
2173 .chained = true,
2174 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2175 },
Mario Kleiner9f660a12015-12-22 00:45:43 +01002176 [ALC889_FIXUP_MP41_VREF] = {
2177 .type = HDA_FIXUP_FUNC,
2178 .v.func = alc889_fixup_mbp_vref,
2179 .chained = true,
2180 .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2181 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002182 [ALC882_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002183 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002184 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002185 },
Takashi Iwaie427c232012-07-29 10:04:08 +02002186 [ALC882_FIXUP_NO_PRIMARY_HP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002187 .type = HDA_FIXUP_FUNC,
Takashi Iwaie427c232012-07-29 10:04:08 +02002188 .v.func = alc882_fixup_no_primary_hp,
2189 },
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002190 [ALC887_FIXUP_ASUS_BASS] = {
2191 .type = HDA_FIXUP_PINS,
2192 .v.pins = (const struct hda_pintbl[]) {
2193 {0x16, 0x99130130}, /* bass speaker */
2194 {}
2195 },
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01002196 .chained = true,
2197 .chain_id = ALC887_FIXUP_BASS_CHMAP,
2198 },
2199 [ALC887_FIXUP_BASS_CHMAP] = {
2200 .type = HDA_FIXUP_FUNC,
2201 .v.func = alc_fixup_bass_chmap,
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002202 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002203};
2204
2205static const struct snd_pci_quirk alc882_fixup_tbl[] = {
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002206 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2207 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaib5d724b2015-06-02 19:57:08 +02002208 SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
Takashi Iwai8812c4f2011-11-09 17:39:15 +01002209 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2210 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2211 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2212 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
Takashi Iwaic3e837b2011-11-10 16:01:47 +01002213 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2214 ALC882_FIXUP_ACER_ASPIRE_4930G),
2215 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2216 ALC882_FIXUP_ACER_ASPIRE_4930G),
2217 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2218 ALC882_FIXUP_ACER_ASPIRE_8930G),
2219 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2220 ALC882_FIXUP_ACER_ASPIRE_8930G),
2221 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2222 ALC882_FIXUP_ACER_ASPIRE_4930G),
2223 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2224 ALC882_FIXUP_ACER_ASPIRE_4930G),
2225 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2226 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002227 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
Takashi Iwaif5c53d82012-05-07 10:07:33 +02002228 SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2229 ALC882_FIXUP_ACER_ASPIRE_4930G),
Takashi Iwai02a237b2012-02-13 15:25:07 +01002230 SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
Takashi Iwaife97da12012-04-12 08:00:19 +02002231 SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002232 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
Takashi Iwai177943a2011-11-09 12:55:18 +01002233 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002234 SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002235 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
Takashi Iwai0e7cc2e2011-11-09 12:42:48 +01002236 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
Takashi Iwai1f0bbf02013-11-28 15:21:21 +01002237 SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
Takashi Iwai71c88fc2016-12-06 16:20:36 +01002238 SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002239 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
Takashi Iwaie427c232012-07-29 10:04:08 +02002240 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
Sergei A. Trusovc531a242017-08-02 20:23:48 +10002241 SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
Fernando Luis Vázquez Cao12e31a72013-02-12 16:47:44 +09002242 SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwaic44d9b12016-02-07 09:38:26 +01002243 SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
Takashi Iwai56710872011-11-14 17:42:11 +01002244
2245 /* All Apple entries are in codec SSIDs */
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002246 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2247 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2248 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwaic20f31e2014-02-03 11:02:10 +01002249 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002250 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2251 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002252 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2253 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002254 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
Adrien Vergée7729a42014-01-24 14:56:14 -05002255 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai0756f092013-12-04 13:59:45 +01002256 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002257 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2258 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002259 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002260 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2261 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2262 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
Mario Kleiner9f660a12015-12-22 00:45:43 +01002263 SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
Takashi Iwai05193632012-11-12 10:07:36 +01002264 SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002265 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2266 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
Takashi Iwai649ccd02015-07-30 22:30:29 +02002267 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
Takashi Iwai56710872011-11-14 17:42:11 +01002268
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002269 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
Takashi Iwaibca40132012-05-07 11:13:14 +02002270 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
Takashi Iwaieb844d52011-11-09 18:03:07 +01002271 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
David Henningssonb2c53e22014-01-01 14:01:34 +01002272 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
Takashi Iwai5c0ebfb2011-11-07 17:59:13 +01002273 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
Takashi Iwai7a6069b2011-11-09 15:22:01 +01002274 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2275 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
Takashi Iwaiac9b1cd2011-11-09 17:45:55 +01002276 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
Takashi Iwai68ef0562011-11-09 18:24:44 +01002277 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002278 {}
2279};
2280
Takashi Iwai1727a772013-01-10 09:52:52 +01002281static const struct hda_model_fixup alc882_fixup_models[] = {
Takashi Iwai912093b2012-04-11 14:03:41 +02002282 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2283 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2284 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002285 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaie427c232012-07-29 10:04:08 +02002286 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
Takashi Iwai912093b2012-04-11 14:03:41 +02002287 {}
2288};
2289
Takashi Iwai1d045db2011-07-07 18:23:21 +02002290/*
2291 * BIOS auto configuration
2292 */
2293/* almost identical with ALC880 parser... */
2294static int alc882_parse_auto_config(struct hda_codec *codec)
2295{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002296 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002297 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2298 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002299}
2300
Takashi Iwai1d045db2011-07-07 18:23:21 +02002301/*
2302 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002303static int patch_alc882(struct hda_codec *codec)
2304{
2305 struct alc_spec *spec;
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002306 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002307
Takashi Iwai3de95172012-05-07 18:03:15 +02002308 err = alc_alloc_spec(codec, 0x0b);
2309 if (err < 0)
2310 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002311
Takashi Iwai3de95172012-05-07 18:03:15 +02002312 spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002313
Takashi Iwai7639a062015-03-03 10:07:24 +01002314 switch (codec->core.vendor_id) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002315 case 0x10ec0882:
2316 case 0x10ec0885:
Takashi Iwaiacf08082014-09-02 07:21:56 +02002317 case 0x10ec0900:
Takashi Iwai1d045db2011-07-07 18:23:21 +02002318 break;
2319 default:
2320 /* ALC883 and variants */
2321 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2322 break;
2323 }
2324
Takashi Iwai1727a772013-01-10 09:52:52 +01002325 snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
Takashi Iwai912093b2012-04-11 14:03:41 +02002326 alc882_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002327 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002328
2329 alc_auto_parse_customize_define(codec);
2330
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002331 if (has_cdefine_beep(codec))
2332 spec->gen.beep_nid = 0x01;
2333
Takashi Iwai1a97b7f2012-02-21 11:11:48 +01002334 /* automatic parse from the BIOS config */
2335 err = alc882_parse_auto_config(codec);
2336 if (err < 0)
2337 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002338
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002339 if (!spec->gen.no_analog && spec->gen.beep_nid)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002340 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2341
Takashi Iwai1727a772013-01-10 09:52:52 +01002342 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002343
Takashi Iwai1d045db2011-07-07 18:23:21 +02002344 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002345
2346 error:
2347 alc_free(codec);
2348 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002349}
2350
2351
2352/*
2353 * ALC262 support
2354 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002355static int alc262_parse_auto_config(struct hda_codec *codec)
2356{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002357 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002358 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2359 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002360}
2361
2362/*
2363 * Pin config fixes
2364 */
2365enum {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002366 ALC262_FIXUP_FSC_H270,
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002367 ALC262_FIXUP_FSC_S7110,
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002368 ALC262_FIXUP_HP_Z200,
2369 ALC262_FIXUP_TYAN,
Takashi Iwaic4701502011-11-07 14:20:07 +01002370 ALC262_FIXUP_LENOVO_3000,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002371 ALC262_FIXUP_BENQ,
2372 ALC262_FIXUP_BENQ_T31,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002373 ALC262_FIXUP_INV_DMIC,
Mengdong Linb5c66112013-11-29 00:35:35 -05002374 ALC262_FIXUP_INTEL_BAYLEYBAY,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002375};
2376
Takashi Iwai1727a772013-01-10 09:52:52 +01002377static const struct hda_fixup alc262_fixups[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002378 [ALC262_FIXUP_FSC_H270] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002379 .type = HDA_FIXUP_PINS,
2380 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002381 { 0x14, 0x99130110 }, /* speaker */
2382 { 0x15, 0x0221142f }, /* front HP */
2383 { 0x1b, 0x0121141f }, /* rear HP */
2384 { }
2385 }
2386 },
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002387 [ALC262_FIXUP_FSC_S7110] = {
2388 .type = HDA_FIXUP_PINS,
2389 .v.pins = (const struct hda_pintbl[]) {
2390 { 0x15, 0x90170110 }, /* speaker */
2391 { }
2392 },
2393 .chained = true,
2394 .chain_id = ALC262_FIXUP_BENQ,
2395 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002396 [ALC262_FIXUP_HP_Z200] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002397 .type = HDA_FIXUP_PINS,
2398 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002399 { 0x16, 0x99130120 }, /* internal speaker */
2400 { }
2401 }
2402 },
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002403 [ALC262_FIXUP_TYAN] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002404 .type = HDA_FIXUP_PINS,
2405 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002406 { 0x14, 0x1993e1f0 }, /* int AUX */
2407 { }
2408 }
2409 },
Takashi Iwaic4701502011-11-07 14:20:07 +01002410 [ALC262_FIXUP_LENOVO_3000] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01002411 .type = HDA_FIXUP_PINCTLS,
2412 .v.pins = (const struct hda_pintbl[]) {
2413 { 0x19, PIN_VREF50 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002414 {}
2415 },
2416 .chained = true,
2417 .chain_id = ALC262_FIXUP_BENQ,
2418 },
2419 [ALC262_FIXUP_BENQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002420 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002421 .v.verbs = (const struct hda_verb[]) {
Takashi Iwaic4701502011-11-07 14:20:07 +01002422 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2423 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2424 {}
2425 }
2426 },
Takashi Iwaib42590b2011-11-07 14:41:01 +01002427 [ALC262_FIXUP_BENQ_T31] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002428 .type = HDA_FIXUP_VERBS,
Takashi Iwaib42590b2011-11-07 14:41:01 +01002429 .v.verbs = (const struct hda_verb[]) {
2430 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2431 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2432 {}
2433 }
2434 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002435 [ALC262_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002436 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002437 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002438 },
Mengdong Linb5c66112013-11-29 00:35:35 -05002439 [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2440 .type = HDA_FIXUP_FUNC,
2441 .v.func = alc_fixup_no_depop_delay,
2442 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02002443};
2444
2445static const struct snd_pci_quirk alc262_fixup_tbl[] = {
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002446 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
Takashi Iwai7513e6d2013-01-18 15:41:34 +01002447 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
Takashi Iwai3dcd3be2011-11-07 14:59:40 +01002448 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002449 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
Takashi Iwaiafd82d02018-06-22 12:17:45 +02002450 SND_PCI_QUIRK(0x1734, 0x1141, "FSC ESPRIMO U9210", ALC262_FIXUP_FSC_H270),
Takashi Iwaiea4e7af2011-11-07 12:23:55 +01002451 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
Takashi Iwaic4701502011-11-07 14:20:07 +01002452 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
Takashi Iwaib42590b2011-11-07 14:41:01 +01002453 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2454 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
Mengdong Linb5c66112013-11-29 00:35:35 -05002455 SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
Takashi Iwai1d045db2011-07-07 18:23:21 +02002456 {}
2457};
2458
Takashi Iwai1727a772013-01-10 09:52:52 +01002459static const struct hda_model_fixup alc262_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002460 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2461 {}
2462};
Takashi Iwai1d045db2011-07-07 18:23:21 +02002463
Takashi Iwai1d045db2011-07-07 18:23:21 +02002464/*
2465 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002466static int patch_alc262(struct hda_codec *codec)
2467{
2468 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002469 int err;
2470
Takashi Iwai3de95172012-05-07 18:03:15 +02002471 err = alc_alloc_spec(codec, 0x0b);
2472 if (err < 0)
2473 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002474
Takashi Iwai3de95172012-05-07 18:03:15 +02002475 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01002476 spec->gen.shared_mic_vref_pin = 0x18;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002477
Takashi Iwai225068a2015-05-29 10:42:14 +02002478 spec->shutup = alc_eapd_shutup;
2479
Takashi Iwai1d045db2011-07-07 18:23:21 +02002480#if 0
2481 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
2482 * under-run
2483 */
Takashi Iwai98b24882014-08-18 13:47:50 +02002484 alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002485#endif
Takashi Iwai1d045db2011-07-07 18:23:21 +02002486 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2487
Takashi Iwai1727a772013-01-10 09:52:52 +01002488 snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002489 alc262_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01002490 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002491
Takashi Iwaiaf741c12012-05-07 18:09:48 +02002492 alc_auto_parse_customize_define(codec);
2493
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002494 if (has_cdefine_beep(codec))
2495 spec->gen.beep_nid = 0x01;
2496
Takashi Iwai42399f72011-11-07 17:18:44 +01002497 /* automatic parse from the BIOS config */
2498 err = alc262_parse_auto_config(codec);
2499 if (err < 0)
2500 goto error;
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002501
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002502 if (!spec->gen.no_analog && spec->gen.beep_nid)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002503 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2504
Takashi Iwai1727a772013-01-10 09:52:52 +01002505 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01002506
Takashi Iwai1d045db2011-07-07 18:23:21 +02002507 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002508
2509 error:
2510 alc_free(codec);
2511 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002512}
2513
2514/*
2515 * ALC268
2516 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002517/* bind Beep switches of both NID 0x0f and 0x10 */
2518static const struct hda_bind_ctls alc268_bind_beep_sw = {
2519 .ops = &snd_hda_bind_sw,
2520 .values = {
2521 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2522 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2523 0
2524 },
2525};
2526
2527static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2528 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2529 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2530 { }
2531};
2532
2533/* set PCBEEP vol = 0, mute connections */
2534static const struct hda_verb alc268_beep_init_verbs[] = {
2535 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2536 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2537 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2538 { }
2539};
2540
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002541enum {
2542 ALC268_FIXUP_INV_DMIC,
Takashi Iwaicb766402012-10-20 10:55:21 +02002543 ALC268_FIXUP_HP_EAPD,
Takashi Iwai24eff322013-11-04 18:21:08 +01002544 ALC268_FIXUP_SPDIF,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002545};
2546
Takashi Iwai1727a772013-01-10 09:52:52 +01002547static const struct hda_fixup alc268_fixups[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002548 [ALC268_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002549 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02002550 .v.func = alc_fixup_inv_dmic,
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002551 },
Takashi Iwaicb766402012-10-20 10:55:21 +02002552 [ALC268_FIXUP_HP_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01002553 .type = HDA_FIXUP_VERBS,
Takashi Iwaicb766402012-10-20 10:55:21 +02002554 .v.verbs = (const struct hda_verb[]) {
2555 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2556 {}
2557 }
2558 },
Takashi Iwai24eff322013-11-04 18:21:08 +01002559 [ALC268_FIXUP_SPDIF] = {
2560 .type = HDA_FIXUP_PINS,
2561 .v.pins = (const struct hda_pintbl[]) {
2562 { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2563 {}
2564 }
2565 },
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002566};
2567
Takashi Iwai1727a772013-01-10 09:52:52 +01002568static const struct hda_model_fixup alc268_fixup_models[] = {
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002569 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
Takashi Iwaicb766402012-10-20 10:55:21 +02002570 {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2571 {}
2572};
2573
2574static const struct snd_pci_quirk alc268_fixup_tbl[] = {
Takashi Iwai24eff322013-11-04 18:21:08 +01002575 SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
David Henningssonfcd8f3b2013-01-28 05:45:47 +01002576 SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
Takashi Iwaicb766402012-10-20 10:55:21 +02002577 /* below is codec SSID since multiple Toshiba laptops have the
2578 * same PCI SSID 1179:ff00
2579 */
2580 SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002581 {}
2582};
2583
Takashi Iwai1d045db2011-07-07 18:23:21 +02002584/*
2585 * BIOS auto configuration
2586 */
2587static int alc268_parse_auto_config(struct hda_codec *codec)
2588{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002589 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002590 return alc_parse_auto_config(codec, NULL, alc268_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002591}
2592
Takashi Iwai1d045db2011-07-07 18:23:21 +02002593/*
2594 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002595static int patch_alc268(struct hda_codec *codec)
2596{
2597 struct alc_spec *spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002598 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002599
Takashi Iwai1d045db2011-07-07 18:23:21 +02002600 /* ALC268 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02002601 err = alc_alloc_spec(codec, 0);
2602 if (err < 0)
2603 return err;
2604
2605 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002606 spec->gen.beep_nid = 0x01;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002607
Takashi Iwai225068a2015-05-29 10:42:14 +02002608 spec->shutup = alc_eapd_shutup;
2609
Takashi Iwai1727a772013-01-10 09:52:52 +01002610 snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2611 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002612
Takashi Iwai6ebb8052011-08-16 15:15:40 +02002613 /* automatic parse from the BIOS config */
2614 err = alc268_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002615 if (err < 0)
2616 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002617
Takashi Iwai7504b6c2013-03-18 11:25:51 +01002618 if (err > 0 && !spec->gen.no_analog &&
2619 spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2620 add_mixer(spec, alc268_beep_mixer);
2621 snd_hda_add_verbs(codec, alc268_beep_init_verbs);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002622 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2623 /* override the amp caps for beep generator */
2624 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2625 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2626 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2627 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2628 (0 << AC_AMPCAP_MUTE_SHIFT));
2629 }
2630
Takashi Iwai1727a772013-01-10 09:52:52 +01002631 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai6e72aa52012-06-25 10:52:25 +02002632
Takashi Iwai1d045db2011-07-07 18:23:21 +02002633 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02002634
2635 error:
2636 alc_free(codec);
2637 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02002638}
2639
2640/*
2641 * ALC269
2642 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01002643
Takashi Iwai1d045db2011-07-07 18:23:21 +02002644static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002645 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002646};
2647
2648static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002649 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
Takashi Iwai1d045db2011-07-07 18:23:21 +02002650};
2651
Takashi Iwai1d045db2011-07-07 18:23:21 +02002652/* different alc269-variants */
2653enum {
2654 ALC269_TYPE_ALC269VA,
2655 ALC269_TYPE_ALC269VB,
2656 ALC269_TYPE_ALC269VC,
Kailang Yangadcc70b2012-05-25 08:08:38 +02002657 ALC269_TYPE_ALC269VD,
Kailang Yang065380f2013-01-10 10:25:48 +01002658 ALC269_TYPE_ALC280,
2659 ALC269_TYPE_ALC282,
Kailang Yang2af02be2013-08-22 10:03:50 +02002660 ALC269_TYPE_ALC283,
Kailang Yang065380f2013-01-10 10:25:48 +01002661 ALC269_TYPE_ALC284,
Kailang Yang161ebf22013-10-24 11:36:33 +02002662 ALC269_TYPE_ALC285,
Kailang Yang7fc7d042013-04-25 11:04:43 +02002663 ALC269_TYPE_ALC286,
Kailang Yang506b62c2014-12-18 17:07:44 +08002664 ALC269_TYPE_ALC298,
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002665 ALC269_TYPE_ALC255,
Kailang Yang4344aec2014-12-17 17:39:05 +08002666 ALC269_TYPE_ALC256,
Kailang Yang2435d6b2017-12-05 15:38:24 +08002667 ALC269_TYPE_ALC257,
Kailang Yang42314302016-02-03 15:03:50 +08002668 ALC269_TYPE_ALC225,
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002669 ALC269_TYPE_ALC294,
Kailang Yang6fbae352016-05-30 16:44:20 +08002670 ALC269_TYPE_ALC700,
Takashi Iwai1d045db2011-07-07 18:23:21 +02002671};
2672
2673/*
2674 * BIOS auto configuration
2675 */
2676static int alc269_parse_auto_config(struct hda_codec *codec)
2677{
Takashi Iwai1d045db2011-07-07 18:23:21 +02002678 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002679 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2680 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2681 struct alc_spec *spec = codec->spec;
Kailang Yangadcc70b2012-05-25 08:08:38 +02002682 const hda_nid_t *ssids;
2683
2684 switch (spec->codec_variant) {
2685 case ALC269_TYPE_ALC269VA:
2686 case ALC269_TYPE_ALC269VC:
Kailang Yang065380f2013-01-10 10:25:48 +01002687 case ALC269_TYPE_ALC280:
2688 case ALC269_TYPE_ALC284:
Kailang Yang161ebf22013-10-24 11:36:33 +02002689 case ALC269_TYPE_ALC285:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002690 ssids = alc269va_ssids;
2691 break;
2692 case ALC269_TYPE_ALC269VB:
2693 case ALC269_TYPE_ALC269VD:
Kailang Yang065380f2013-01-10 10:25:48 +01002694 case ALC269_TYPE_ALC282:
Kailang Yang2af02be2013-08-22 10:03:50 +02002695 case ALC269_TYPE_ALC283:
Kailang Yang7fc7d042013-04-25 11:04:43 +02002696 case ALC269_TYPE_ALC286:
Kailang Yang506b62c2014-12-18 17:07:44 +08002697 case ALC269_TYPE_ALC298:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02002698 case ALC269_TYPE_ALC255:
Kailang Yang4344aec2014-12-17 17:39:05 +08002699 case ALC269_TYPE_ALC256:
Kailang Yang2435d6b2017-12-05 15:38:24 +08002700 case ALC269_TYPE_ALC257:
Kailang Yang42314302016-02-03 15:03:50 +08002701 case ALC269_TYPE_ALC225:
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08002702 case ALC269_TYPE_ALC294:
Kailang Yang6fbae352016-05-30 16:44:20 +08002703 case ALC269_TYPE_ALC700:
Kailang Yangadcc70b2012-05-25 08:08:38 +02002704 ssids = alc269_ssids;
2705 break;
2706 default:
2707 ssids = alc269_ssids;
2708 break;
2709 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02002710
Takashi Iwai3e6179b2011-07-08 16:55:13 +02002711 return alc_parse_auto_config(codec, alc269_ignore, ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002712}
2713
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08002714static int find_ext_mic_pin(struct hda_codec *codec);
2715
2716static void alc286_shutup(struct hda_codec *codec)
2717{
2718 int i;
2719 int mic_pin = find_ext_mic_pin(codec);
2720 /* don't shut up pins when unloading the driver; otherwise it breaks
2721 * the default pin setup at the next load of the driver
2722 */
2723 if (codec->bus->shutdown)
2724 return;
2725 for (i = 0; i < codec->init_pins.used; i++) {
2726 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
2727 /* use read here for syncing after issuing each verb */
2728 if (pin->nid != mic_pin)
2729 snd_hda_codec_read(codec, pin->nid, 0,
2730 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2731 }
2732 codec->pins_shutup = 1;
2733}
2734
Kailang Yang1387e2d2012-11-08 10:23:18 +01002735static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
Takashi Iwai1d045db2011-07-07 18:23:21 +02002736{
Takashi Iwai98b24882014-08-18 13:47:50 +02002737 alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002738}
2739
2740static void alc269_shutup(struct hda_codec *codec)
2741{
Kailang Yangadcc70b2012-05-25 08:08:38 +02002742 struct alc_spec *spec = codec->spec;
2743
Kailang Yang1387e2d2012-11-08 10:23:18 +01002744 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2745 alc269vb_toggle_power_output(codec, 0);
2746 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2747 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02002748 msleep(150);
2749 }
Takashi Iwai9bfb2842013-07-24 14:31:50 +02002750 snd_hda_shutup_pins(codec);
Takashi Iwai1d045db2011-07-07 18:23:21 +02002751}
2752
Takashi Iwai54db6c32014-08-18 15:11:19 +02002753static struct coef_fw alc282_coefs[] = {
2754 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang32fa7e42014-10-24 16:26:01 +08002755 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002756 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2757 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2758 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2759 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2760 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2761 WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2762 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2763 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2764 WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2765 UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2766 WRITE_COEF(0x34, 0xa0c0), /* ANC */
2767 UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2768 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2769 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2770 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2771 WRITE_COEF(0x63, 0x2902), /* PLL */
2772 WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2773 WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2774 WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2775 WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2776 UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2777 WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2778 UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2779 WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2780 WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2781 UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2782 WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2783 {}
2784};
2785
Kailang Yangcb149cb2014-03-18 16:45:32 +08002786static void alc282_restore_default_value(struct hda_codec *codec)
2787{
Takashi Iwai54db6c32014-08-18 15:11:19 +02002788 alc_process_coef_fw(codec, alc282_coefs);
Kailang Yangcb149cb2014-03-18 16:45:32 +08002789}
2790
Kailang Yang7b5c7a02014-03-18 16:15:54 +08002791static void alc282_init(struct hda_codec *codec)
2792{
2793 struct alc_spec *spec = codec->spec;
2794 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2795 bool hp_pin_sense;
2796 int coef78;
2797
Kailang Yangcb149cb2014-03-18 16:45:32 +08002798 alc282_restore_default_value(codec);
2799
Kailang Yang7b5c7a02014-03-18 16:15:54 +08002800 if (!hp_pin)
2801 return;
2802 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2803 coef78 = alc_read_coef_idx(codec, 0x78);
2804
2805 /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2806 /* Headphone capless set to high power mode */
2807 alc_write_coef_idx(codec, 0x78, 0x9004);
2808
2809 if (hp_pin_sense)
2810 msleep(2);
2811
2812 snd_hda_codec_write(codec, hp_pin, 0,
2813 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2814
2815 if (hp_pin_sense)
2816 msleep(85);
2817
2818 snd_hda_codec_write(codec, hp_pin, 0,
2819 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2820
2821 if (hp_pin_sense)
2822 msleep(100);
2823
2824 /* Headphone capless set to normal mode */
2825 alc_write_coef_idx(codec, 0x78, coef78);
2826}
2827
2828static void alc282_shutup(struct hda_codec *codec)
2829{
2830 struct alc_spec *spec = codec->spec;
2831 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2832 bool hp_pin_sense;
2833 int coef78;
2834
2835 if (!hp_pin) {
2836 alc269_shutup(codec);
2837 return;
2838 }
2839
2840 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2841 coef78 = alc_read_coef_idx(codec, 0x78);
2842 alc_write_coef_idx(codec, 0x78, 0x9004);
2843
2844 if (hp_pin_sense)
2845 msleep(2);
2846
2847 snd_hda_codec_write(codec, hp_pin, 0,
2848 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2849
2850 if (hp_pin_sense)
2851 msleep(85);
2852
2853 snd_hda_codec_write(codec, hp_pin, 0,
2854 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2855
2856 if (hp_pin_sense)
2857 msleep(100);
2858
2859 alc_auto_setup_eapd(codec, false);
2860 snd_hda_shutup_pins(codec);
2861 alc_write_coef_idx(codec, 0x78, coef78);
2862}
2863
Takashi Iwai54db6c32014-08-18 15:11:19 +02002864static struct coef_fw alc283_coefs[] = {
2865 WRITE_COEF(0x03, 0x0002), /* Power Down Control */
Kailang Yang56779862014-10-24 16:17:51 +08002866 UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002867 WRITE_COEF(0x07, 0x0200), /* DMIC control */
2868 UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2869 UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2870 WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2871 WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2872 WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
2873 UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2874 UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2875 WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
2876 UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
2877 WRITE_COEF(0x22, 0xa0c0), /* ANC */
2878 UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
2879 UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2880 UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2881 WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2882 WRITE_COEF(0x2e, 0x2902), /* PLL */
2883 WRITE_COEF(0x33, 0xa080), /* capless control 2 */
2884 WRITE_COEF(0x34, 0x3400), /* capless control 3 */
2885 WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
2886 WRITE_COEF(0x36, 0x0), /* capless control 5 */
2887 UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
2888 WRITE_COEF(0x39, 0x110a), /* class D test 3 */
2889 UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
2890 WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
2891 WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
2892 UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
2893 WRITE_COEF(0x49, 0x0), /* test mode */
2894 UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
2895 UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
2896 WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
Kailang Yang56779862014-10-24 16:17:51 +08002897 UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
Takashi Iwai54db6c32014-08-18 15:11:19 +02002898 {}
2899};
2900
Kailang Yang6bd55b02014-03-17 13:51:27 +08002901static void alc283_restore_default_value(struct hda_codec *codec)
2902{
Takashi Iwai54db6c32014-08-18 15:11:19 +02002903 alc_process_coef_fw(codec, alc283_coefs);
Kailang Yang6bd55b02014-03-17 13:51:27 +08002904}
2905
Kailang Yang2af02be2013-08-22 10:03:50 +02002906static void alc283_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;
Kailang Yang2af02be2013-08-22 10:03:50 +02002911
Kailang Yang8314f222014-04-03 17:28:39 +08002912 if (!spec->gen.autocfg.hp_outs) {
2913 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2914 hp_pin = spec->gen.autocfg.line_out_pins[0];
2915 }
2916
Kailang Yang6bd55b02014-03-17 13:51:27 +08002917 alc283_restore_default_value(codec);
2918
Kailang Yang2af02be2013-08-22 10:03:50 +02002919 if (!hp_pin)
2920 return;
Kailang Yanga59d7192015-04-08 16:34:00 +08002921
2922 msleep(30);
Kailang Yang2af02be2013-08-22 10:03:50 +02002923 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2924
2925 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2926 /* Headphone capless set to high power mode */
2927 alc_write_coef_idx(codec, 0x43, 0x9004);
2928
2929 snd_hda_codec_write(codec, hp_pin, 0,
2930 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2931
2932 if (hp_pin_sense)
2933 msleep(85);
2934
2935 snd_hda_codec_write(codec, hp_pin, 0,
2936 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2937
2938 if (hp_pin_sense)
2939 msleep(85);
2940 /* Index 0x46 Combo jack auto switch control 2 */
2941 /* 3k pull low control for Headset jack. */
Takashi Iwai98b24882014-08-18 13:47:50 +02002942 alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
Kailang Yang2af02be2013-08-22 10:03:50 +02002943 /* Headphone capless set to normal mode */
2944 alc_write_coef_idx(codec, 0x43, 0x9614);
2945}
2946
2947static void alc283_shutup(struct hda_codec *codec)
2948{
2949 struct alc_spec *spec = codec->spec;
2950 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2951 bool hp_pin_sense;
Kailang Yang2af02be2013-08-22 10:03:50 +02002952
Kailang Yang8314f222014-04-03 17:28:39 +08002953 if (!spec->gen.autocfg.hp_outs) {
2954 if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2955 hp_pin = spec->gen.autocfg.line_out_pins[0];
2956 }
2957
Kailang Yang2af02be2013-08-22 10:03:50 +02002958 if (!hp_pin) {
2959 alc269_shutup(codec);
2960 return;
2961 }
2962
2963 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2964
2965 alc_write_coef_idx(codec, 0x43, 0x9004);
2966
Harsha Priyab450b172014-10-09 11:04:56 +00002967 /*depop hp during suspend*/
2968 alc_write_coef_idx(codec, 0x06, 0x2100);
2969
Kailang Yang2af02be2013-08-22 10:03:50 +02002970 snd_hda_codec_write(codec, hp_pin, 0,
2971 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2972
2973 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02002974 msleep(100);
Kailang Yang2af02be2013-08-22 10:03:50 +02002975
2976 snd_hda_codec_write(codec, hp_pin, 0,
2977 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2978
Takashi Iwai98b24882014-08-18 13:47:50 +02002979 alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
Kailang Yang2af02be2013-08-22 10:03:50 +02002980
2981 if (hp_pin_sense)
Kailang Yang88011c092013-10-24 15:45:24 +02002982 msleep(100);
Kailang Yang0435b3f2014-04-08 17:14:14 +08002983 alc_auto_setup_eapd(codec, false);
Kailang Yang2af02be2013-08-22 10:03:50 +02002984 snd_hda_shutup_pins(codec);
2985 alc_write_coef_idx(codec, 0x43, 0x9614);
2986}
2987
Kailang Yangad60d502013-06-28 12:03:01 +02002988static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2989 unsigned int val)
2990{
2991 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2992 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2993 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2994}
2995
2996static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2997{
2998 unsigned int val;
2999
3000 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3001 val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3002 & 0xffff;
3003 val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3004 << 16;
3005 return val;
3006}
3007
3008static void alc5505_dsp_halt(struct hda_codec *codec)
3009{
3010 unsigned int val;
3011
3012 alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3013 alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3014 alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3015 alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3016 alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3017 alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3018 alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3019 val = alc5505_coef_get(codec, 0x6220);
3020 alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3021}
3022
3023static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3024{
3025 alc5505_coef_set(codec, 0x61b8, 0x04133302);
3026 alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3027 alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3028 alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3029 alc5505_coef_set(codec, 0x6220, 0x2002010f);
3030 alc5505_coef_set(codec, 0x880c, 0x00000004);
3031}
3032
3033static void alc5505_dsp_init(struct hda_codec *codec)
3034{
3035 unsigned int val;
3036
3037 alc5505_dsp_halt(codec);
3038 alc5505_dsp_back_from_halt(codec);
3039 alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3040 alc5505_coef_set(codec, 0x61b0, 0x5b16);
3041 alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3042 alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3043 alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3044 alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3045 snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3046 alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3047 alc5505_coef_set(codec, 0x61b8, 0x04173302);
3048 alc5505_coef_set(codec, 0x61b8, 0x04163302);
3049 alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3050 alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3051 alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3052
3053 val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3054 if (val <= 3)
3055 alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3056 else
3057 alc5505_coef_set(codec, 0x6220, 0x6002018f);
3058
3059 alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3060 alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3061 alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3062 alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3063 alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3064 alc5505_coef_set(codec, 0x880c, 0x00000003);
3065 alc5505_coef_set(codec, 0x880c, 0x00000010);
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003066
3067#ifdef HALT_REALTEK_ALC5505
3068 alc5505_dsp_halt(codec);
3069#endif
Kailang Yangad60d502013-06-28 12:03:01 +02003070}
3071
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003072#ifdef HALT_REALTEK_ALC5505
3073#define alc5505_dsp_suspend(codec) /* NOP */
3074#define alc5505_dsp_resume(codec) /* NOP */
3075#else
3076#define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec)
3077#define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec)
3078#endif
3079
Takashi Iwai2a439522011-07-26 09:52:50 +02003080#ifdef CONFIG_PM
Kailang Yangad60d502013-06-28 12:03:01 +02003081static int alc269_suspend(struct hda_codec *codec)
3082{
3083 struct alc_spec *spec = codec->spec;
3084
3085 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003086 alc5505_dsp_suspend(codec);
Kailang Yangad60d502013-06-28 12:03:01 +02003087 return alc_suspend(codec);
3088}
3089
Takashi Iwai1d045db2011-07-07 18:23:21 +02003090static int alc269_resume(struct hda_codec *codec)
3091{
Kailang Yangadcc70b2012-05-25 08:08:38 +02003092 struct alc_spec *spec = codec->spec;
3093
Kailang Yang1387e2d2012-11-08 10:23:18 +01003094 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3095 alc269vb_toggle_power_output(codec, 0);
3096 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003097 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003098 msleep(150);
3099 }
3100
3101 codec->patch_ops.init(codec);
3102
Kailang Yang1387e2d2012-11-08 10:23:18 +01003103 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3104 alc269vb_toggle_power_output(codec, 1);
3105 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
Kailang Yangadcc70b2012-05-25 08:08:38 +02003106 (alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02003107 msleep(200);
3108 }
3109
Takashi Iwaieeecd9d2015-02-25 15:18:50 +01003110 regcache_sync(codec->core.regmap);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003111 hda_call_check_power_status(codec, 0x01);
Hui Wangf4753712014-08-19 12:07:03 +08003112
3113 /* on some machine, the BIOS will clear the codec gpio data when enter
3114 * suspend, and won't restore the data after resume, so we restore it
3115 * in the driver.
3116 */
3117 if (spec->gpio_led)
Takashi Iwai7639a062015-03-03 10:07:24 +01003118 snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA,
Hui Wangf4753712014-08-19 12:07:03 +08003119 spec->gpio_led);
3120
Kailang Yangad60d502013-06-28 12:03:01 +02003121 if (spec->has_alc5505_dsp)
Takashi Iwaicd63a5f2013-07-05 12:13:59 +02003122 alc5505_dsp_resume(codec);
Kailang Yangc5177c82013-07-24 14:39:49 +02003123
Takashi Iwai1d045db2011-07-07 18:23:21 +02003124 return 0;
3125}
Takashi Iwai2a439522011-07-26 09:52:50 +02003126#endif /* CONFIG_PM */
Takashi Iwai1d045db2011-07-07 18:23:21 +02003127
David Henningsson108cc102012-07-20 10:37:25 +02003128static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003129 const struct hda_fixup *fix, int action)
David Henningsson108cc102012-07-20 10:37:25 +02003130{
3131 struct alc_spec *spec = codec->spec;
3132
Takashi Iwai1727a772013-01-10 09:52:52 +01003133 if (action == HDA_FIXUP_ACT_PRE_PROBE)
David Henningsson108cc102012-07-20 10:37:25 +02003134 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3135}
3136
Jan-Marek Glogowskibb1a4222018-02-14 11:29:15 +01003137static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec,
3138 const struct hda_fixup *fix,
3139 int action)
3140{
3141 unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21);
3142 unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19);
3143
3144 if (cfg_headphone && cfg_headset_mic == 0x411111f0)
3145 snd_hda_codec_set_pincfg(codec, 0x19,
3146 (cfg_headphone & ~AC_DEFCFG_DEVICE) |
3147 (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT));
3148}
3149
Takashi Iwai1d045db2011-07-07 18:23:21 +02003150static void alc269_fixup_hweq(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003151 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003152{
Takashi Iwai98b24882014-08-18 13:47:50 +02003153 if (action == HDA_FIXUP_ACT_INIT)
3154 alc_update_coef_idx(codec, 0x1e, 0, 0x80);
Takashi Iwai1d045db2011-07-07 18:23:21 +02003155}
3156
David Henningsson7c478f02013-10-11 10:18:46 +02003157static void alc269_fixup_headset_mic(struct hda_codec *codec,
3158 const struct hda_fixup *fix, int action)
3159{
3160 struct alc_spec *spec = codec->spec;
3161
3162 if (action == HDA_FIXUP_ACT_PRE_PROBE)
3163 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3164}
3165
Takashi Iwai1d045db2011-07-07 18:23:21 +02003166static void alc271_fixup_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003167 const struct hda_fixup *fix, int action)
Takashi Iwai1d045db2011-07-07 18:23:21 +02003168{
3169 static const struct hda_verb verbs[] = {
3170 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3171 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3172 {}
3173 };
3174 unsigned int cfg;
3175
Takashi Iwai7639a062015-03-03 10:07:24 +01003176 if (strcmp(codec->core.chip_name, "ALC271X") &&
3177 strcmp(codec->core.chip_name, "ALC269VB"))
Takashi Iwai1d045db2011-07-07 18:23:21 +02003178 return;
3179 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3180 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3181 snd_hda_sequence_write(codec, verbs);
3182}
3183
Takashi Iwai017f2a12011-07-09 14:42:25 +02003184static void alc269_fixup_pcm_44k(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003185 const struct hda_fixup *fix, int action)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003186{
3187 struct alc_spec *spec = codec->spec;
3188
Takashi Iwai1727a772013-01-10 09:52:52 +01003189 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai017f2a12011-07-09 14:42:25 +02003190 return;
3191
3192 /* Due to a hardware problem on Lenovo Ideadpad, we need to
3193 * fix the sample rate of analog I/O to 44.1kHz
3194 */
Takashi Iwai08c189f2012-12-19 15:22:24 +01003195 spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3196 spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
Takashi Iwai017f2a12011-07-09 14:42:25 +02003197}
3198
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003199static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003200 const struct hda_fixup *fix, int action)
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003201{
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003202 /* The digital-mic unit sends PDM (differential signal) instead of
3203 * the standard PCM, thus you can't record a valid mono stream as is.
3204 * Below is a workaround specific to ALC269 to control the dmic
3205 * signal source as mono.
3206 */
Takashi Iwai98b24882014-08-18 13:47:50 +02003207 if (action == HDA_FIXUP_ACT_INIT)
3208 alc_update_coef_idx(codec, 0x07, 0, 0x80);
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02003209}
3210
Takashi Iwai24519912011-08-16 15:08:49 +02003211static void alc269_quanta_automute(struct hda_codec *codec)
3212{
Takashi Iwai08c189f2012-12-19 15:22:24 +01003213 snd_hda_gen_update_outputs(codec);
Takashi Iwai24519912011-08-16 15:08:49 +02003214
Takashi Iwai1687ccc2014-08-18 13:49:35 +02003215 alc_write_coef_idx(codec, 0x0c, 0x680);
3216 alc_write_coef_idx(codec, 0x0c, 0x480);
Takashi Iwai24519912011-08-16 15:08:49 +02003217}
3218
3219static void alc269_fixup_quanta_mute(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01003220 const struct hda_fixup *fix, int action)
Takashi Iwai24519912011-08-16 15:08:49 +02003221{
3222 struct alc_spec *spec = codec->spec;
Takashi Iwai1727a772013-01-10 09:52:52 +01003223 if (action != HDA_FIXUP_ACT_PROBE)
Takashi Iwai24519912011-08-16 15:08:49 +02003224 return;
Takashi Iwai08c189f2012-12-19 15:22:24 +01003225 spec->gen.automute_hook = alc269_quanta_automute;
Takashi Iwai24519912011-08-16 15:08:49 +02003226}
3227
David Henningssond240d1d2013-04-15 12:50:02 +02003228static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02003229 struct hda_jack_callback *jack)
David Henningssond240d1d2013-04-15 12:50:02 +02003230{
3231 struct alc_spec *spec = codec->spec;
3232 int vref;
3233 msleep(200);
3234 snd_hda_gen_hp_automute(codec, jack);
3235
3236 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3237 msleep(100);
3238 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3239 vref);
3240 msleep(500);
3241 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3242 vref);
3243}
3244
3245static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3246 const struct hda_fixup *fix, int action)
3247{
3248 struct alc_spec *spec = codec->spec;
3249 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3250 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3251 spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3252 }
3253}
3254
3255
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003256/* update mute-LED according to the speaker mute state via mic VREF pin */
3257static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003258{
3259 struct hda_codec *codec = private_data;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003260 struct alc_spec *spec = codec->spec;
3261 unsigned int pinval;
3262
3263 if (spec->mute_led_polarity)
3264 enabled = !enabled;
Takashi Iwai415d5552014-04-03 11:51:21 +02003265 pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3266 pinval &= ~AC_PINCTL_VREFEN;
3267 pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
Takashi Iwaiff0b03a2018-03-17 22:40:18 +01003268 if (spec->mute_led_nid) {
3269 /* temporarily power up/down for setting VREF */
3270 snd_hda_power_up_pm(codec);
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003271 snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
Takashi Iwaiff0b03a2018-03-17 22:40:18 +01003272 snd_hda_power_down_pm(codec);
3273 }
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003274}
3275
David Henningssond5b6b652013-11-06 10:50:44 +01003276/* Make sure the led works even in runtime suspend */
3277static unsigned int led_power_filter(struct hda_codec *codec,
3278 hda_nid_t nid,
3279 unsigned int power_state)
3280{
3281 struct alc_spec *spec = codec->spec;
3282
Hui Wang50dd9052014-07-08 17:56:15 +08003283 if (power_state != AC_PWRST_D3 || nid == 0 ||
3284 (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
David Henningssond5b6b652013-11-06 10:50:44 +01003285 return power_state;
3286
3287 /* Set pin ctl again, it might have just been set to 0 */
3288 snd_hda_set_pin_ctl(codec, nid,
3289 snd_hda_codec_get_pin_target(codec, nid));
3290
Takashi Iwaicffd3962015-04-09 10:30:25 +02003291 return snd_hda_gen_path_power_filter(codec, nid, power_state);
David Henningssond5b6b652013-11-06 10:50:44 +01003292}
3293
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003294static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3295 const struct hda_fixup *fix, int action)
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003296{
3297 struct alc_spec *spec = codec->spec;
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003298 const struct dmi_device *dev = NULL;
3299
3300 if (action != HDA_FIXUP_ACT_PRE_PROBE)
3301 return;
3302
3303 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3304 int pol, pin;
3305 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3306 continue;
3307 if (pin < 0x0a || pin >= 0x10)
3308 break;
3309 spec->mute_led_polarity = pol;
3310 spec->mute_led_nid = pin - 0x0a + 0x18;
3311 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003312 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003313 codec->power_filter = led_power_filter;
Takashi Iwai4e76a882014-02-25 12:21:03 +01003314 codec_dbg(codec,
3315 "Detected mute LED for %x:%d\n", spec->mute_led_nid,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003316 spec->mute_led_polarity);
David Henningsson6d3cd5d2013-01-07 12:03:47 +01003317 break;
3318 }
3319}
3320
David Henningssond06ac142013-02-18 11:41:55 +01003321static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3322 const struct hda_fixup *fix, int action)
3323{
3324 struct alc_spec *spec = codec->spec;
3325 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3326 spec->mute_led_polarity = 0;
3327 spec->mute_led_nid = 0x18;
3328 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3329 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003330 codec->power_filter = led_power_filter;
David Henningssond06ac142013-02-18 11:41:55 +01003331 }
3332}
3333
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003334static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3335 const struct hda_fixup *fix, int action)
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003336{
3337 struct alc_spec *spec = codec->spec;
Takashi Iwai9bb1f062013-01-10 17:14:29 +01003338 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai08fb0d02013-01-10 17:33:58 +01003339 spec->mute_led_polarity = 0;
3340 spec->mute_led_nid = 0x19;
3341 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
Takashi Iwaifd25a972012-12-20 14:57:18 +01003342 spec->gen.vmaster_mute_enum = 1;
David Henningssond5b6b652013-11-06 10:50:44 +01003343 codec->power_filter = led_power_filter;
Takashi Iwai420b0fe2012-03-12 12:35:27 +01003344 }
3345}
3346
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003347/* update LED status via GPIO */
3348static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3349 bool enabled)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003350{
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003351 struct alc_spec *spec = codec->spec;
3352 unsigned int oldval = spec->gpio_led;
3353
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003354 if (spec->mute_led_polarity)
3355 enabled = !enabled;
3356
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003357 if (enabled)
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003358 spec->gpio_led &= ~mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003359 else
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003360 spec->gpio_led |= mask;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003361 if (spec->gpio_led != oldval)
3362 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3363 spec->gpio_led);
3364}
3365
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003366/* turn on/off mute LED via GPIO per vmaster hook */
3367static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3368{
3369 struct hda_codec *codec = private_data;
3370 struct alc_spec *spec = codec->spec;
3371
3372 alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3373}
3374
3375/* turn on/off mic-mute LED via GPIO per capture hook */
3376static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
3377 struct snd_kcontrol *kcontrol,
3378 struct snd_ctl_elem_value *ucontrol)
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003379{
3380 struct alc_spec *spec = codec->spec;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003381
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003382 if (ucontrol)
3383 alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3384 ucontrol->value.integer.value[0] ||
3385 ucontrol->value.integer.value[1]);
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003386}
3387
3388static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3389 const struct hda_fixup *fix, int action)
3390{
3391 struct alc_spec *spec = codec->spec;
3392 static const struct hda_verb gpio_init[] = {
3393 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3394 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3395 {}
3396 };
3397
3398 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003399 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3400 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003401 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003402 spec->mute_led_polarity = 0;
3403 spec->gpio_mute_led_mask = 0x08;
3404 spec->gpio_mic_led_mask = 0x10;
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01003405 snd_hda_add_verbs(codec, gpio_init);
3406 }
3407}
3408
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08003409static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3410 const struct hda_fixup *fix, int action)
3411{
3412 struct alc_spec *spec = codec->spec;
3413 static const struct hda_verb gpio_init[] = {
3414 { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3415 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3416 {}
3417 };
3418
3419 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3420 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3421 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3422 spec->gpio_led = 0;
3423 spec->mute_led_polarity = 0;
3424 spec->gpio_mute_led_mask = 0x02;
3425 spec->gpio_mic_led_mask = 0x20;
Takashi Iwai1d045db2011-07-07 18:23:21 +02003426 snd_hda_add_verbs(codec, gpio_init);
3427 }
3428}
3429
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003430/* turn on/off mic-mute LED per capture hook */
3431static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
3432 struct snd_kcontrol *kcontrol,
3433 struct snd_ctl_elem_value *ucontrol)
3434{
3435 struct alc_spec *spec = codec->spec;
3436 unsigned int pinval, enable, disable;
3437
Hui Wangfc1fad92014-07-08 17:56:14 +08003438 pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003439 pinval &= ~AC_PINCTL_VREFEN;
3440 enable = pinval | AC_PINCTL_VREF_80;
3441 disable = pinval | AC_PINCTL_VREF_HIZ;
3442
3443 if (!ucontrol)
3444 return;
3445
3446 if (ucontrol->value.integer.value[0] ||
3447 ucontrol->value.integer.value[1])
3448 pinval = disable;
3449 else
3450 pinval = enable;
3451
3452 if (spec->cap_mute_led_nid)
3453 snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
3454}
3455
3456static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3457 const struct hda_fixup *fix, int action)
3458{
3459 struct alc_spec *spec = codec->spec;
3460 static const struct hda_verb gpio_init[] = {
3461 { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3462 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3463 {}
3464 };
3465
3466 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003467 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003468 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3469 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003470 spec->mute_led_polarity = 0;
3471 spec->gpio_mute_led_mask = 0x08;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003472 spec->cap_mute_led_nid = 0x18;
3473 snd_hda_add_verbs(codec, gpio_init);
Hui Wang50dd9052014-07-08 17:56:15 +08003474 codec->power_filter = led_power_filter;
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003475 }
3476}
3477
David Henningsson7a5255f2014-10-30 08:26:01 +01003478static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3479 const struct hda_fixup *fix, int action)
3480{
3481 /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3482 struct alc_spec *spec = codec->spec;
3483 static const struct hda_verb gpio_init[] = {
3484 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3485 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3486 {}
3487 };
3488
3489 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003490 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
David Henningsson7a5255f2014-10-30 08:26:01 +01003491 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3492 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01003493 spec->mute_led_polarity = 0;
3494 spec->gpio_mute_led_mask = 0x08;
David Henningsson7a5255f2014-10-30 08:26:01 +01003495 spec->cap_mute_led_nid = 0x18;
3496 snd_hda_add_verbs(codec, gpio_init);
3497 codec->power_filter = led_power_filter;
3498 }
3499}
3500
Takashi Iwaidba8e962018-04-27 17:17:35 +02003501#if IS_REACHABLE(CONFIG_INPUT)
David Henningsson33f4acd2015-01-07 15:50:13 +01003502static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3503 struct hda_jack_callback *event)
3504{
3505 struct alc_spec *spec = codec->spec;
3506
3507 /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3508 send both key on and key off event for every interrupt. */
Hui Wangc7b60a82015-12-28 11:35:25 +08003509 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 1);
David Henningsson33f4acd2015-01-07 15:50:13 +01003510 input_sync(spec->kb_dev);
Hui Wangc7b60a82015-12-28 11:35:25 +08003511 input_report_key(spec->kb_dev, spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX], 0);
David Henningsson33f4acd2015-01-07 15:50:13 +01003512 input_sync(spec->kb_dev);
3513}
David Henningsson33f4acd2015-01-07 15:50:13 +01003514
Kailang3694cb22015-12-28 11:35:24 +08003515static int alc_register_micmute_input_device(struct hda_codec *codec)
3516{
3517 struct alc_spec *spec = codec->spec;
Hui Wangc7b60a82015-12-28 11:35:25 +08003518 int i;
Kailang3694cb22015-12-28 11:35:24 +08003519
3520 spec->kb_dev = input_allocate_device();
3521 if (!spec->kb_dev) {
3522 codec_err(codec, "Out of memory (input_allocate_device)\n");
3523 return -ENOMEM;
3524 }
Hui Wangc7b60a82015-12-28 11:35:25 +08003525
3526 spec->alc_mute_keycode_map[ALC_KEY_MICMUTE_INDEX] = KEY_MICMUTE;
3527
Kailang3694cb22015-12-28 11:35:24 +08003528 spec->kb_dev->name = "Microphone Mute Button";
3529 spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
Hui Wangc7b60a82015-12-28 11:35:25 +08003530 spec->kb_dev->keycodesize = sizeof(spec->alc_mute_keycode_map[0]);
3531 spec->kb_dev->keycodemax = ARRAY_SIZE(spec->alc_mute_keycode_map);
3532 spec->kb_dev->keycode = spec->alc_mute_keycode_map;
3533 for (i = 0; i < ARRAY_SIZE(spec->alc_mute_keycode_map); i++)
3534 set_bit(spec->alc_mute_keycode_map[i], spec->kb_dev->keybit);
Kailang3694cb22015-12-28 11:35:24 +08003535
3536 if (input_register_device(spec->kb_dev)) {
3537 codec_err(codec, "input_register_device failed\n");
3538 input_free_device(spec->kb_dev);
3539 spec->kb_dev = NULL;
3540 return -ENOMEM;
3541 }
3542
3543 return 0;
3544}
3545
David Henningsson33f4acd2015-01-07 15:50:13 +01003546static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3547 const struct hda_fixup *fix, int action)
3548{
David Henningsson33f4acd2015-01-07 15:50:13 +01003549 /* GPIO1 = set according to SKU external amp
3550 GPIO2 = mic mute hotkey
3551 GPIO3 = mute LED
3552 GPIO4 = mic mute LED */
3553 static const struct hda_verb gpio_init[] = {
3554 { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3555 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3556 { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3557 {}
3558 };
3559
3560 struct alc_spec *spec = codec->spec;
3561
3562 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang3694cb22015-12-28 11:35:24 +08003563 if (alc_register_micmute_input_device(codec) != 0)
David Henningsson33f4acd2015-01-07 15:50:13 +01003564 return;
David Henningsson33f4acd2015-01-07 15:50:13 +01003565
3566 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwai7639a062015-03-03 10:07:24 +01003567 snd_hda_codec_write_cache(codec, codec->core.afg, 0,
David Henningsson33f4acd2015-01-07 15:50:13 +01003568 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
Takashi Iwai7639a062015-03-03 10:07:24 +01003569 snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
David Henningsson33f4acd2015-01-07 15:50:13 +01003570 gpio2_mic_hotkey_event);
3571
3572 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3573 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3574 spec->gpio_led = 0;
3575 spec->mute_led_polarity = 0;
3576 spec->gpio_mute_led_mask = 0x08;
3577 spec->gpio_mic_led_mask = 0x10;
3578 return;
3579 }
3580
3581 if (!spec->kb_dev)
3582 return;
3583
3584 switch (action) {
3585 case HDA_FIXUP_ACT_PROBE:
3586 spec->init_amp = ALC_INIT_DEFAULT;
3587 break;
3588 case HDA_FIXUP_ACT_FREE:
3589 input_unregister_device(spec->kb_dev);
David Henningsson33f4acd2015-01-07 15:50:13 +01003590 spec->kb_dev = NULL;
3591 }
David Henningsson33f4acd2015-01-07 15:50:13 +01003592}
3593
Kailang3694cb22015-12-28 11:35:24 +08003594static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec,
3595 const struct hda_fixup *fix, int action)
3596{
3597 /* Line2 = mic mute hotkey
3598 GPIO2 = mic mute LED */
3599 static const struct hda_verb gpio_init[] = {
3600 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
3601 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
3602 {}
3603 };
3604
3605 struct alc_spec *spec = codec->spec;
3606
3607 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3608 if (alc_register_micmute_input_device(codec) != 0)
3609 return;
3610
3611 snd_hda_add_verbs(codec, gpio_init);
3612 snd_hda_jack_detect_enable_callback(codec, 0x1b,
3613 gpio2_mic_hotkey_event);
3614
3615 spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3616 spec->gpio_led = 0;
3617 spec->mute_led_polarity = 0;
3618 spec->gpio_mic_led_mask = 0x04;
3619 return;
3620 }
3621
3622 if (!spec->kb_dev)
3623 return;
3624
3625 switch (action) {
3626 case HDA_FIXUP_ACT_PROBE:
3627 spec->init_amp = ALC_INIT_DEFAULT;
3628 break;
3629 case HDA_FIXUP_ACT_FREE:
3630 input_unregister_device(spec->kb_dev);
3631 spec->kb_dev = NULL;
3632 }
3633}
Takashi Iwai71bff392018-01-15 10:44:35 +01003634#else /* INPUT */
3635#define alc280_fixup_hp_gpio2_mic_hotkey NULL
3636#define alc233_fixup_lenovo_line2_mic_hotkey NULL
3637#endif /* INPUT */
Kailang3694cb22015-12-28 11:35:24 +08003638
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08003639static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3640 const struct hda_fixup *fix, int action)
3641{
3642 struct alc_spec *spec = codec->spec;
3643
3644 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3645 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3646 spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3647 spec->mute_led_polarity = 0;
3648 spec->mute_led_nid = 0x1a;
3649 spec->cap_mute_led_nid = 0x18;
3650 spec->gen.vmaster_mute_enum = 1;
3651 codec->power_filter = led_power_filter;
3652 }
3653}
3654
David Henningsson73bdd592013-04-15 15:44:14 +02003655static void alc_headset_mode_unplugged(struct hda_codec *codec)
3656{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003657 static struct coef_fw coef0255[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02003658 WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
3659 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
3660 WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
3661 WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
3662 {}
3663 };
Kailang Yange69e7e02016-05-30 15:58:28 +08003664 static struct coef_fw coef0255_1[] = {
3665 WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
3666 {}
3667 };
3668 static struct coef_fw coef0256[] = {
3669 WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
3670 {}
3671 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003672 static struct coef_fw coef0233[] = {
3673 WRITE_COEF(0x1b, 0x0c0b),
3674 WRITE_COEF(0x45, 0xc429),
3675 UPDATE_COEF(0x35, 0x4000, 0),
3676 WRITE_COEF(0x06, 0x2104),
3677 WRITE_COEF(0x1a, 0x0001),
3678 WRITE_COEF(0x26, 0x0004),
3679 WRITE_COEF(0x32, 0x42a3),
3680 {}
3681 };
Kailang Yangf3b70332015-04-08 15:01:17 +08003682 static struct coef_fw coef0288[] = {
3683 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3684 UPDATE_COEF(0x50, 0x2000, 0x2000),
3685 UPDATE_COEF(0x56, 0x0006, 0x0006),
3686 UPDATE_COEF(0x66, 0x0008, 0),
3687 UPDATE_COEF(0x67, 0x2000, 0),
3688 {}
3689 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003690 static struct coef_fw coef0292[] = {
3691 WRITE_COEF(0x76, 0x000e),
3692 WRITE_COEF(0x6c, 0x2400),
3693 WRITE_COEF(0x18, 0x7308),
3694 WRITE_COEF(0x6b, 0xc429),
3695 {}
3696 };
3697 static struct coef_fw coef0293[] = {
3698 UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
3699 UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
3700 UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
3701 UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
3702 WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
3703 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3704 {}
3705 };
3706 static struct coef_fw coef0668[] = {
3707 WRITE_COEF(0x15, 0x0d40),
3708 WRITE_COEF(0xb7, 0x802b),
3709 {}
3710 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003711 static struct coef_fw coef0225[] = {
3712 UPDATE_COEF(0x4a, 1<<8, 0),
3713 UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
3714 UPDATE_COEF(0x63, 3<<14, 3<<14),
3715 UPDATE_COEF(0x4a, 3<<4, 2<<4),
3716 UPDATE_COEF(0x4a, 3<<10, 3<<10),
3717 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3718 UPDATE_COEF(0x4a, 3<<10, 0),
3719 {}
3720 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003721
Takashi Iwai7639a062015-03-03 10:07:24 +01003722 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003723 case 0x10ec0255:
Kailang Yange69e7e02016-05-30 15:58:28 +08003724 alc_process_coef_fw(codec, coef0255_1);
3725 alc_process_coef_fw(codec, coef0255);
3726 break;
Kailang Yang61ae3fb2017-10-20 15:06:34 +08003727 case 0x10ec0236:
Kailang Yang7081adf2015-03-30 17:05:37 +08003728 case 0x10ec0256:
Kailang Yange69e7e02016-05-30 15:58:28 +08003729 alc_process_coef_fw(codec, coef0256);
Takashi Iwai54db6c32014-08-18 15:11:19 +02003730 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003731 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08003732 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02003733 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003734 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02003735 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08003736 case 0x10ec0286:
3737 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08003738 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08003739 alc_process_coef_fw(codec, coef0288);
3740 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003741 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003742 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02003743 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08003744 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003745 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08003746 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003747 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003748 alc_process_coef_fw(codec, coef0668);
David Henningsson73bdd592013-04-15 15:44:14 +02003749 break;
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003750 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08003751 case 0x10ec0295:
Kailang Yangf6e94c22017-01-04 14:49:07 +08003752 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003753 alc_process_coef_fw(codec, coef0225);
3754 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08003755 case 0x10ec0867:
3756 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
3757 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003758 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01003759 codec_dbg(codec, "Headset jack set to unplugged mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02003760}
3761
3762
3763static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3764 hda_nid_t mic_pin)
3765{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003766 static struct coef_fw coef0255[] = {
3767 WRITE_COEFEX(0x57, 0x03, 0x8aa6),
3768 WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
3769 {}
3770 };
3771 static struct coef_fw coef0233[] = {
3772 UPDATE_COEF(0x35, 0, 1<<14),
3773 WRITE_COEF(0x06, 0x2100),
3774 WRITE_COEF(0x1a, 0x0021),
3775 WRITE_COEF(0x26, 0x008c),
3776 {}
3777 };
Kailang Yangf3b70332015-04-08 15:01:17 +08003778 static struct coef_fw coef0288[] = {
3779 UPDATE_COEF(0x50, 0x2000, 0),
3780 UPDATE_COEF(0x56, 0x0006, 0),
3781 UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3782 UPDATE_COEF(0x66, 0x0008, 0x0008),
3783 UPDATE_COEF(0x67, 0x2000, 0x2000),
3784 {}
3785 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003786 static struct coef_fw coef0292[] = {
3787 WRITE_COEF(0x19, 0xa208),
3788 WRITE_COEF(0x2e, 0xacf0),
3789 {}
3790 };
3791 static struct coef_fw coef0293[] = {
3792 UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
3793 UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
3794 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3795 {}
3796 };
3797 static struct coef_fw coef0688[] = {
3798 WRITE_COEF(0xb7, 0x802b),
3799 WRITE_COEF(0xb5, 0x1040),
3800 UPDATE_COEF(0xc3, 0, 1<<12),
3801 {}
3802 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003803 static struct coef_fw coef0225[] = {
3804 UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
3805 UPDATE_COEF(0x4a, 3<<4, 2<<4),
3806 UPDATE_COEF(0x63, 3<<14, 0),
3807 {}
3808 };
3809
Takashi Iwai54db6c32014-08-18 15:11:19 +02003810
Takashi Iwai7639a062015-03-03 10:07:24 +01003811 switch (codec->core.vendor_id) {
Kailang Yang61ae3fb2017-10-20 15:06:34 +08003812 case 0x10ec0236:
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003813 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08003814 case 0x10ec0256:
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003815 alc_write_coef_idx(codec, 0x45, 0xc489);
3816 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02003817 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003818 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3819 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08003820 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02003821 case 0x10ec0283:
3822 alc_write_coef_idx(codec, 0x45, 0xc429);
3823 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02003824 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02003825 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3826 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08003827 case 0x10ec0286:
3828 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08003829 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08003830 alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
3831 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3832 alc_process_coef_fw(codec, coef0288);
3833 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3834 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003835 case 0x10ec0292:
3836 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02003837 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02003838 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08003839 case 0x10ec0293:
3840 /* Set to TRS mode */
3841 alc_write_coef_idx(codec, 0x45, 0xc429);
3842 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02003843 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08003844 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3845 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08003846 case 0x10ec0867:
3847 alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
3848 /* fallthru */
David Henningsson1f8b46c2015-05-12 14:38:15 +02003849 case 0x10ec0662:
3850 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3851 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3852 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003853 case 0x10ec0668:
3854 alc_write_coef_idx(codec, 0x11, 0x0001);
3855 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
Takashi Iwai54db6c32014-08-18 15:11:19 +02003856 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02003857 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3858 break;
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003859 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08003860 case 0x10ec0295:
Kailang Yangf6e94c22017-01-04 14:49:07 +08003861 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003862 alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
3863 snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3864 alc_process_coef_fw(codec, coef0225);
3865 snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3866 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003867 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01003868 codec_dbg(codec, "Headset jack set to mic-in mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02003869}
3870
3871static void alc_headset_mode_default(struct hda_codec *codec)
3872{
David Henningsson2ae95572016-02-25 09:37:05 +01003873 static struct coef_fw coef0225[] = {
3874 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
3875 {}
3876 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003877 static struct coef_fw coef0255[] = {
3878 WRITE_COEF(0x45, 0xc089),
3879 WRITE_COEF(0x45, 0xc489),
3880 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3881 WRITE_COEF(0x49, 0x0049),
3882 {}
3883 };
3884 static struct coef_fw coef0233[] = {
3885 WRITE_COEF(0x06, 0x2100),
3886 WRITE_COEF(0x32, 0x4ea3),
3887 {}
3888 };
Kailang Yangf3b70332015-04-08 15:01:17 +08003889 static struct coef_fw coef0288[] = {
3890 UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
3891 UPDATE_COEF(0x50, 0x2000, 0x2000),
3892 UPDATE_COEF(0x56, 0x0006, 0x0006),
3893 UPDATE_COEF(0x66, 0x0008, 0),
3894 UPDATE_COEF(0x67, 0x2000, 0),
3895 {}
3896 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003897 static struct coef_fw coef0292[] = {
3898 WRITE_COEF(0x76, 0x000e),
3899 WRITE_COEF(0x6c, 0x2400),
3900 WRITE_COEF(0x6b, 0xc429),
3901 WRITE_COEF(0x18, 0x7308),
3902 {}
3903 };
3904 static struct coef_fw coef0293[] = {
3905 UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3906 WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
3907 UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3908 {}
3909 };
3910 static struct coef_fw coef0688[] = {
3911 WRITE_COEF(0x11, 0x0041),
3912 WRITE_COEF(0x15, 0x0d40),
3913 WRITE_COEF(0xb7, 0x802b),
3914 {}
3915 };
3916
Takashi Iwai7639a062015-03-03 10:07:24 +01003917 switch (codec->core.vendor_id) {
David Henningsson2ae95572016-02-25 09:37:05 +01003918 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08003919 case 0x10ec0295:
Kailang Yangf6e94c22017-01-04 14:49:07 +08003920 case 0x10ec0299:
David Henningsson2ae95572016-02-25 09:37:05 +01003921 alc_process_coef_fw(codec, coef0225);
3922 break;
Kailang Yang61ae3fb2017-10-20 15:06:34 +08003923 case 0x10ec0236:
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003924 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08003925 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003926 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08003927 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08003928 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02003929 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003930 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02003931 break;
Kailang Yangf3b70332015-04-08 15:01:17 +08003932 case 0x10ec0286:
3933 case 0x10ec0288:
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08003934 case 0x10ec0298:
Kailang Yangf3b70332015-04-08 15:01:17 +08003935 alc_process_coef_fw(codec, coef0288);
3936 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003937 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003938 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02003939 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08003940 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003941 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08003942 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003943 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02003944 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02003945 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08003946 case 0x10ec0867:
3947 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
3948 break;
David Henningsson73bdd592013-04-15 15:44:14 +02003949 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01003950 codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02003951}
3952
3953/* Iphone type */
3954static void alc_headset_mode_ctia(struct hda_codec *codec)
3955{
Takashi Iwai54db6c32014-08-18 15:11:19 +02003956 static struct coef_fw coef0255[] = {
3957 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3958 WRITE_COEF(0x1b, 0x0c2b),
3959 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3960 {}
3961 };
Kailang Yange69e7e02016-05-30 15:58:28 +08003962 static struct coef_fw coef0256[] = {
3963 WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3964 WRITE_COEF(0x1b, 0x0c6b),
3965 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3966 {}
3967 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003968 static struct coef_fw coef0233[] = {
3969 WRITE_COEF(0x45, 0xd429),
3970 WRITE_COEF(0x1b, 0x0c2b),
3971 WRITE_COEF(0x32, 0x4ea3),
3972 {}
3973 };
Kailang Yangf3b70332015-04-08 15:01:17 +08003974 static struct coef_fw coef0288[] = {
3975 UPDATE_COEF(0x50, 0x2000, 0x2000),
3976 UPDATE_COEF(0x56, 0x0006, 0x0006),
3977 UPDATE_COEF(0x66, 0x0008, 0),
3978 UPDATE_COEF(0x67, 0x2000, 0),
3979 {}
3980 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02003981 static struct coef_fw coef0292[] = {
3982 WRITE_COEF(0x6b, 0xd429),
3983 WRITE_COEF(0x76, 0x0008),
3984 WRITE_COEF(0x18, 0x7388),
3985 {}
3986 };
3987 static struct coef_fw coef0293[] = {
3988 WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
3989 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3990 {}
3991 };
3992 static struct coef_fw coef0688[] = {
3993 WRITE_COEF(0x11, 0x0001),
3994 WRITE_COEF(0x15, 0x0d60),
3995 WRITE_COEF(0xc3, 0x0000),
3996 {}
3997 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08003998 static struct coef_fw coef0225[] = {
3999 UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
4000 UPDATE_COEF(0x49, 1<<8, 1<<8),
4001 UPDATE_COEF(0x4a, 7<<6, 7<<6),
4002 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4003 {}
4004 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004005
Takashi Iwai7639a062015-03-03 10:07:24 +01004006 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004007 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004008 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004009 break;
Kailang Yang61ae3fb2017-10-20 15:06:34 +08004010 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004011 case 0x10ec0256:
4012 alc_process_coef_fw(codec, coef0256);
4013 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004014 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004015 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004016 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004017 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004018 case 0x10ec0298:
4019 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);/* Headset output enable */
4020 /* ALC298 jack type setting is the same with ALC286/ALC288 */
Kailang Yangf3b70332015-04-08 15:01:17 +08004021 case 0x10ec0286:
4022 case 0x10ec0288:
4023 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
4024 msleep(300);
4025 alc_process_coef_fw(codec, coef0288);
4026 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004027 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004028 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004029 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004030 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004031 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004032 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004033 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004034 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004035 break;
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004036 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08004037 case 0x10ec0295:
Kailang Yangf6e94c22017-01-04 14:49:07 +08004038 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004039 alc_process_coef_fw(codec, coef0225);
4040 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004041 case 0x10ec0867:
4042 alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
4043 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004044 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004045 codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004046}
4047
4048/* Nokia type */
4049static void alc_headset_mode_omtp(struct hda_codec *codec)
4050{
Takashi Iwai54db6c32014-08-18 15:11:19 +02004051 static struct coef_fw coef0255[] = {
4052 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4053 WRITE_COEF(0x1b, 0x0c2b),
4054 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4055 {}
4056 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004057 static struct coef_fw coef0256[] = {
4058 WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
4059 WRITE_COEF(0x1b, 0x0c6b),
4060 WRITE_COEFEX(0x57, 0x03, 0x8ea6),
4061 {}
4062 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004063 static struct coef_fw coef0233[] = {
4064 WRITE_COEF(0x45, 0xe429),
4065 WRITE_COEF(0x1b, 0x0c2b),
4066 WRITE_COEF(0x32, 0x4ea3),
4067 {}
4068 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004069 static struct coef_fw coef0288[] = {
4070 UPDATE_COEF(0x50, 0x2000, 0x2000),
4071 UPDATE_COEF(0x56, 0x0006, 0x0006),
4072 UPDATE_COEF(0x66, 0x0008, 0),
4073 UPDATE_COEF(0x67, 0x2000, 0),
4074 {}
4075 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004076 static struct coef_fw coef0292[] = {
4077 WRITE_COEF(0x6b, 0xe429),
4078 WRITE_COEF(0x76, 0x0008),
4079 WRITE_COEF(0x18, 0x7388),
4080 {}
4081 };
4082 static struct coef_fw coef0293[] = {
4083 WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
4084 UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
4085 {}
4086 };
4087 static struct coef_fw coef0688[] = {
4088 WRITE_COEF(0x11, 0x0001),
4089 WRITE_COEF(0x15, 0x0d50),
4090 WRITE_COEF(0xc3, 0x0000),
4091 {}
4092 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004093 static struct coef_fw coef0225[] = {
4094 UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
4095 UPDATE_COEF(0x49, 1<<8, 1<<8),
4096 UPDATE_COEF(0x4a, 7<<6, 7<<6),
4097 UPDATE_COEF(0x4a, 3<<4, 3<<4),
4098 {}
4099 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004100
Takashi Iwai7639a062015-03-03 10:07:24 +01004101 switch (codec->core.vendor_id) {
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004102 case 0x10ec0255:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004103 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004104 break;
Kailang Yang61ae3fb2017-10-20 15:06:34 +08004105 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004106 case 0x10ec0256:
4107 alc_process_coef_fw(codec, coef0256);
4108 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004109 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004110 case 0x10ec0283:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004111 alc_process_coef_fw(codec, coef0233);
David Henningsson73bdd592013-04-15 15:44:14 +02004112 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004113 case 0x10ec0298:
4114 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
4115 /* ALC298 jack type setting is the same with ALC286/ALC288 */
Kailang Yangf3b70332015-04-08 15:01:17 +08004116 case 0x10ec0286:
4117 case 0x10ec0288:
4118 alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
4119 msleep(300);
4120 alc_process_coef_fw(codec, coef0288);
4121 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004122 case 0x10ec0292:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004123 alc_process_coef_fw(codec, coef0292);
David Henningsson73bdd592013-04-15 15:44:14 +02004124 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004125 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004126 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004127 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004128 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004129 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004130 break;
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004131 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08004132 case 0x10ec0295:
Kailang Yangf6e94c22017-01-04 14:49:07 +08004133 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004134 alc_process_coef_fw(codec, coef0225);
4135 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004136 }
Takashi Iwai4e76a882014-02-25 12:21:03 +01004137 codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
David Henningsson73bdd592013-04-15 15:44:14 +02004138}
4139
4140static void alc_determine_headset_type(struct hda_codec *codec)
4141{
4142 int val;
4143 bool is_ctia = false;
4144 struct alc_spec *spec = codec->spec;
Takashi Iwai54db6c32014-08-18 15:11:19 +02004145 static struct coef_fw coef0255[] = {
4146 WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
4147 WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
4148 conteol) */
4149 {}
4150 };
Kailang Yangf3b70332015-04-08 15:01:17 +08004151 static struct coef_fw coef0288[] = {
4152 UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
4153 {}
4154 };
Takashi Iwai54db6c32014-08-18 15:11:19 +02004155 static struct coef_fw coef0293[] = {
4156 UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
4157 WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
4158 {}
4159 };
4160 static struct coef_fw coef0688[] = {
4161 WRITE_COEF(0x11, 0x0001),
4162 WRITE_COEF(0xb7, 0x802b),
4163 WRITE_COEF(0x15, 0x0d60),
4164 WRITE_COEF(0xc3, 0x0c00),
4165 {}
4166 };
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004167 static struct coef_fw coef0225[] = {
4168 UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
4169 UPDATE_COEF(0x49, 1<<8, 1<<8),
4170 {}
4171 };
David Henningsson73bdd592013-04-15 15:44:14 +02004172
Takashi Iwai7639a062015-03-03 10:07:24 +01004173 switch (codec->core.vendor_id) {
Kailang Yang61ae3fb2017-10-20 15:06:34 +08004174 case 0x10ec0236:
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004175 case 0x10ec0255:
Kailang Yang7081adf2015-03-30 17:05:37 +08004176 case 0x10ec0256:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004177 alc_process_coef_fw(codec, coef0255);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004178 msleep(300);
4179 val = alc_read_coef_idx(codec, 0x46);
4180 is_ctia = (val & 0x0070) == 0x0070;
4181 break;
Kailang Yang13fd08a2014-05-21 16:49:48 +08004182 case 0x10ec0233:
David Henningsson73bdd592013-04-15 15:44:14 +02004183 case 0x10ec0283:
4184 alc_write_coef_idx(codec, 0x45, 0xd029);
4185 msleep(300);
4186 val = alc_read_coef_idx(codec, 0x46);
4187 is_ctia = (val & 0x0070) == 0x0070;
4188 break;
Kailang Yang1a5bc8d2015-05-12 17:11:10 +08004189 case 0x10ec0298:
4190 alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); /* Headset output enable */
4191 /* ALC298 check jack type is the same with ALC286/ALC288 */
Kailang Yangf3b70332015-04-08 15:01:17 +08004192 case 0x10ec0286:
4193 case 0x10ec0288:
4194 alc_process_coef_fw(codec, coef0288);
4195 msleep(350);
4196 val = alc_read_coef_idx(codec, 0x50);
4197 is_ctia = (val & 0x0070) == 0x0070;
4198 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004199 case 0x10ec0292:
4200 alc_write_coef_idx(codec, 0x6b, 0xd429);
4201 msleep(300);
4202 val = alc_read_coef_idx(codec, 0x6c);
4203 is_ctia = (val & 0x001c) == 0x001c;
4204 break;
Kailang Yanga22aa262014-04-23 17:34:28 +08004205 case 0x10ec0293:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004206 alc_process_coef_fw(codec, coef0293);
Kailang Yanga22aa262014-04-23 17:34:28 +08004207 msleep(300);
4208 val = alc_read_coef_idx(codec, 0x46);
4209 is_ctia = (val & 0x0070) == 0x0070;
4210 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004211 case 0x10ec0668:
Takashi Iwai54db6c32014-08-18 15:11:19 +02004212 alc_process_coef_fw(codec, coef0688);
David Henningsson73bdd592013-04-15 15:44:14 +02004213 msleep(300);
4214 val = alc_read_coef_idx(codec, 0xbe);
4215 is_ctia = (val & 0x1c02) == 0x1c02;
4216 break;
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004217 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08004218 case 0x10ec0295:
Kailang Yangf6e94c22017-01-04 14:49:07 +08004219 case 0x10ec0299:
Kailang Yang4cc9b9d2016-02-03 15:09:35 +08004220 alc_process_coef_fw(codec, coef0225);
4221 msleep(800);
4222 val = alc_read_coef_idx(codec, 0x46);
4223 is_ctia = (val & 0x00f0) == 0x00f0;
4224 break;
Kailang Yang78f4f7c2016-06-07 11:31:34 +08004225 case 0x10ec0867:
4226 is_ctia = true;
4227 break;
David Henningsson73bdd592013-04-15 15:44:14 +02004228 }
4229
Takashi Iwai4e76a882014-02-25 12:21:03 +01004230 codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
David Henningsson73bdd592013-04-15 15:44:14 +02004231 is_ctia ? "yes" : "no");
4232 spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
4233}
4234
4235static void alc_update_headset_mode(struct hda_codec *codec)
4236{
4237 struct alc_spec *spec = codec->spec;
4238
4239 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
4240 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
4241
4242 int new_headset_mode;
4243
4244 if (!snd_hda_jack_detect(codec, hp_pin))
4245 new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
4246 else if (mux_pin == spec->headset_mic_pin)
4247 new_headset_mode = ALC_HEADSET_MODE_HEADSET;
4248 else if (mux_pin == spec->headphone_mic_pin)
4249 new_headset_mode = ALC_HEADSET_MODE_MIC;
4250 else
4251 new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
4252
David Henningsson5959a6b2013-11-12 11:10:57 +01004253 if (new_headset_mode == spec->current_headset_mode) {
4254 snd_hda_gen_update_outputs(codec);
David Henningsson73bdd592013-04-15 15:44:14 +02004255 return;
David Henningsson5959a6b2013-11-12 11:10:57 +01004256 }
David Henningsson73bdd592013-04-15 15:44:14 +02004257
4258 switch (new_headset_mode) {
4259 case ALC_HEADSET_MODE_UNPLUGGED:
4260 alc_headset_mode_unplugged(codec);
4261 spec->gen.hp_jack_present = false;
4262 break;
4263 case ALC_HEADSET_MODE_HEADSET:
4264 if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4265 alc_determine_headset_type(codec);
4266 if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4267 alc_headset_mode_ctia(codec);
4268 else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4269 alc_headset_mode_omtp(codec);
4270 spec->gen.hp_jack_present = true;
4271 break;
4272 case ALC_HEADSET_MODE_MIC:
4273 alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4274 spec->gen.hp_jack_present = false;
4275 break;
4276 case ALC_HEADSET_MODE_HEADPHONE:
4277 alc_headset_mode_default(codec);
4278 spec->gen.hp_jack_present = true;
4279 break;
4280 }
4281 if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4282 snd_hda_set_pin_ctl_cache(codec, hp_pin,
4283 AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004284 if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
David Henningsson73bdd592013-04-15 15:44:14 +02004285 snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4286 PIN_VREFHIZ);
4287 }
4288 spec->current_headset_mode = new_headset_mode;
4289
4290 snd_hda_gen_update_outputs(codec);
4291}
4292
4293static void alc_update_headset_mode_hook(struct hda_codec *codec,
Takashi Iwai7fe30712014-01-30 17:59:02 +01004294 struct snd_kcontrol *kcontrol,
4295 struct snd_ctl_elem_value *ucontrol)
David Henningsson73bdd592013-04-15 15:44:14 +02004296{
4297 alc_update_headset_mode(codec);
4298}
4299
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004300static void alc_update_headset_jack_cb(struct hda_codec *codec,
4301 struct hda_jack_callback *jack)
David Henningsson73bdd592013-04-15 15:44:14 +02004302{
4303 struct alc_spec *spec = codec->spec;
David Henningsson5db4d342013-11-22 12:17:06 +01004304 spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
David Henningsson73bdd592013-04-15 15:44:14 +02004305 snd_hda_gen_hp_automute(codec, jack);
4306}
4307
4308static void alc_probe_headset_mode(struct hda_codec *codec)
4309{
4310 int i;
4311 struct alc_spec *spec = codec->spec;
4312 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4313
4314 /* Find mic pins */
4315 for (i = 0; i < cfg->num_inputs; i++) {
4316 if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4317 spec->headset_mic_pin = cfg->inputs[i].pin;
4318 if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4319 spec->headphone_mic_pin = cfg->inputs[i].pin;
4320 }
4321
4322 spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4323 spec->gen.automute_hook = alc_update_headset_mode;
4324 spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4325}
4326
4327static void alc_fixup_headset_mode(struct hda_codec *codec,
4328 const struct hda_fixup *fix, int action)
4329{
4330 struct alc_spec *spec = codec->spec;
4331
4332 switch (action) {
4333 case HDA_FIXUP_ACT_PRE_PROBE:
4334 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4335 break;
4336 case HDA_FIXUP_ACT_PROBE:
4337 alc_probe_headset_mode(codec);
4338 break;
4339 case HDA_FIXUP_ACT_INIT:
4340 spec->current_headset_mode = 0;
4341 alc_update_headset_mode(codec);
4342 break;
4343 }
4344}
4345
4346static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4347 const struct hda_fixup *fix, int action)
4348{
4349 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4350 struct alc_spec *spec = codec->spec;
4351 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4352 }
4353 else
4354 alc_fixup_headset_mode(codec, fix, action);
4355}
4356
Kailang Yang31278992014-03-03 15:27:22 +08004357static void alc255_set_default_jack_type(struct hda_codec *codec)
4358{
4359 /* Set to iphone type */
Kailang Yange69e7e02016-05-30 15:58:28 +08004360 static struct coef_fw alc255fw[] = {
Takashi Iwai54db6c32014-08-18 15:11:19 +02004361 WRITE_COEF(0x1b, 0x880b),
4362 WRITE_COEF(0x45, 0xd089),
4363 WRITE_COEF(0x1b, 0x080b),
4364 WRITE_COEF(0x46, 0x0004),
4365 WRITE_COEF(0x1b, 0x0c0b),
4366 {}
4367 };
Kailang Yange69e7e02016-05-30 15:58:28 +08004368 static struct coef_fw alc256fw[] = {
4369 WRITE_COEF(0x1b, 0x884b),
4370 WRITE_COEF(0x45, 0xd089),
4371 WRITE_COEF(0x1b, 0x084b),
4372 WRITE_COEF(0x46, 0x0004),
4373 WRITE_COEF(0x1b, 0x0c4b),
4374 {}
4375 };
4376 switch (codec->core.vendor_id) {
4377 case 0x10ec0255:
4378 alc_process_coef_fw(codec, alc255fw);
4379 break;
Kailang Yang61ae3fb2017-10-20 15:06:34 +08004380 case 0x10ec0236:
Kailang Yange69e7e02016-05-30 15:58:28 +08004381 case 0x10ec0256:
4382 alc_process_coef_fw(codec, alc256fw);
4383 break;
4384 }
Kailang Yang31278992014-03-03 15:27:22 +08004385 msleep(30);
4386}
4387
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004388static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4389 const struct hda_fixup *fix, int action)
4390{
4391 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Kailang Yang31278992014-03-03 15:27:22 +08004392 alc255_set_default_jack_type(codec);
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004393 }
4394 alc_fixup_headset_mode(codec, fix, action);
4395}
4396
Kailang Yang31278992014-03-03 15:27:22 +08004397static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4398 const struct hda_fixup *fix, int action)
4399{
4400 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4401 struct alc_spec *spec = codec->spec;
4402 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4403 alc255_set_default_jack_type(codec);
4404 }
4405 else
4406 alc_fixup_headset_mode(codec, fix, action);
4407}
4408
Kailang Yange1e62b92015-04-08 16:01:22 +08004409static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4410 struct hda_jack_callback *jack)
4411{
4412 struct alc_spec *spec = codec->spec;
4413 int present;
4414
4415 alc_update_headset_jack_cb(codec, jack);
4416 /* Headset Mic enable or disable, only for Dell Dino */
4417 present = spec->gen.hp_jack_present ? 0x40 : 0;
4418 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4419 present);
4420}
4421
4422static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4423 const struct hda_fixup *fix, int action)
4424{
4425 alc_fixup_headset_mode(codec, fix, action);
4426 if (action == HDA_FIXUP_ACT_PROBE) {
4427 struct alc_spec *spec = codec->spec;
4428 spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4429 }
4430}
4431
Hui Wang493a52a2014-01-14 14:07:36 +08004432static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4433 const struct hda_fixup *fix, int action)
4434{
4435 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4436 struct alc_spec *spec = codec->spec;
4437 spec->gen.auto_mute_via_amp = 1;
4438 }
4439}
4440
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004441static void alc_no_shutup(struct hda_codec *codec)
4442{
4443}
4444
4445static void alc_fixup_no_shutup(struct hda_codec *codec,
4446 const struct hda_fixup *fix, int action)
4447{
Gabriele Mazzottad47162b2016-12-24 19:50:00 +01004448 if (action == HDA_FIXUP_ACT_PROBE) {
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004449 struct alc_spec *spec = codec->spec;
4450 spec->shutup = alc_no_shutup;
4451 }
4452}
4453
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02004454static void alc_fixup_disable_aamix(struct hda_codec *codec,
4455 const struct hda_fixup *fix, int action)
4456{
4457 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4458 struct alc_spec *spec = codec->spec;
4459 /* Disable AA-loopback as it causes white noise */
4460 spec->gen.mixer_nid = 0;
4461 }
4462}
4463
Takashi Iwai7f57d802015-09-24 17:36:51 +02004464/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4465static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4466 const struct hda_fixup *fix, int action)
4467{
4468 static const struct hda_pintbl pincfgs[] = {
4469 { 0x16, 0x21211010 }, /* dock headphone */
4470 { 0x19, 0x21a11010 }, /* dock mic */
4471 { }
4472 };
4473 struct alc_spec *spec = codec->spec;
4474
4475 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai70a09762015-12-15 14:59:58 +01004476 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
Takashi Iwai7f57d802015-09-24 17:36:51 +02004477 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4478 codec->power_save_node = 0; /* avoid click noises */
4479 snd_hda_apply_pincfgs(codec, pincfgs);
4480 }
4481}
4482
Kailang Yangd8fff0e72018-02-02 15:26:46 +08004483static void alc_fixup_tpt470_dock(struct hda_codec *codec,
4484 const struct hda_fixup *fix, int action)
4485{
4486 static const struct hda_pintbl pincfgs[] = {
4487 { 0x17, 0x21211010 }, /* dock headphone */
4488 { 0x19, 0x21a11010 }, /* dock mic */
4489 { }
4490 };
Takashi Iwai5e513182018-12-03 10:44:15 +01004491 /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
4492 * the speaker output becomes too low by some reason on Thinkpads with
4493 * ALC298 codec
4494 */
4495 static hda_nid_t preferred_pairs[] = {
4496 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
4497 0
4498 };
Kailang Yangd8fff0e72018-02-02 15:26:46 +08004499 struct alc_spec *spec = codec->spec;
4500
4501 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai5e513182018-12-03 10:44:15 +01004502 spec->gen.preferred_dacs = preferred_pairs;
Kailang Yangd8fff0e72018-02-02 15:26:46 +08004503 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
Takashi Iwai61963d32018-02-26 15:36:38 +01004504 snd_hda_apply_pincfgs(codec, pincfgs);
4505 } else if (action == HDA_FIXUP_ACT_INIT) {
Kailang Yangd8fff0e72018-02-02 15:26:46 +08004506 /* Enable DOCK device */
4507 snd_hda_codec_write(codec, 0x17, 0,
4508 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
4509 /* Enable DOCK device */
4510 snd_hda_codec_write(codec, 0x19, 0,
4511 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0);
Kailang Yangd8fff0e72018-02-02 15:26:46 +08004512 }
4513}
4514
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02004515static void alc_shutup_dell_xps13(struct hda_codec *codec)
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02004516{
4517 struct alc_spec *spec = codec->spec;
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02004518 int hp_pin = spec->gen.autocfg.hp_pins[0];
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02004519
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02004520 /* Prevent pop noises when headphones are plugged in */
4521 snd_hda_codec_write(codec, hp_pin, 0,
4522 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4523 msleep(20);
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02004524}
4525
4526static void alc_fixup_dell_xps13(struct hda_codec *codec,
4527 const struct hda_fixup *fix, int action)
4528{
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02004529 struct alc_spec *spec = codec->spec;
4530 struct hda_input_mux *imux = &spec->gen.input_mux;
4531 int i;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02004532
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02004533 switch (action) {
4534 case HDA_FIXUP_ACT_PRE_PROBE:
4535 /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
4536 * it causes a click noise at start up
4537 */
4538 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4539 break;
4540 case HDA_FIXUP_ACT_PROBE:
Gabriele Mazzotta9476d3692015-04-19 19:00:40 +02004541 spec->shutup = alc_shutup_dell_xps13;
Gabriele Mazzottaf38663a2014-08-08 19:34:40 +02004542
4543 /* Make the internal mic the default input source. */
4544 for (i = 0; i < imux->num_items; i++) {
4545 if (spec->gen.imux_pins[i] == 0x12) {
4546 spec->gen.cur_mux[0] = i;
4547 break;
4548 }
4549 }
Takashi Iwai3e1b0c42015-04-27 10:43:22 +02004550 break;
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02004551 }
4552}
4553
David Henningsson1f8b46c2015-05-12 14:38:15 +02004554static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
4555 const struct hda_fixup *fix, int action)
4556{
4557 struct alc_spec *spec = codec->spec;
4558
4559 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4560 spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4561 spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
David Henningssonb40eda62015-05-28 09:40:23 +02004562
4563 /* Disable boost for mic-in permanently. (This code is only called
4564 from quirks that guarantee that the headphone is at NID 0x1b.) */
4565 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
4566 snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
David Henningsson1f8b46c2015-05-12 14:38:15 +02004567 } else
4568 alc_fixup_headset_mode(codec, fix, action);
4569}
4570
David Henningsson73bdd592013-04-15 15:44:14 +02004571static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
4572 const struct hda_fixup *fix, int action)
4573{
4574 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
David Henningsson73bdd592013-04-15 15:44:14 +02004575 alc_write_coef_idx(codec, 0xc4, 0x8000);
Takashi Iwai98b24882014-08-18 13:47:50 +02004576 alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
David Henningsson73bdd592013-04-15 15:44:14 +02004577 snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
4578 }
4579 alc_fixup_headset_mode(codec, fix, action);
4580}
4581
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08004582/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
4583static int find_ext_mic_pin(struct hda_codec *codec)
4584{
4585 struct alc_spec *spec = codec->spec;
4586 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4587 hda_nid_t nid;
4588 unsigned int defcfg;
4589 int i;
4590
4591 for (i = 0; i < cfg->num_inputs; i++) {
4592 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4593 continue;
4594 nid = cfg->inputs[i].pin;
4595 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4596 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
4597 continue;
4598 return nid;
4599 }
4600
4601 return 0;
4602}
4603
Dylan Reid08a978d2012-11-18 22:56:40 -08004604static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01004605 const struct hda_fixup *fix,
Dylan Reid08a978d2012-11-18 22:56:40 -08004606 int action)
4607{
4608 struct alc_spec *spec = codec->spec;
4609
Takashi Iwai0db75792013-01-23 13:57:20 +01004610 if (action == HDA_FIXUP_ACT_PROBE) {
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08004611 int mic_pin = find_ext_mic_pin(codec);
4612 int hp_pin = spec->gen.autocfg.hp_pins[0];
4613
4614 if (snd_BUG_ON(!mic_pin || !hp_pin))
Takashi Iwai0db75792013-01-23 13:57:20 +01004615 return;
Chih-Chung Changbde7bc62013-08-05 16:38:42 +08004616 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
Takashi Iwai0db75792013-01-23 13:57:20 +01004617 }
Dylan Reid08a978d2012-11-18 22:56:40 -08004618}
David Henningsson693b6132012-06-22 19:12:10 +02004619
David Henningsson3e0d6112013-04-22 14:30:14 +02004620static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4621 const struct hda_fixup *fix,
4622 int action)
4623{
4624 struct alc_spec *spec = codec->spec;
4625 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4626 int i;
4627
4628 /* The mic boosts on level 2 and 3 are too noisy
4629 on the internal mic input.
4630 Therefore limit the boost to 0 or 1. */
4631
4632 if (action != HDA_FIXUP_ACT_PROBE)
4633 return;
4634
4635 for (i = 0; i < cfg->num_inputs; i++) {
4636 hda_nid_t nid = cfg->inputs[i].pin;
4637 unsigned int defcfg;
4638 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4639 continue;
4640 defcfg = snd_hda_codec_get_pincfg(codec, nid);
4641 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
4642 continue;
4643
4644 snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
4645 (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
4646 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4647 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
4648 (0 << AC_AMPCAP_MUTE_SHIFT));
4649 }
4650}
4651
Kailang Yangcd217a62013-08-22 10:15:24 +02004652static void alc283_hp_automute_hook(struct hda_codec *codec,
Takashi Iwai1a4f69d2014-09-11 15:22:46 +02004653 struct hda_jack_callback *jack)
Kailang Yangcd217a62013-08-22 10:15:24 +02004654{
4655 struct alc_spec *spec = codec->spec;
4656 int vref;
4657
4658 msleep(200);
4659 snd_hda_gen_hp_automute(codec, jack);
4660
4661 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4662
4663 msleep(600);
4664 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4665 vref);
4666}
4667
Kailang Yangcd217a62013-08-22 10:15:24 +02004668static void alc283_fixup_chromebook(struct hda_codec *codec,
4669 const struct hda_fixup *fix, int action)
4670{
4671 struct alc_spec *spec = codec->spec;
Kailang Yangcd217a62013-08-22 10:15:24 +02004672
4673 switch (action) {
4674 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yang0202e992013-12-02 15:20:15 +08004675 snd_hda_override_wcaps(codec, 0x03, 0);
Takashi Iwaid2e92702013-10-30 07:50:53 +01004676 /* Disable AA-loopback as it causes white noise */
4677 spec->gen.mixer_nid = 0;
Kailang Yang38070212013-11-01 15:57:35 +08004678 break;
4679 case HDA_FIXUP_ACT_INIT:
Kailang Yangde9481c2014-04-07 16:41:52 +08004680 /* MIC2-VREF control */
4681 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02004682 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yang0202e992013-12-02 15:20:15 +08004683 /* Enable Line1 input control by verb */
Takashi Iwai98b24882014-08-18 13:47:50 +02004684 alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
Kailang Yang0202e992013-12-02 15:20:15 +08004685 break;
4686 }
4687}
4688
4689static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4690 const struct hda_fixup *fix, int action)
4691{
4692 struct alc_spec *spec = codec->spec;
Kailang Yang0202e992013-12-02 15:20:15 +08004693
4694 switch (action) {
4695 case HDA_FIXUP_ACT_PRE_PROBE:
Kailang Yangcd217a62013-08-22 10:15:24 +02004696 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
4697 break;
4698 case HDA_FIXUP_ACT_INIT:
4699 /* MIC2-VREF control */
4700 /* Set to manual mode */
Takashi Iwai98b24882014-08-18 13:47:50 +02004701 alc_update_coef_idx(codec, 0x06, 0x000c, 0);
Kailang Yangcd217a62013-08-22 10:15:24 +02004702 break;
4703 }
4704}
4705
Takashi Iwai7bba2152013-09-06 15:45:38 +02004706/* mute tablet speaker pin (0x14) via dock plugging in addition */
4707static void asus_tx300_automute(struct hda_codec *codec)
4708{
4709 struct alc_spec *spec = codec->spec;
4710 snd_hda_gen_update_outputs(codec);
4711 if (snd_hda_jack_detect(codec, 0x1b))
4712 spec->gen.mute_bits |= (1ULL << 0x14);
4713}
4714
4715static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4716 const struct hda_fixup *fix, int action)
4717{
4718 struct alc_spec *spec = codec->spec;
4719 /* TX300 needs to set up GPIO2 for the speaker amp */
4720 static const struct hda_verb gpio2_verbs[] = {
4721 { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4722 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4723 { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4724 {}
4725 };
4726 static const struct hda_pintbl dock_pins[] = {
4727 { 0x1b, 0x21114000 }, /* dock speaker pin */
4728 {}
4729 };
4730 struct snd_kcontrol *kctl;
4731
4732 switch (action) {
4733 case HDA_FIXUP_ACT_PRE_PROBE:
4734 snd_hda_add_verbs(codec, gpio2_verbs);
4735 snd_hda_apply_pincfgs(codec, dock_pins);
4736 spec->gen.auto_mute_via_amp = 1;
4737 spec->gen.automute_hook = asus_tx300_automute;
4738 snd_hda_jack_detect_enable_callback(codec, 0x1b,
Takashi Iwai7bba2152013-09-06 15:45:38 +02004739 snd_hda_gen_hp_automute);
4740 break;
4741 case HDA_FIXUP_ACT_BUILD:
4742 /* this is a bit tricky; give more sane names for the main
4743 * (tablet) speaker and the dock speaker, respectively
4744 */
4745 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4746 if (kctl)
4747 strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4748 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4749 if (kctl)
4750 strcpy(kctl->id.name, "Speaker Playback Switch");
4751 break;
4752 }
4753}
4754
David Henningsson338cae52013-10-07 10:39:59 +02004755static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4756 const struct hda_fixup *fix, int action)
4757{
David Henningsson0f4881d2013-12-20 16:08:13 +01004758 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4759 /* DAC node 0x03 is giving mono output. We therefore want to
4760 make sure 0x14 (front speaker) and 0x15 (headphones) use the
4761 stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4762 hda_nid_t conn1[2] = { 0x0c };
4763 snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4764 snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4765 }
David Henningsson338cae52013-10-07 10:39:59 +02004766}
4767
Hui Wangdd9aa332016-08-01 10:20:32 +08004768static void alc298_fixup_speaker_volume(struct hda_codec *codec,
4769 const struct hda_fixup *fix, int action)
4770{
4771 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4772 /* The speaker is routed to the Node 0x06 by a mistake, as a result
4773 we can't adjust the speaker's volume since this node does not has
4774 Amp-out capability. we change the speaker's route to:
4775 Node 0x02 (Audio Output) -> Node 0x0c (Audio Mixer) -> Node 0x17 (
4776 Pin Complex), since Node 0x02 has Amp-out caps, we can adjust
4777 speaker's volume now. */
4778
4779 hda_nid_t conn1[1] = { 0x0c };
4780 snd_hda_override_conn_list(codec, 0x17, 1, conn1);
4781 }
4782}
4783
Takashi Iwaib992e8f2018-03-06 12:14:17 +01004784/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
4785static void alc295_fixup_disable_dac3(struct hda_codec *codec,
4786 const struct hda_fixup *fix, int action)
4787{
4788 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4789 hda_nid_t conn[2] = { 0x02, 0x03 };
4790 snd_hda_override_conn_list(codec, 0x17, 2, conn);
4791 }
4792}
4793
Keith Packard98973f22015-07-15 12:14:39 -07004794/* Hook to update amp GPIO4 for automute */
4795static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
4796 struct hda_jack_callback *jack)
4797{
4798 struct alc_spec *spec = codec->spec;
4799
4800 snd_hda_gen_hp_automute(codec, jack);
4801 /* mute_led_polarity is set to 0, so we pass inverted value here */
4802 alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
4803}
4804
4805/* Manage GPIOs for HP EliteBook Folio 9480m.
4806 *
4807 * GPIO4 is the headphone amplifier power control
4808 * GPIO3 is the audio output mute indicator LED
4809 */
4810
4811static void alc280_fixup_hp_9480m(struct hda_codec *codec,
4812 const struct hda_fixup *fix,
4813 int action)
4814{
4815 struct alc_spec *spec = codec->spec;
4816 static const struct hda_verb gpio_init[] = {
4817 { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
4818 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
4819 {}
4820 };
4821
4822 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4823 /* Set the hooks to turn the headphone amp on/off
4824 * as needed
4825 */
4826 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4827 spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
4828
4829 /* The GPIOs are currently off */
4830 spec->gpio_led = 0;
4831
4832 /* GPIO3 is connected to the output mute LED,
4833 * high is on, low is off
4834 */
4835 spec->mute_led_polarity = 0;
4836 spec->gpio_mute_led_mask = 0x08;
4837
4838 /* Initialize GPIO configuration */
4839 snd_hda_add_verbs(codec, gpio_init);
4840 }
4841}
4842
Kailang Yangdfce2062019-01-09 17:05:24 +08004843static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
4844 const struct hda_fixup *fix, int action)
4845{
4846 if (action == HDA_FIXUP_ACT_PRE_PROBE)
4847 snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4848}
4849
Takashi Iwaib317b032014-01-08 11:44:21 +01004850/* for hda_fixup_thinkpad_acpi() */
4851#include "thinkpad_helper.c"
David Henningssonb67ae3f2013-11-05 13:11:37 +01004852
Takashi Iwai6008de22018-06-13 12:43:10 +02004853static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
4854 const struct hda_fixup *fix, int action)
4855{
4856 alc_fixup_no_shutup(codec, fix, action); /* reduce click noise */
4857 hda_fixup_thinkpad_acpi(codec, fix, action);
4858}
4859
Hui Wang00ef9942014-07-31 11:52:38 +08004860/* for dell wmi mic mute led */
4861#include "dell_wmi_helper.c"
4862
Takashi Iwai1d045db2011-07-07 18:23:21 +02004863enum {
4864 ALC269_FIXUP_SONY_VAIO,
4865 ALC275_FIXUP_SONY_VAIO_GPIO2,
4866 ALC269_FIXUP_DELL_M101Z,
4867 ALC269_FIXUP_SKU_IGNORE,
4868 ALC269_FIXUP_ASUS_G73JW,
4869 ALC269_FIXUP_LENOVO_EAPD,
4870 ALC275_FIXUP_SONY_HWEQ,
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02004871 ALC275_FIXUP_SONY_DISABLE_AAMIX,
Takashi Iwai1d045db2011-07-07 18:23:21 +02004872 ALC271_FIXUP_DMIC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02004873 ALC269_FIXUP_PCM_44K,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02004874 ALC269_FIXUP_STEREO_DMIC,
David Henningsson7c478f02013-10-11 10:18:46 +02004875 ALC269_FIXUP_HEADSET_MIC,
Takashi Iwai24519912011-08-16 15:08:49 +02004876 ALC269_FIXUP_QUANTA_MUTE,
4877 ALC269_FIXUP_LIFEBOOK,
David Henningsson2041d562014-06-13 11:15:44 +02004878 ALC269_FIXUP_LIFEBOOK_EXTMIC,
Takashi Iwaicc7016a2015-04-08 20:47:55 +02004879 ALC269_FIXUP_LIFEBOOK_HP_PIN,
Takashi Iwai4df3fd12015-06-29 08:38:02 +02004880 ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
Jan-Marek Glogowskibb1a4222018-02-14 11:29:15 +01004881 ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC,
Takashi Iwaia4297b52011-08-23 18:40:12 +02004882 ALC269_FIXUP_AMIC,
4883 ALC269_FIXUP_DMIC,
4884 ALC269VB_FIXUP_AMIC,
4885 ALC269VB_FIXUP_DMIC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004886 ALC269_FIXUP_HP_MUTE_LED,
David Henningssond06ac142013-02-18 11:41:55 +01004887 ALC269_FIXUP_HP_MUTE_LED_MIC1,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01004888 ALC269_FIXUP_HP_MUTE_LED_MIC2,
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01004889 ALC269_FIXUP_HP_GPIO_LED,
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08004890 ALC269_FIXUP_HP_GPIO_MIC1_LED,
4891 ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningsson693b6132012-06-22 19:12:10 +02004892 ALC269_FIXUP_INV_DMIC,
David Henningsson108cc102012-07-20 10:37:25 +02004893 ALC269_FIXUP_LENOVO_DOCK,
Takashi Iwai9b745ab2014-03-07 08:37:19 +01004894 ALC269_FIXUP_NO_SHUTUP,
David Henningsson88cfcf82013-10-11 10:18:45 +02004895 ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
David Henningsson108cc102012-07-20 10:37:25 +02004896 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
David Henningsson73bdd592013-04-15 15:44:14 +02004897 ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4898 ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningsson338cae52013-10-07 10:39:59 +02004899 ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02004900 ALC269_FIXUP_HEADSET_MODE,
4901 ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
Takashi Iwai78197172015-06-27 10:21:13 +02004902 ALC269_FIXUP_ASPIRE_HEADSET_MIC,
David Henningssond240d1d2013-04-15 12:50:02 +02004903 ALC269_FIXUP_ASUS_X101_FUNC,
4904 ALC269_FIXUP_ASUS_X101_VERB,
4905 ALC269_FIXUP_ASUS_X101,
Dylan Reid08a978d2012-11-18 22:56:40 -08004906 ALC271_FIXUP_AMIC_MIC2,
4907 ALC271_FIXUP_HP_GATE_MIC_JACK,
Oleksij Rempelb1e89722013-12-04 20:50:53 +01004908 ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
Dylan Reid42397002013-04-05 14:58:22 -07004909 ALC269_FIXUP_ACER_AC700,
David Henningsson3e0d6112013-04-22 14:30:14 +02004910 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
Oleksij Rempel2cede302013-11-27 17:12:03 +01004911 ALC269VB_FIXUP_ASUS_ZENBOOK,
Takashi Iwai23870832013-11-29 14:13:12 +01004912 ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
David Henningsson8e35cd42013-11-06 11:20:01 +01004913 ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
Anisse Astier02b504d2013-06-03 11:53:10 +02004914 ALC269VB_FIXUP_ORDISSIMO_EVE2,
Kailang Yangcd217a62013-08-22 10:15:24 +02004915 ALC283_FIXUP_CHROME_BOOK,
Kailang Yang0202e992013-12-02 15:20:15 +08004916 ALC283_FIXUP_SENSE_COMBO_JACK,
Takashi Iwai7bba2152013-09-06 15:45:38 +02004917 ALC282_FIXUP_ASUS_TX300,
Kailang Yang1bb3e062013-09-27 13:10:25 +02004918 ALC283_FIXUP_INT_MIC,
David Henningsson338cae52013-10-07 10:39:59 +02004919 ALC290_FIXUP_MONO_SPEAKERS,
David Henningsson0f4881d2013-12-20 16:08:13 +01004920 ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4921 ALC290_FIXUP_SUBWOOFER,
4922 ALC290_FIXUP_SUBWOOFER_HSJACK,
David Henningssonb67ae3f2013-11-05 13:11:37 +01004923 ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson56f27012016-01-11 09:33:14 +01004924 ALC269_FIXUP_DMIC_THINKPAD_ACPI,
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004925 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang31278992014-03-03 15:27:22 +08004926 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Kailang Yang9a22a8f2013-11-08 15:54:49 +08004927 ALC255_FIXUP_HEADSET_MODE,
Kailang Yang31278992014-03-03 15:27:22 +08004928 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
Kailang Yanga22aa262014-04-23 17:34:28 +08004929 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwai1c37c222014-05-06 17:34:42 +02004930 ALC292_FIXUP_TPT440_DOCK,
Takashi Iwai9a811232015-12-09 15:17:43 +01004931 ALC292_FIXUP_TPT440,
Anisse Astierabaa22742016-08-24 09:14:13 +02004932 ALC283_FIXUP_HEADSET_MIC,
Hui Wang00ef9942014-07-31 11:52:38 +08004933 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
Takashi Iwai1a22e772014-08-27 08:19:05 +02004934 ALC282_FIXUP_ASPIRE_V5_PINS,
David Henningsson7a5255f2014-10-30 08:26:01 +01004935 ALC280_FIXUP_HP_GPIO4,
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08004936 ALC286_FIXUP_HP_GPIO_LED,
David Henningsson33f4acd2015-01-07 15:50:13 +01004937 ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
TienFu Chenb4b33f92015-01-20 15:06:21 +01004938 ALC280_FIXUP_HP_DOCK_PINS,
Jaroslav Kysela52c33232017-03-09 13:29:13 +01004939 ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED,
Keith Packard98973f22015-07-15 12:14:39 -07004940 ALC280_FIXUP_HP_9480M,
Kailang Yange1e62b92015-04-08 16:01:22 +08004941 ALC288_FIXUP_DELL_HEADSET_MODE,
4942 ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4943 ALC288_FIXUP_DELL_XPS_13_GPIO6,
Hui Wang831bfdf2015-06-26 12:35:17 +08004944 ALC288_FIXUP_DELL_XPS_13,
4945 ALC288_FIXUP_DISABLE_AAMIX,
Takashi Iwai8b99aba2015-06-15 11:59:32 +02004946 ALC292_FIXUP_DELL_E7X,
4947 ALC292_FIXUP_DISABLE_AAMIX,
David Henningssonc04017e2015-12-15 14:44:03 +01004948 ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK,
Kailang Yang977e6272015-05-18 15:31:20 +08004949 ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang8aabccd2017-03-31 10:31:40 +08004950 ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Kailang Yang6ed11312015-10-26 15:37:39 +08004951 ALC275_FIXUP_DELL_XPS,
Hui Wang8c697292015-11-24 11:08:18 +08004952 ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
Hui Wang23adc192015-12-08 12:27:18 +08004953 ALC293_FIXUP_LENOVO_SPK_NOISE,
Kailang3694cb22015-12-28 11:35:24 +08004954 ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08004955 ALC255_FIXUP_DELL_SPK_NOISE,
Kailang Yangdfce2062019-01-09 17:05:24 +08004956 ALC225_FIXUP_DISABLE_MIC_VREF,
David Henningsson2ae95572016-02-25 09:37:05 +01004957 ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Takashi Iwaib992e8f2018-03-06 12:14:17 +01004958 ALC295_FIXUP_DISABLE_DAC3,
Takashi Iwaif8839822016-02-25 14:31:59 +01004959 ALC280_FIXUP_HP_HEADSET_MIC,
Hui Wange549d192016-04-01 11:00:15 +08004960 ALC221_FIXUP_HP_FRONT_MIC,
Sven Eckelmannc636b952016-04-11 16:55:26 +02004961 ALC292_FIXUP_TPT460,
Hui Wangdd9aa332016-08-01 10:20:32 +08004962 ALC298_FIXUP_SPK_VOLUME,
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08004963 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
Kailang Yangd8fff0e72018-02-02 15:26:46 +08004964 ALC298_FIXUP_TPT470_DOCK,
Takashi Iwai1d045db2011-07-07 18:23:21 +02004965};
4966
Takashi Iwai1727a772013-01-10 09:52:52 +01004967static const struct hda_fixup alc269_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02004968 [ALC269_FIXUP_SONY_VAIO] = {
Takashi Iwaifd108212013-01-10 10:18:14 +01004969 .type = HDA_FIXUP_PINCTLS,
4970 .v.pins = (const struct hda_pintbl[]) {
4971 {0x19, PIN_VREFGRD},
Takashi Iwai1d045db2011-07-07 18:23:21 +02004972 {}
4973 }
4974 },
4975 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01004976 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02004977 .v.verbs = (const struct hda_verb[]) {
4978 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4979 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4980 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4981 { }
4982 },
4983 .chained = true,
4984 .chain_id = ALC269_FIXUP_SONY_VAIO
4985 },
4986 [ALC269_FIXUP_DELL_M101Z] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01004987 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02004988 .v.verbs = (const struct hda_verb[]) {
4989 /* Enables internal speaker */
4990 {0x20, AC_VERB_SET_COEF_INDEX, 13},
4991 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4992 {}
4993 }
4994 },
4995 [ALC269_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01004996 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02004997 .v.func = alc_fixup_sku_ignore,
Takashi Iwai1d045db2011-07-07 18:23:21 +02004998 },
4999 [ALC269_FIXUP_ASUS_G73JW] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005000 .type = HDA_FIXUP_PINS,
5001 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02005002 { 0x17, 0x99130111 }, /* subwoofer */
5003 { }
5004 }
5005 },
5006 [ALC269_FIXUP_LENOVO_EAPD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005007 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005008 .v.verbs = (const struct hda_verb[]) {
5009 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5010 {}
5011 }
5012 },
5013 [ALC275_FIXUP_SONY_HWEQ] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005014 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005015 .v.func = alc269_fixup_hweq,
5016 .chained = true,
5017 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5018 },
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005019 [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
5020 .type = HDA_FIXUP_FUNC,
5021 .v.func = alc_fixup_disable_aamix,
5022 .chained = true,
5023 .chain_id = ALC269_FIXUP_SONY_VAIO
5024 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005025 [ALC271_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005026 .type = HDA_FIXUP_FUNC,
Takashi Iwai1d045db2011-07-07 18:23:21 +02005027 .v.func = alc271_fixup_dmic,
5028 },
Takashi Iwai017f2a12011-07-09 14:42:25 +02005029 [ALC269_FIXUP_PCM_44K] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005030 .type = HDA_FIXUP_FUNC,
Takashi Iwai017f2a12011-07-09 14:42:25 +02005031 .v.func = alc269_fixup_pcm_44k,
David Henningsson012e7eb2012-08-08 08:43:37 +02005032 .chained = true,
5033 .chain_id = ALC269_FIXUP_QUANTA_MUTE
Takashi Iwai017f2a12011-07-09 14:42:25 +02005034 },
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005035 [ALC269_FIXUP_STEREO_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005036 .type = HDA_FIXUP_FUNC,
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005037 .v.func = alc269_fixup_stereo_dmic,
5038 },
David Henningsson7c478f02013-10-11 10:18:46 +02005039 [ALC269_FIXUP_HEADSET_MIC] = {
5040 .type = HDA_FIXUP_FUNC,
5041 .v.func = alc269_fixup_headset_mic,
5042 },
Takashi Iwai24519912011-08-16 15:08:49 +02005043 [ALC269_FIXUP_QUANTA_MUTE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005044 .type = HDA_FIXUP_FUNC,
Takashi Iwai24519912011-08-16 15:08:49 +02005045 .v.func = alc269_fixup_quanta_mute,
5046 },
5047 [ALC269_FIXUP_LIFEBOOK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005048 .type = HDA_FIXUP_PINS,
5049 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai24519912011-08-16 15:08:49 +02005050 { 0x1a, 0x2101103f }, /* dock line-out */
5051 { 0x1b, 0x23a11040 }, /* dock mic-in */
5052 { }
5053 },
5054 .chained = true,
5055 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5056 },
David Henningsson2041d562014-06-13 11:15:44 +02005057 [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
5058 .type = HDA_FIXUP_PINS,
5059 .v.pins = (const struct hda_pintbl[]) {
5060 { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
5061 { }
5062 },
5063 },
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005064 [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
5065 .type = HDA_FIXUP_PINS,
5066 .v.pins = (const struct hda_pintbl[]) {
5067 { 0x21, 0x0221102f }, /* HP out */
5068 { }
5069 },
5070 },
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005071 [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
5072 .type = HDA_FIXUP_FUNC,
5073 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
5074 },
Jan-Marek Glogowskibb1a4222018-02-14 11:29:15 +01005075 [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = {
5076 .type = HDA_FIXUP_FUNC,
5077 .v.func = alc269_fixup_pincfg_U7x7_headset_mic,
5078 },
Takashi Iwaia4297b52011-08-23 18:40:12 +02005079 [ALC269_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005080 .type = HDA_FIXUP_PINS,
5081 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005082 { 0x14, 0x99130110 }, /* speaker */
5083 { 0x15, 0x0121401f }, /* HP out */
5084 { 0x18, 0x01a19c20 }, /* mic */
5085 { 0x19, 0x99a3092f }, /* int-mic */
5086 { }
5087 },
5088 },
5089 [ALC269_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005090 .type = HDA_FIXUP_PINS,
5091 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005092 { 0x12, 0x99a3092f }, /* int-mic */
5093 { 0x14, 0x99130110 }, /* speaker */
5094 { 0x15, 0x0121401f }, /* HP out */
5095 { 0x18, 0x01a19c20 }, /* mic */
5096 { }
5097 },
5098 },
5099 [ALC269VB_FIXUP_AMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005100 .type = HDA_FIXUP_PINS,
5101 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005102 { 0x14, 0x99130110 }, /* speaker */
5103 { 0x18, 0x01a19c20 }, /* mic */
5104 { 0x19, 0x99a3092f }, /* int-mic */
5105 { 0x21, 0x0121401f }, /* HP out */
5106 { }
5107 },
5108 },
David Henningsson2267ea92012-01-03 08:45:56 +01005109 [ALC269VB_FIXUP_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005110 .type = HDA_FIXUP_PINS,
5111 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005112 { 0x12, 0x99a3092f }, /* int-mic */
5113 { 0x14, 0x99130110 }, /* speaker */
5114 { 0x18, 0x01a19c20 }, /* mic */
5115 { 0x21, 0x0121401f }, /* HP out */
5116 { }
5117 },
5118 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005119 [ALC269_FIXUP_HP_MUTE_LED] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005120 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005121 .v.func = alc269_fixup_hp_mute_led,
David Henningsson6d3cd5d2013-01-07 12:03:47 +01005122 },
David Henningssond06ac142013-02-18 11:41:55 +01005123 [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
5124 .type = HDA_FIXUP_FUNC,
5125 .v.func = alc269_fixup_hp_mute_led_mic1,
5126 },
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005127 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005128 .type = HDA_FIXUP_FUNC,
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005129 .v.func = alc269_fixup_hp_mute_led_mic2,
Takashi Iwai420b0fe2012-03-12 12:35:27 +01005130 },
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005131 [ALC269_FIXUP_HP_GPIO_LED] = {
5132 .type = HDA_FIXUP_FUNC,
5133 .v.func = alc269_fixup_hp_gpio_led,
5134 },
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005135 [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
5136 .type = HDA_FIXUP_FUNC,
5137 .v.func = alc269_fixup_hp_gpio_mic1_led,
5138 },
5139 [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
5140 .type = HDA_FIXUP_FUNC,
5141 .v.func = alc269_fixup_hp_line1_mic1_led,
5142 },
David Henningsson693b6132012-06-22 19:12:10 +02005143 [ALC269_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005144 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02005145 .v.func = alc_fixup_inv_dmic,
David Henningsson693b6132012-06-22 19:12:10 +02005146 },
Takashi Iwai9b745ab2014-03-07 08:37:19 +01005147 [ALC269_FIXUP_NO_SHUTUP] = {
5148 .type = HDA_FIXUP_FUNC,
5149 .v.func = alc_fixup_no_shutup,
5150 },
David Henningsson108cc102012-07-20 10:37:25 +02005151 [ALC269_FIXUP_LENOVO_DOCK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005152 .type = HDA_FIXUP_PINS,
5153 .v.pins = (const struct hda_pintbl[]) {
David Henningsson108cc102012-07-20 10:37:25 +02005154 { 0x19, 0x23a11040 }, /* dock mic */
5155 { 0x1b, 0x2121103f }, /* dock headphone */
5156 { }
5157 },
5158 .chained = true,
5159 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5160 },
5161 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005162 .type = HDA_FIXUP_FUNC,
David Henningsson108cc102012-07-20 10:37:25 +02005163 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
David Henningsson52129002013-11-19 10:25:53 +01005164 .chained = true,
5165 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson108cc102012-07-20 10:37:25 +02005166 },
David Henningsson73bdd592013-04-15 15:44:14 +02005167 [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5168 .type = HDA_FIXUP_PINS,
5169 .v.pins = (const struct hda_pintbl[]) {
5170 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5171 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5172 { }
5173 },
5174 .chained = true,
5175 .chain_id = ALC269_FIXUP_HEADSET_MODE
5176 },
5177 [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5178 .type = HDA_FIXUP_PINS,
5179 .v.pins = (const struct hda_pintbl[]) {
5180 { 0x16, 0x21014020 }, /* dock line out */
5181 { 0x19, 0x21a19030 }, /* dock mic */
5182 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5183 { }
5184 },
5185 .chained = true,
5186 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5187 },
David Henningsson338cae52013-10-07 10:39:59 +02005188 [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
5189 .type = HDA_FIXUP_PINS,
5190 .v.pins = (const struct hda_pintbl[]) {
5191 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5192 { }
5193 },
5194 .chained = true,
5195 .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
5196 },
David Henningsson73bdd592013-04-15 15:44:14 +02005197 [ALC269_FIXUP_HEADSET_MODE] = {
5198 .type = HDA_FIXUP_FUNC,
5199 .v.func = alc_fixup_headset_mode,
Hui Wang6676f302014-11-18 17:57:41 +08005200 .chained = true,
5201 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
David Henningsson73bdd592013-04-15 15:44:14 +02005202 },
5203 [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5204 .type = HDA_FIXUP_FUNC,
5205 .v.func = alc_fixup_headset_mode_no_hp_mic,
5206 },
Takashi Iwai78197172015-06-27 10:21:13 +02005207 [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
5208 .type = HDA_FIXUP_PINS,
5209 .v.pins = (const struct hda_pintbl[]) {
5210 { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
5211 { }
5212 },
5213 .chained = true,
5214 .chain_id = ALC269_FIXUP_HEADSET_MODE,
5215 },
David Henningsson88cfcf82013-10-11 10:18:45 +02005216 [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
5217 .type = HDA_FIXUP_PINS,
5218 .v.pins = (const struct hda_pintbl[]) {
5219 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5220 { }
5221 },
David Henningssonfbc78ad2013-10-11 13:46:04 +02005222 .chained = true,
5223 .chain_id = ALC269_FIXUP_HEADSET_MIC
David Henningsson88cfcf82013-10-11 10:18:45 +02005224 },
David Henningssond240d1d2013-04-15 12:50:02 +02005225 [ALC269_FIXUP_ASUS_X101_FUNC] = {
5226 .type = HDA_FIXUP_FUNC,
5227 .v.func = alc269_fixup_x101_headset_mic,
5228 },
5229 [ALC269_FIXUP_ASUS_X101_VERB] = {
5230 .type = HDA_FIXUP_VERBS,
5231 .v.verbs = (const struct hda_verb[]) {
5232 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5233 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
5234 {0x20, AC_VERB_SET_PROC_COEF, 0x0310},
5235 { }
5236 },
5237 .chained = true,
5238 .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
5239 },
5240 [ALC269_FIXUP_ASUS_X101] = {
5241 .type = HDA_FIXUP_PINS,
5242 .v.pins = (const struct hda_pintbl[]) {
5243 { 0x18, 0x04a1182c }, /* Headset mic */
5244 { }
5245 },
5246 .chained = true,
5247 .chain_id = ALC269_FIXUP_ASUS_X101_VERB
5248 },
Dylan Reid08a978d2012-11-18 22:56:40 -08005249 [ALC271_FIXUP_AMIC_MIC2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005250 .type = HDA_FIXUP_PINS,
5251 .v.pins = (const struct hda_pintbl[]) {
Dylan Reid08a978d2012-11-18 22:56:40 -08005252 { 0x14, 0x99130110 }, /* speaker */
5253 { 0x19, 0x01a19c20 }, /* mic */
5254 { 0x1b, 0x99a7012f }, /* int-mic */
5255 { 0x21, 0x0121401f }, /* HP out */
5256 { }
5257 },
5258 },
5259 [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01005260 .type = HDA_FIXUP_FUNC,
Dylan Reid08a978d2012-11-18 22:56:40 -08005261 .v.func = alc271_hp_gate_mic_jack,
5262 .chained = true,
5263 .chain_id = ALC271_FIXUP_AMIC_MIC2,
5264 },
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005265 [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
5266 .type = HDA_FIXUP_FUNC,
5267 .v.func = alc269_fixup_limit_int_mic_boost,
5268 .chained = true,
5269 .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
5270 },
Dylan Reid42397002013-04-05 14:58:22 -07005271 [ALC269_FIXUP_ACER_AC700] = {
5272 .type = HDA_FIXUP_PINS,
5273 .v.pins = (const struct hda_pintbl[]) {
5274 { 0x12, 0x99a3092f }, /* int-mic */
5275 { 0x14, 0x99130110 }, /* speaker */
5276 { 0x18, 0x03a11c20 }, /* mic */
5277 { 0x1e, 0x0346101e }, /* SPDIF1 */
5278 { 0x21, 0x0321101f }, /* HP out */
5279 { }
5280 },
5281 .chained = true,
5282 .chain_id = ALC271_FIXUP_DMIC,
5283 },
David Henningsson3e0d6112013-04-22 14:30:14 +02005284 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
5285 .type = HDA_FIXUP_FUNC,
5286 .v.func = alc269_fixup_limit_int_mic_boost,
David Henningsson27937692013-11-18 11:51:47 +01005287 .chained = true,
5288 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
David Henningsson3e0d6112013-04-22 14:30:14 +02005289 },
Oleksij Rempel2cede302013-11-27 17:12:03 +01005290 [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
5291 .type = HDA_FIXUP_FUNC,
5292 .v.func = alc269_fixup_limit_int_mic_boost,
5293 .chained = true,
5294 .chain_id = ALC269VB_FIXUP_DMIC,
5295 },
Takashi Iwai23870832013-11-29 14:13:12 +01005296 [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
5297 .type = HDA_FIXUP_VERBS,
5298 .v.verbs = (const struct hda_verb[]) {
5299 /* class-D output amp +5dB */
5300 { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
5301 { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
5302 {}
5303 },
5304 .chained = true,
5305 .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
5306 },
David Henningsson8e35cd42013-11-06 11:20:01 +01005307 [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
5308 .type = HDA_FIXUP_FUNC,
5309 .v.func = alc269_fixup_limit_int_mic_boost,
5310 .chained = true,
5311 .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
5312 },
Anisse Astier02b504d2013-06-03 11:53:10 +02005313 [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
5314 .type = HDA_FIXUP_PINS,
5315 .v.pins = (const struct hda_pintbl[]) {
5316 { 0x12, 0x99a3092f }, /* int-mic */
5317 { 0x18, 0x03a11d20 }, /* mic */
5318 { 0x19, 0x411111f0 }, /* Unused bogus pin */
5319 { }
5320 },
5321 },
Kailang Yangcd217a62013-08-22 10:15:24 +02005322 [ALC283_FIXUP_CHROME_BOOK] = {
5323 .type = HDA_FIXUP_FUNC,
5324 .v.func = alc283_fixup_chromebook,
5325 },
Kailang Yang0202e992013-12-02 15:20:15 +08005326 [ALC283_FIXUP_SENSE_COMBO_JACK] = {
5327 .type = HDA_FIXUP_FUNC,
5328 .v.func = alc283_fixup_sense_combo_jack,
5329 .chained = true,
5330 .chain_id = ALC283_FIXUP_CHROME_BOOK,
5331 },
Takashi Iwai7bba2152013-09-06 15:45:38 +02005332 [ALC282_FIXUP_ASUS_TX300] = {
5333 .type = HDA_FIXUP_FUNC,
5334 .v.func = alc282_fixup_asus_tx300,
5335 },
Kailang Yang1bb3e062013-09-27 13:10:25 +02005336 [ALC283_FIXUP_INT_MIC] = {
5337 .type = HDA_FIXUP_VERBS,
5338 .v.verbs = (const struct hda_verb[]) {
5339 {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
5340 {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
5341 { }
5342 },
5343 .chained = true,
5344 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5345 },
David Henningsson0f4881d2013-12-20 16:08:13 +01005346 [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
5347 .type = HDA_FIXUP_PINS,
5348 .v.pins = (const struct hda_pintbl[]) {
5349 { 0x17, 0x90170112 }, /* subwoofer */
5350 { }
5351 },
5352 .chained = true,
5353 .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
5354 },
5355 [ALC290_FIXUP_SUBWOOFER] = {
5356 .type = HDA_FIXUP_PINS,
5357 .v.pins = (const struct hda_pintbl[]) {
5358 { 0x17, 0x90170112 }, /* subwoofer */
5359 { }
5360 },
5361 .chained = true,
5362 .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
5363 },
David Henningsson338cae52013-10-07 10:39:59 +02005364 [ALC290_FIXUP_MONO_SPEAKERS] = {
5365 .type = HDA_FIXUP_FUNC,
5366 .v.func = alc290_fixup_mono_speakers,
David Henningsson0f4881d2013-12-20 16:08:13 +01005367 },
5368 [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
5369 .type = HDA_FIXUP_FUNC,
5370 .v.func = alc290_fixup_mono_speakers,
David Henningsson338cae52013-10-07 10:39:59 +02005371 .chained = true,
5372 .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5373 },
David Henningssonb67ae3f2013-11-05 13:11:37 +01005374 [ALC269_FIXUP_THINKPAD_ACPI] = {
5375 .type = HDA_FIXUP_FUNC,
Takashi Iwai6008de22018-06-13 12:43:10 +02005376 .v.func = alc_fixup_thinkpad_acpi,
Takashi Iwai09da1112016-09-08 12:15:02 +02005377 .chained = true,
5378 .chain_id = ALC269_FIXUP_SKU_IGNORE,
David Henningssonb67ae3f2013-11-05 13:11:37 +01005379 },
David Henningsson56f27012016-01-11 09:33:14 +01005380 [ALC269_FIXUP_DMIC_THINKPAD_ACPI] = {
5381 .type = HDA_FIXUP_FUNC,
5382 .v.func = alc_fixup_inv_dmic,
5383 .chained = true,
5384 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
5385 },
Kailang Yang9a22a8f2013-11-08 15:54:49 +08005386 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5387 .type = HDA_FIXUP_PINS,
5388 .v.pins = (const struct hda_pintbl[]) {
5389 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5390 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5391 { }
5392 },
5393 .chained = true,
5394 .chain_id = ALC255_FIXUP_HEADSET_MODE
5395 },
Kailang Yang31278992014-03-03 15:27:22 +08005396 [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5397 .type = HDA_FIXUP_PINS,
5398 .v.pins = (const struct hda_pintbl[]) {
5399 { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5400 { }
5401 },
5402 .chained = true,
5403 .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
5404 },
Kailang Yang9a22a8f2013-11-08 15:54:49 +08005405 [ALC255_FIXUP_HEADSET_MODE] = {
5406 .type = HDA_FIXUP_FUNC,
5407 .v.func = alc_fixup_headset_mode_alc255,
Hui Wang4a83d422014-11-18 17:57:40 +08005408 .chained = true,
5409 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
Kailang Yang9a22a8f2013-11-08 15:54:49 +08005410 },
Kailang Yang31278992014-03-03 15:27:22 +08005411 [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5412 .type = HDA_FIXUP_FUNC,
5413 .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
5414 },
Kailang Yanga22aa262014-04-23 17:34:28 +08005415 [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5416 .type = HDA_FIXUP_PINS,
5417 .v.pins = (const struct hda_pintbl[]) {
5418 { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5419 { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5420 { }
5421 },
5422 .chained = true,
5423 .chain_id = ALC269_FIXUP_HEADSET_MODE
5424 },
Takashi Iwai1c37c222014-05-06 17:34:42 +02005425 [ALC292_FIXUP_TPT440_DOCK] = {
David Henningssonec56af62015-06-24 10:46:33 +02005426 .type = HDA_FIXUP_FUNC,
Takashi Iwai7f57d802015-09-24 17:36:51 +02005427 .v.func = alc_fixup_tpt440_dock,
Takashi Iwai1c37c222014-05-06 17:34:42 +02005428 .chained = true,
5429 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5430 },
Takashi Iwai9a811232015-12-09 15:17:43 +01005431 [ALC292_FIXUP_TPT440] = {
5432 .type = HDA_FIXUP_FUNC,
Takashi Iwai157f0b72015-12-10 23:30:43 +01005433 .v.func = alc_fixup_disable_aamix,
Takashi Iwai9a811232015-12-09 15:17:43 +01005434 .chained = true,
5435 .chain_id = ALC292_FIXUP_TPT440_DOCK,
5436 },
Anisse Astierabaa22742016-08-24 09:14:13 +02005437 [ALC283_FIXUP_HEADSET_MIC] = {
Daniel Drake9dc12862014-07-22 10:58:29 +01005438 .type = HDA_FIXUP_PINS,
5439 .v.pins = (const struct hda_pintbl[]) {
5440 { 0x19, 0x04a110f0 },
5441 { },
5442 },
5443 },
Hui Wang00ef9942014-07-31 11:52:38 +08005444 [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
5445 .type = HDA_FIXUP_FUNC,
5446 .v.func = alc_fixup_dell_wmi,
Hui Wang00ef9942014-07-31 11:52:38 +08005447 },
Takashi Iwai1a22e772014-08-27 08:19:05 +02005448 [ALC282_FIXUP_ASPIRE_V5_PINS] = {
5449 .type = HDA_FIXUP_PINS,
5450 .v.pins = (const struct hda_pintbl[]) {
5451 { 0x12, 0x90a60130 },
5452 { 0x14, 0x90170110 },
5453 { 0x17, 0x40000008 },
5454 { 0x18, 0x411111f0 },
Mateusz Sylwestrzak04206942015-07-19 17:38:56 +02005455 { 0x19, 0x01a1913c },
Takashi Iwai1a22e772014-08-27 08:19:05 +02005456 { 0x1a, 0x411111f0 },
5457 { 0x1b, 0x411111f0 },
5458 { 0x1d, 0x40f89b2d },
5459 { 0x1e, 0x411111f0 },
5460 { 0x21, 0x0321101f },
5461 { },
5462 },
5463 },
David Henningsson7a5255f2014-10-30 08:26:01 +01005464 [ALC280_FIXUP_HP_GPIO4] = {
5465 .type = HDA_FIXUP_FUNC,
5466 .v.func = alc280_fixup_hp_gpio4,
5467 },
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005468 [ALC286_FIXUP_HP_GPIO_LED] = {
5469 .type = HDA_FIXUP_FUNC,
5470 .v.func = alc286_fixup_hp_gpio_led,
5471 },
David Henningsson33f4acd2015-01-07 15:50:13 +01005472 [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
5473 .type = HDA_FIXUP_FUNC,
5474 .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
5475 },
TienFu Chenb4b33f92015-01-20 15:06:21 +01005476 [ALC280_FIXUP_HP_DOCK_PINS] = {
5477 .type = HDA_FIXUP_PINS,
5478 .v.pins = (const struct hda_pintbl[]) {
5479 { 0x1b, 0x21011020 }, /* line-out */
5480 { 0x1a, 0x01a1903c }, /* headset mic */
5481 { 0x18, 0x2181103f }, /* line-in */
5482 { },
5483 },
5484 .chained = true,
5485 .chain_id = ALC280_FIXUP_HP_GPIO4
5486 },
Jaroslav Kysela52c33232017-03-09 13:29:13 +01005487 [ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED] = {
5488 .type = HDA_FIXUP_PINS,
5489 .v.pins = (const struct hda_pintbl[]) {
5490 { 0x1b, 0x21011020 }, /* line-out */
5491 { 0x18, 0x2181103f }, /* line-in */
5492 { },
5493 },
5494 .chained = true,
5495 .chain_id = ALC269_FIXUP_HP_GPIO_MIC1_LED
5496 },
Keith Packard98973f22015-07-15 12:14:39 -07005497 [ALC280_FIXUP_HP_9480M] = {
5498 .type = HDA_FIXUP_FUNC,
5499 .v.func = alc280_fixup_hp_9480m,
5500 },
Kailang Yange1e62b92015-04-08 16:01:22 +08005501 [ALC288_FIXUP_DELL_HEADSET_MODE] = {
5502 .type = HDA_FIXUP_FUNC,
5503 .v.func = alc_fixup_headset_mode_dell_alc288,
5504 .chained = true,
5505 .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5506 },
5507 [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5508 .type = HDA_FIXUP_PINS,
5509 .v.pins = (const struct hda_pintbl[]) {
5510 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5511 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5512 { }
5513 },
5514 .chained = true,
5515 .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5516 },
5517 [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5518 .type = HDA_FIXUP_VERBS,
5519 .v.verbs = (const struct hda_verb[]) {
5520 {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5521 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5522 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5523 { }
5524 },
5525 .chained = true,
5526 .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5527 },
Hui Wang831bfdf2015-06-26 12:35:17 +08005528 [ALC288_FIXUP_DISABLE_AAMIX] = {
5529 .type = HDA_FIXUP_FUNC,
5530 .v.func = alc_fixup_disable_aamix,
5531 .chained = true,
5532 .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6
5533 },
5534 [ALC288_FIXUP_DELL_XPS_13] = {
5535 .type = HDA_FIXUP_FUNC,
5536 .v.func = alc_fixup_dell_xps13,
5537 .chained = true,
5538 .chain_id = ALC288_FIXUP_DISABLE_AAMIX
5539 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005540 [ALC292_FIXUP_DISABLE_AAMIX] = {
5541 .type = HDA_FIXUP_FUNC,
5542 .v.func = alc_fixup_disable_aamix,
Hui Wang831bfdf2015-06-26 12:35:17 +08005543 .chained = true,
5544 .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005545 },
David Henningssonc04017e2015-12-15 14:44:03 +01005546 [ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK] = {
5547 .type = HDA_FIXUP_FUNC,
5548 .v.func = alc_fixup_disable_aamix,
5549 .chained = true,
5550 .chain_id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE
5551 },
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005552 [ALC292_FIXUP_DELL_E7X] = {
5553 .type = HDA_FIXUP_FUNC,
5554 .v.func = alc_fixup_dell_xps13,
5555 .chained = true,
5556 .chain_id = ALC292_FIXUP_DISABLE_AAMIX
5557 },
Kailang Yang977e6272015-05-18 15:31:20 +08005558 [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5559 .type = HDA_FIXUP_PINS,
5560 .v.pins = (const struct hda_pintbl[]) {
5561 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5562 { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5563 { }
5564 },
5565 .chained = true,
5566 .chain_id = ALC269_FIXUP_HEADSET_MODE
5567 },
Hui Wang8aabccd2017-03-31 10:31:40 +08005568 [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = {
5569 .type = HDA_FIXUP_PINS,
5570 .v.pins = (const struct hda_pintbl[]) {
5571 { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5572 { }
5573 },
5574 .chained = true,
5575 .chain_id = ALC269_FIXUP_HEADSET_MODE
5576 },
Kailang Yang6ed11312015-10-26 15:37:39 +08005577 [ALC275_FIXUP_DELL_XPS] = {
5578 .type = HDA_FIXUP_VERBS,
5579 .v.verbs = (const struct hda_verb[]) {
5580 /* Enables internal speaker */
5581 {0x20, AC_VERB_SET_COEF_INDEX, 0x1f},
5582 {0x20, AC_VERB_SET_PROC_COEF, 0x00c0},
5583 {0x20, AC_VERB_SET_COEF_INDEX, 0x30},
5584 {0x20, AC_VERB_SET_PROC_COEF, 0x00b1},
5585 {}
5586 }
5587 },
Hui Wang8c697292015-11-24 11:08:18 +08005588 [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE] = {
5589 .type = HDA_FIXUP_VERBS,
5590 .v.verbs = (const struct hda_verb[]) {
5591 /* Disable pass-through path for FRONT 14h */
5592 {0x20, AC_VERB_SET_COEF_INDEX, 0x36},
5593 {0x20, AC_VERB_SET_PROC_COEF, 0x1737},
5594 {}
5595 },
5596 .chained = true,
5597 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5598 },
Hui Wang23adc192015-12-08 12:27:18 +08005599 [ALC293_FIXUP_LENOVO_SPK_NOISE] = {
5600 .type = HDA_FIXUP_FUNC,
5601 .v.func = alc_fixup_disable_aamix,
5602 .chained = true,
5603 .chain_id = ALC269_FIXUP_THINKPAD_ACPI
5604 },
Kailang3694cb22015-12-28 11:35:24 +08005605 [ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY] = {
5606 .type = HDA_FIXUP_FUNC,
5607 .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
5608 },
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005609 [ALC255_FIXUP_DELL_SPK_NOISE] = {
5610 .type = HDA_FIXUP_FUNC,
5611 .v.func = alc_fixup_disable_aamix,
5612 .chained = true,
5613 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5614 },
Kailang Yangdfce2062019-01-09 17:05:24 +08005615 [ALC225_FIXUP_DISABLE_MIC_VREF] = {
5616 .type = HDA_FIXUP_FUNC,
5617 .v.func = alc_fixup_disable_mic_vref,
5618 .chained = true,
5619 .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
5620 },
David Henningsson2ae95572016-02-25 09:37:05 +01005621 [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5622 .type = HDA_FIXUP_VERBS,
5623 .v.verbs = (const struct hda_verb[]) {
5624 /* Disable pass-through path for FRONT 14h */
5625 { 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
5626 { 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
5627 {}
5628 },
5629 .chained = true,
Kailang Yangdfce2062019-01-09 17:05:24 +08005630 .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
David Henningsson2ae95572016-02-25 09:37:05 +01005631 },
Takashi Iwaif8839822016-02-25 14:31:59 +01005632 [ALC280_FIXUP_HP_HEADSET_MIC] = {
5633 .type = HDA_FIXUP_FUNC,
5634 .v.func = alc_fixup_disable_aamix,
5635 .chained = true,
5636 .chain_id = ALC269_FIXUP_HEADSET_MIC,
5637 },
Hui Wange549d192016-04-01 11:00:15 +08005638 [ALC221_FIXUP_HP_FRONT_MIC] = {
5639 .type = HDA_FIXUP_PINS,
5640 .v.pins = (const struct hda_pintbl[]) {
5641 { 0x19, 0x02a19020 }, /* Front Mic */
5642 { }
5643 },
5644 },
Sven Eckelmannc636b952016-04-11 16:55:26 +02005645 [ALC292_FIXUP_TPT460] = {
5646 .type = HDA_FIXUP_FUNC,
5647 .v.func = alc_fixup_tpt440_dock,
5648 .chained = true,
5649 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE,
5650 },
Hui Wangdd9aa332016-08-01 10:20:32 +08005651 [ALC298_FIXUP_SPK_VOLUME] = {
5652 .type = HDA_FIXUP_FUNC,
5653 .v.func = alc298_fixup_speaker_volume,
Hui Wang59ec4b52016-08-04 15:28:04 +08005654 .chained = true,
Hui Wang8aabccd2017-03-31 10:31:40 +08005655 .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
Hui Wangdd9aa332016-08-01 10:20:32 +08005656 },
Takashi Iwaib992e8f2018-03-06 12:14:17 +01005657 [ALC295_FIXUP_DISABLE_DAC3] = {
5658 .type = HDA_FIXUP_FUNC,
5659 .v.func = alc295_fixup_disable_dac3,
5660 },
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005661 [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
5662 .type = HDA_FIXUP_PINS,
5663 .v.pins = (const struct hda_pintbl[]) {
5664 { 0x1b, 0x90170151 },
5665 { }
5666 },
5667 .chained = true,
5668 .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
5669 },
Kailang Yangd8fff0e72018-02-02 15:26:46 +08005670 [ALC298_FIXUP_TPT470_DOCK] = {
5671 .type = HDA_FIXUP_FUNC,
5672 .v.func = alc_fixup_tpt470_dock,
5673 .chained = true,
5674 .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
5675 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02005676};
5677
5678static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Marius Knausta6b92b62014-03-03 01:48:58 +01005679 SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
David Henningsson693b6132012-06-22 19:12:10 +02005680 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
5681 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02005682 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
Takashi Iwai78197172015-06-27 10:21:13 +02005683 SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5684 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
David Henningssonaaedfb42013-08-16 14:09:02 +02005685 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5686 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
Simon South02322ac2016-03-02 23:10:44 -05005687 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Oleksij Rempelb1e89722013-12-04 20:50:53 +01005688 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
Takashi Iwai1a22e772014-08-27 08:19:05 +02005689 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
Takashi Iwaib9c2fa52015-11-19 16:39:50 +01005690 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
David Henningssonaaedfb42013-08-16 14:09:02 +02005691 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
Kailang Yang6ed11312015-10-26 15:37:39 +08005692 SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
Takashi Iwai86f799b2015-11-14 17:46:31 +01005693 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
Takashi Iwaicf521032016-01-15 12:59:25 +01005694 SND_PCI_QUIRK(0x1028, 0x05be, "Dell Latitude E6540", ALC292_FIXUP_DELL_E7X),
Takashi Iwai8b99aba2015-06-15 11:59:32 +02005695 SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
5696 SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01005697 SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
David Henningsson73bdd592013-04-15 15:44:14 +02005698 SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5699 SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5700 SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningsson0f4881d2013-12-20 16:08:13 +01005701 SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5702 SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
Takashi Iwai98070572016-01-12 21:06:39 +01005703 SND_PCI_QUIRK(0x1028, 0x062c, "Dell Latitude E5550", ALC292_FIXUP_DELL_E7X),
Takashi Iwai42755542015-06-29 10:56:53 +02005704 SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
David Henningsson0f4881d2013-12-20 16:08:13 +01005705 SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
Kailang Yanga22aa262014-04-23 17:34:28 +08005706 SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5707 SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Hui Wang831bfdf2015-06-26 12:35:17 +08005708 SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
Bastien Noceraafecb142016-04-18 11:10:42 +02005709 SND_PCI_QUIRK(0x1028, 0x0669, "Dell Optiplex 9020m", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai3a05d122015-07-29 09:04:52 +02005710 SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
Kailang Yang8b724152014-12-17 17:08:59 +08005711 SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
Kailang Yangb7343042014-12-02 14:50:45 +08005712 SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5713 SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
David Henningssonc04017e2015-12-15 14:44:03 +01005714 SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5715 SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5716 SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5717 SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
5718 SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08005719 SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Fengfd06c772016-08-30 15:36:34 +08005720 SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Kai-Heng Feng3b43b712016-02-25 15:19:38 +08005721 SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
Kai-Heng Feng423cd782016-05-20 15:47:23 +08005722 SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kai-Heng Feng685a8f92018-10-04 11:39:42 +08005723 SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
Hui Wangdd9aa332016-08-01 10:20:32 +08005724 SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
Takashi Iwaib992e8f2018-03-06 12:14:17 +01005725 SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
Takashi Iwai2abe6202017-02-28 17:27:57 +01005726 SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
Takashi Iwaifae704d2018-01-10 08:34:28 +01005727 SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
Kailang Yanga22aa262014-04-23 17:34:28 +08005728 SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5729 SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
Takashi Iwai08fb0d02013-01-10 17:33:58 +01005730 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005731 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
David Henningsson8e35cd42013-11-06 11:20:01 +01005732 SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
David Henningsson33f4acd2015-01-07 15:50:13 +01005733 SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
Kailang Yangc60666b2014-02-21 16:23:35 +08005734 /* ALC282 */
Hui Wang7976eb42015-02-13 11:14:41 +08005735 SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08005736 SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08005737 SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005738 SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5739 SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5740 SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5741 SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005742 SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08005743 SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005744 SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5745 SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08005746 SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangeaa8e5e2014-11-21 15:49:11 +08005747 SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
TienFu Chenb4b33f92015-01-20 15:06:21 +01005748 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
TienFu Chen3271cb22015-02-10 09:09:41 +01005749 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
Kailang Yangc60666b2014-02-21 16:23:35 +08005750 SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005751 SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5752 SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5753 SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005754 SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Keith Packard98973f22015-07-15 12:14:39 -07005755 SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005756 SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5757 SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08005758 /* ALC290 */
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005759 SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005760 SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005761 SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005762 SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5763 SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5764 SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5765 SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5766 SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005767 SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Jaroslav Kysela52c33232017-03-09 13:29:13 +01005768 SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08005769 SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005770 SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5771 SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5772 SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005773 SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5774 SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yang9c5dc3b2014-06-19 16:11:36 +08005775 SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
Kailang Yangc60666b2014-02-21 16:23:35 +08005776 SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005777 SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005778 SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005779 SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5780 SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005781 SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5782 SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yangc60666b2014-02-21 16:23:35 +08005783 SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Kailang Yang8a02b162014-06-13 17:16:31 +08005784 SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5785 SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5786 SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5787 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
Takashi Iwaif8839822016-02-25 14:31:59 +01005788 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
Hui Wange549d192016-04-01 11:00:15 +08005789 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
Takashi Iwai7bba2152013-09-06 15:45:38 +02005790 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
David Henningsson3e0d6112013-04-22 14:30:14 +02005791 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5792 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Oleksij Rempel2cede302013-11-27 17:12:03 +01005793 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
Takashi Iwai23870832013-11-29 14:13:12 +01005794 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
David Henningsson3e0d6112013-04-22 14:30:14 +02005795 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
Takashi Iwai017f2a12011-07-09 14:42:25 +02005796 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
David Henningsson693b6132012-06-22 19:12:10 +02005797 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
David Henningsson3e0d6112013-04-22 14:30:14 +02005798 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaiadabb3e2011-08-03 07:48:37 +02005799 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5800 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5801 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5802 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
David Henningssond240d1d2013-04-15 12:50:02 +02005803 SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
Takashi Iwaif88abaa2014-02-07 12:07:59 +01005804 SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
David Henningsson88cfcf82013-10-11 10:18:45 +02005805 SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
Takashi Iwai1d045db2011-07-07 18:23:21 +02005806 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
5807 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5808 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
Takashi Iwaie9bd7d52014-05-21 11:06:49 +02005809 SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
Takashi Iwai24519912011-08-16 15:08:49 +02005810 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
Takashi Iwai4df3fd12015-06-29 08:38:02 +02005811 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
Takashi Iwaicc7016a2015-04-08 20:47:55 +02005812 SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Takashi Iwai88776f32015-05-01 09:20:34 +02005813 SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
Jan-Marek Glogowskibb1a4222018-02-14 11:29:15 +01005814 SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
David Henningsson2041d562014-06-13 11:15:44 +02005815 SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
David Henningssona33cc482014-10-07 10:18:41 +02005816 SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
Anisse Astierabaa22742016-08-24 09:14:13 +02005817 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
5818 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
Takashi Iwai1d045db2011-07-07 18:23:21 +02005819 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5820 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5821 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5822 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5823 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
Takashi Iwai707fba32012-08-02 09:04:39 +02005824 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
Felix Kaechelec8415a42012-08-06 23:02:01 +02005825 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
Stefán Freyr84f98fd2012-10-19 22:46:00 +02005826 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
Philipp A. Mohrenweiser4407be62012-08-06 13:14:18 +02005827 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
David Henningsson108cc102012-07-20 10:37:25 +02005828 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
David Henningssonaaedfb42013-08-16 14:09:02 +02005829 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
Takashi Iwai9a811232015-12-09 15:17:43 +01005830 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440),
Takashi Iwai1c37c222014-05-06 17:34:42 +02005831 SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwaia12137e2014-06-27 12:14:35 +02005832 SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
Rick Sherman59a51a62015-08-18 21:04:30 -05005833 SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
Takashi Iwai6d169412014-10-07 17:27:02 +02005834 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
Lukas Bossard7c215392014-10-29 18:31:07 +01005835 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
David Henningssona4a9e082013-08-16 14:09:01 +02005836 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Takashi Iwaib6903c02015-12-10 12:20:20 +01005837 SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
Laura Abbottd05ea7d2015-10-02 11:09:54 -07005838 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
Yves-Alexis Perezc0278662015-04-11 09:31:35 +02005839 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
Kailang Yangd8fff0e72018-02-02 15:26:46 +08005840 SND_PCI_QUIRK(0x17aa, 0x222d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5841 SND_PCI_QUIRK(0x17aa, 0x222e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Torsten Hilbrichdab38e42016-06-07 13:14:21 +02005842 SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
Sven Eckelmannc636b952016-04-11 16:55:26 +02005843 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yangd8fff0e72018-02-02 15:26:46 +08005844 SND_PCI_QUIRK(0x17aa, 0x2245, "Thinkpad T470", ALC298_FIXUP_TPT470_DOCK),
5845 SND_PCI_QUIRK(0x17aa, 0x2246, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5846 SND_PCI_QUIRK(0x17aa, 0x2247, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Dennis Wassenberg5191f412018-03-08 13:17:54 +01005847 SND_PCI_QUIRK(0x17aa, 0x2249, "Thinkpad", ALC292_FIXUP_TPT460),
Kailang Yangd8fff0e72018-02-02 15:26:46 +08005848 SND_PCI_QUIRK(0x17aa, 0x224b, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5849 SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5850 SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
Benjamin Bergf8521db2018-02-14 13:29:39 +01005851 SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang3694cb22015-12-28 11:35:24 +08005852 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wang6ef2f682016-03-11 12:04:02 +08005853 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
Hui Wangacb06ff2017-02-27 10:11:47 +08005854 SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
David Henningsson56f27012016-01-11 09:33:14 +01005855 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
Takashi Iwaifedb2242014-11-13 07:11:38 +01005856 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
Michał Wadowski51776202019-05-14 16:58:00 +02005857 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
David Henningssona4a9e082013-08-16 14:09:01 +02005858 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yang1bb3e062013-09-27 13:10:25 +02005859 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
Takashi Iwaic497d9f2014-10-08 12:14:40 +02005860 SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02005861 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Jo-Philipp Wichf2aa1112015-04-13 12:47:26 +02005862 SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
Sebastian Wicki80b311d2015-03-23 17:23:11 +01005863 SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
Ansgar Hegerfeld09ea9972015-05-14 12:31:32 +02005864 SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
Conrad Kostecki037e1192016-04-26 10:08:10 +02005865 SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
Hui Wang23adc192015-12-08 12:27:18 +08005866 SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02005867 SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
Torsten Hilbrich9cd25742016-07-05 10:40:22 +02005868 SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
Jaroslav Kysela0f087ee2016-06-24 15:13:16 +02005869 SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
Kailang Yangd8fff0e72018-02-02 15:26:46 +08005870 SND_PCI_QUIRK(0x17aa, 0x505d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5871 SND_PCI_QUIRK(0x17aa, 0x505f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5872 SND_PCI_QUIRK(0x17aa, 0x5062, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningssoncd5302c2013-08-19 12:22:33 +02005873 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Kailang Yangd8fff0e72018-02-02 15:26:46 +08005874 SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
5875 SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
David Henningsson012e7eb2012-08-08 08:43:37 +02005876 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
Takashi Iwai1d045db2011-07-07 18:23:21 +02005877 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
Anisse Astier02b504d2013-06-03 11:53:10 +02005878 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02005879
Takashi Iwaia7f3eed2012-02-16 13:03:18 +01005880#if 0
Takashi Iwaia4297b52011-08-23 18:40:12 +02005881 /* Below is a quirk table taken from the old code.
5882 * Basically the device should work as is without the fixup table.
5883 * If BIOS doesn't give a proper info, enable the corresponding
5884 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02005885 */
Takashi Iwaia4297b52011-08-23 18:40:12 +02005886 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5887 ALC269_FIXUP_AMIC),
5888 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
Takashi Iwaia4297b52011-08-23 18:40:12 +02005889 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5890 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5891 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
5892 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
5893 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
5894 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
5895 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
5896 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
5897 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
5898 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
5899 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
5900 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
5901 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
5902 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
5903 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
5904 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
5905 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
5906 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
5907 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
5908 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
5909 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
5910 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
5911 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
5912 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
5913 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
5914 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
5915 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
5916 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
5917 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
5918 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
5919 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
5920 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
5921 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
5922 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
5923 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
5924 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
5925 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
5926 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
5927#endif
5928 {}
5929};
5930
David Henningsson214eef72014-07-22 14:09:35 +02005931static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
5932 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
5933 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
5934 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
5935 SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
5936 {}
5937};
5938
Takashi Iwai1727a772013-01-10 09:52:52 +01005939static const struct hda_model_fixup alc269_fixup_models[] = {
Takashi Iwaia4297b52011-08-23 18:40:12 +02005940 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5941 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02005942 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
5943 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
5944 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningsson7c478f02013-10-11 10:18:46 +02005945 {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
Takashi Iwaib0169512015-05-19 10:20:13 +02005946 {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
5947 {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
David Henningsson108cc102012-07-20 10:37:25 +02005948 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
Takashi Iwai9f5c6fa2013-03-18 14:15:58 +01005949 {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
Jaroslav Kysela52c33232017-03-09 13:29:13 +01005950 {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
David Henningssone32aa852013-06-17 11:04:02 +02005951 {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5952 {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
Kailang Yangbe8ef162014-04-08 15:19:49 +08005953 {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
Kailang Yang0202e992013-12-02 15:20:15 +08005954 {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
Takashi Iwai1c37c222014-05-06 17:34:42 +02005955 {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
Takashi Iwai9a811232015-12-09 15:17:43 +01005956 {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
Sven Eckelmannc636b952016-04-11 16:55:26 +02005957 {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
Takashi Iwai1d045db2011-07-07 18:23:21 +02005958 {}
5959};
Kailang Yangcfc5a842016-02-03 15:20:39 +08005960#define ALC225_STANDARD_PINS \
Kailang Yangcfc5a842016-02-03 15:20:39 +08005961 {0x21, 0x04211020}
Takashi Iwai1d045db2011-07-07 18:23:21 +02005962
Hui Wange8191a82015-04-24 13:39:59 +08005963#define ALC256_STANDARD_PINS \
5964 {0x12, 0x90a60140}, \
5965 {0x14, 0x90170110}, \
Hui Wange8191a82015-04-24 13:39:59 +08005966 {0x21, 0x02211020}
5967
David Henningssonfea185e2014-09-03 10:23:04 +02005968#define ALC282_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08005969 {0x14, 0x90170110}
Kailang Yange1e62b92015-04-08 16:01:22 +08005970
David Henningssonfea185e2014-09-03 10:23:04 +02005971#define ALC290_STANDARD_PINS \
Hui Wang11580292015-08-03 11:03:49 +08005972 {0x12, 0x99a30130}
David Henningssonfea185e2014-09-03 10:23:04 +02005973
5974#define ALC292_STANDARD_PINS \
5975 {0x14, 0x90170110}, \
Hui Wang11580292015-08-03 11:03:49 +08005976 {0x15, 0x0221401f}
Kailang Yang977e6272015-05-18 15:31:20 +08005977
Hui Wang3f6409702016-09-11 11:26:16 +08005978#define ALC295_STANDARD_PINS \
5979 {0x12, 0xb7a60130}, \
5980 {0x14, 0x90170110}, \
Hui Wang3f6409702016-09-11 11:26:16 +08005981 {0x21, 0x04211020}
5982
Woodrow Shen703867e2015-08-05 12:34:12 +08005983#define ALC298_STANDARD_PINS \
5984 {0x12, 0x90a60130}, \
5985 {0x21, 0x03211020}
5986
Hui Wange1918932014-05-26 16:22:44 +08005987static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
David Henningsson2ae95572016-02-25 09:37:05 +01005988 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08005989 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08005990 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08005991 {0x14, 0x901701a0}),
David Henningsson2ae95572016-02-25 09:37:05 +01005992 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yangcfc5a842016-02-03 15:20:39 +08005993 ALC225_STANDARD_PINS,
Hui Wang8a132092016-07-08 14:26:57 +08005994 {0x12, 0xb7a60130},
Kailang Yangcfc5a842016-02-03 15:20:39 +08005995 {0x14, 0x901701b0}),
Hui Wang8a132092016-07-08 14:26:57 +08005996 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
5997 ALC225_STANDARD_PINS,
5998 {0x12, 0xb7a60150},
5999 {0x14, 0x901701a0}),
6000 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6001 ALC225_STANDARD_PINS,
6002 {0x12, 0xb7a60150},
6003 {0x14, 0x901701b0}),
6004 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6005 ALC225_STANDARD_PINS,
6006 {0x12, 0xb7a60130},
6007 {0x1b, 0x90170110}),
Hui Wang41f804d2017-10-24 16:53:34 +08006008 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6009 {0x12, 0x90a60140},
6010 {0x14, 0x90170110},
6011 {0x21, 0x02211020}),
6012 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6013 {0x12, 0x90a60140},
6014 {0x14, 0x90170150},
6015 {0x21, 0x02211020}),
Hui Wangc77900e2014-09-03 11:31:07 +08006016 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Hui Wangc77900e2014-09-03 11:31:07 +08006017 {0x14, 0x90170110},
Hui Wangc77900e2014-09-03 11:31:07 +08006018 {0x21, 0x02211020}),
David Henningsson76c21322014-06-24 14:46:54 +02006019 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang86c72d12016-05-25 12:12:32 +08006020 {0x14, 0x90170130},
6021 {0x21, 0x02211040}),
6022 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02006023 {0x12, 0x90a60140},
6024 {0x14, 0x90170110},
David Henningsson76c21322014-06-24 14:46:54 +02006025 {0x21, 0x02211020}),
6026 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6027 {0x12, 0x90a60160},
6028 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006029 {0x21, 0x02211030}),
6030 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang392c9da2016-09-26 10:59:38 +08006031 {0x14, 0x90170110},
6032 {0x1b, 0x02011020},
6033 {0x21, 0x0221101f}),
6034 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang6aecd872016-10-20 14:03:33 +08006035 {0x14, 0x90170110},
6036 {0x1b, 0x01011020},
6037 {0x21, 0x0221101f}),
6038 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncba59972015-07-22 10:00:25 +02006039 {0x14, 0x90170130},
David Henningssoncba59972015-07-22 10:00:25 +02006040 {0x1b, 0x01014020},
David Henningssoncba59972015-07-22 10:00:25 +02006041 {0x21, 0x0221103f}),
6042 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang59ec4b52016-08-04 15:28:04 +08006043 {0x14, 0x90170130},
Hui Wang6aecd872016-10-20 14:03:33 +08006044 {0x1b, 0x01011020},
6045 {0x21, 0x0221103f}),
6046 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6047 {0x14, 0x90170130},
Hui Wang59ec4b52016-08-04 15:28:04 +08006048 {0x1b, 0x02011020},
6049 {0x21, 0x0221103f}),
6050 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08006051 {0x14, 0x90170150},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006052 {0x1b, 0x02011020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006053 {0x21, 0x0221105f}),
6054 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shene9c28e12015-07-25 10:36:16 +08006055 {0x14, 0x90170110},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006056 {0x1b, 0x01014020},
Woodrow Shene9c28e12015-07-25 10:36:16 +08006057 {0x21, 0x0221101f}),
6058 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson76c21322014-06-24 14:46:54 +02006059 {0x12, 0x90a60160},
6060 {0x14, 0x90170120},
6061 {0x17, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02006062 {0x21, 0x0321102f}),
6063 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6064 {0x12, 0x90a60160},
6065 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02006066 {0x21, 0x02211040}),
6067 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6068 {0x12, 0x90a60160},
6069 {0x14, 0x90170140},
David Henningsson76c21322014-06-24 14:46:54 +02006070 {0x21, 0x02211050}),
6071 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6072 {0x12, 0x90a60170},
6073 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006074 {0x21, 0x02211030}),
6075 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6076 {0x12, 0x90a60170},
6077 {0x14, 0x90170130},
David Henningsson76c21322014-06-24 14:46:54 +02006078 {0x21, 0x02211040}),
Hui Wang70658b92015-03-06 14:03:57 +08006079 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang70658b92015-03-06 14:03:57 +08006080 {0x12, 0x90a60170},
Hui Wang0a1f90a2016-01-13 11:51:38 +08006081 {0x14, 0x90171130},
6082 {0x21, 0x02211040}),
6083 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6084 {0x12, 0x90a60170},
Hui Wang70658b92015-03-06 14:03:57 +08006085 {0x14, 0x90170140},
Hui Wang70658b92015-03-06 14:03:57 +08006086 {0x21, 0x02211050}),
David Henningsson9b5a4e32015-05-11 14:04:14 +02006087 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningsson9b5a4e32015-05-11 14:04:14 +02006088 {0x12, 0x90a60180},
6089 {0x14, 0x90170130},
David Henningsson9b5a4e32015-05-11 14:04:14 +02006090 {0x21, 0x02211040}),
AceLan Kaof90d83b2016-06-03 14:45:25 +08006091 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6092 {0x12, 0x90a60180},
6093 {0x14, 0x90170120},
6094 {0x21, 0x02211030}),
Hui Wang0119d5d2016-11-23 16:05:38 +08006095 SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6096 {0x1b, 0x01011020},
6097 {0x21, 0x02211010}),
Kailang Yang7081adf2015-03-30 17:05:37 +08006098 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang65ca46e2017-12-22 11:17:45 +08006099 {0x12, 0x90a60130},
6100 {0x14, 0x90170110},
6101 {0x1b, 0x01011020},
6102 {0x21, 0x0221101f}),
6103 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Kailang Yang81a12312015-05-28 16:48:22 +08006104 {0x12, 0x90a60160},
6105 {0x14, 0x90170120},
Kailang Yang81a12312015-05-28 16:48:22 +08006106 {0x21, 0x02211030}),
6107 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shenf83c3292016-06-24 15:58:34 +08006108 {0x12, 0x90a60170},
6109 {0x14, 0x90170120},
6110 {0x21, 0x02211030}),
Shrirang Bagul311042d2016-08-29 15:19:27 +08006111 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
6112 {0x12, 0x90a60180},
6113 {0x14, 0x90170120},
6114 {0x21, 0x02211030}),
Woodrow Shenf83c3292016-06-24 15:58:34 +08006115 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3f6409702016-09-11 11:26:16 +08006116 {0x12, 0xb7a60130},
6117 {0x14, 0x90170110},
6118 {0x21, 0x02211020}),
David Henningssoncf51eb92014-10-30 08:26:02 +01006119 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wang3dc694f2018-01-29 14:23:15 +08006120 {0x12, 0x90a60130},
6121 {0x14, 0x90170110},
6122 {0x14, 0x01011020},
6123 {0x21, 0x0221101f}),
6124 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssoncf51eb92014-10-30 08:26:02 +01006125 ALC256_STANDARD_PINS),
6126 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
6127 {0x12, 0x90a60130},
6128 {0x14, 0x90170110},
6129 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08006130 {0x1a, 0x04a11020}),
Hui Wang02796612014-09-03 11:31:11 +08006131 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
6132 {0x12, 0x90a60140},
Hui Wang02796612014-09-03 11:31:11 +08006133 {0x14, 0x90170110},
6134 {0x15, 0x0421101f},
Hui Wang02796612014-09-03 11:31:11 +08006135 {0x18, 0x02811030},
Hui Wang02796612014-09-03 11:31:11 +08006136 {0x1a, 0x04a1103f},
Hui Wang11580292015-08-03 11:03:49 +08006137 {0x1b, 0x02011020}),
David Henningsson42304472014-07-22 11:42:17 +02006138 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006139 ALC282_STANDARD_PINS,
David Henningsson42304472014-07-22 11:42:17 +02006140 {0x12, 0x99a30130},
David Henningsson42304472014-07-22 11:42:17 +02006141 {0x19, 0x03a11020},
David Henningsson42304472014-07-22 11:42:17 +02006142 {0x21, 0x0321101f}),
Hui Wang2c609992014-09-03 11:31:08 +08006143 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006144 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006145 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006146 {0x19, 0x03a11020},
Hui Wang2c609992014-09-03 11:31:08 +08006147 {0x21, 0x03211040}),
6148 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006149 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006150 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006151 {0x19, 0x03a11030},
Hui Wang2c609992014-09-03 11:31:08 +08006152 {0x21, 0x03211020}),
6153 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006154 ALC282_STANDARD_PINS,
Hui Wang2c609992014-09-03 11:31:08 +08006155 {0x12, 0x99a30130},
Hui Wang2c609992014-09-03 11:31:08 +08006156 {0x19, 0x04a11020},
Hui Wang2c609992014-09-03 11:31:08 +08006157 {0x21, 0x0421101f}),
Hui Wang200afc02014-09-03 11:31:10 +08006158 SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
David Henningssonaec856d2014-09-03 10:23:05 +02006159 ALC282_STANDARD_PINS,
Hui Wang200afc02014-09-03 11:31:10 +08006160 {0x12, 0x90a60140},
Hui Wang200afc02014-09-03 11:31:10 +08006161 {0x19, 0x04a11030},
Hui Wang200afc02014-09-03 11:31:10 +08006162 {0x21, 0x04211020}),
David Henningsson76c21322014-06-24 14:46:54 +02006163 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006164 ALC282_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02006165 {0x12, 0x90a60130},
David Henningsson76c21322014-06-24 14:46:54 +02006166 {0x21, 0x0321101f}),
6167 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6168 {0x12, 0x90a60160},
6169 {0x14, 0x90170120},
David Henningsson76c21322014-06-24 14:46:54 +02006170 {0x21, 0x02211030}),
Hui Wangbc262172014-09-03 11:31:05 +08006171 SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006172 ALC282_STANDARD_PINS,
Hui Wangbc262172014-09-03 11:31:05 +08006173 {0x12, 0x90a60130},
Hui Wangbc262172014-09-03 11:31:05 +08006174 {0x19, 0x03a11020},
Hui Wangbc262172014-09-03 11:31:05 +08006175 {0x21, 0x0321101f}),
Kailang Yange1e62b92015-04-08 16:01:22 +08006176 SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
Kailang Yange1e62b92015-04-08 16:01:22 +08006177 {0x12, 0x90a60120},
Kailang Yange1e62b92015-04-08 16:01:22 +08006178 {0x14, 0x90170110},
Kailang Yange1e62b92015-04-08 16:01:22 +08006179 {0x21, 0x0321101f}),
Hui Wang3dc694f2018-01-29 14:23:15 +08006180 SND_HDA_PIN_QUIRK(0x10ec0289, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
6181 {0x12, 0xb7a60130},
6182 {0x14, 0x90170110},
6183 {0x21, 0x04211020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006184 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006185 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006186 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08006187 {0x18, 0x90170112},
Hui Wang11580292015-08-03 11:03:49 +08006188 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006189 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006190 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006191 {0x15, 0x04211040},
Hui Wange4442bc2014-09-03 11:31:09 +08006192 {0x18, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08006193 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006194 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006195 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006196 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08006197 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006198 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006199 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006200 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08006201 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08006202 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006203 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006204 {0x14, 0x90170110},
6205 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08006206 {0x1a, 0x04a11040}),
Hui Wange4442bc2014-09-03 11:31:09 +08006207 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006208 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006209 {0x14, 0x90170110},
6210 {0x15, 0x04211020},
Hui Wang11580292015-08-03 11:03:49 +08006211 {0x1a, 0x04a11020}),
Hui Wange4442bc2014-09-03 11:31:09 +08006212 SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
David Henningssonaec856d2014-09-03 10:23:05 +02006213 ALC290_STANDARD_PINS,
Hui Wange4442bc2014-09-03 11:31:09 +08006214 {0x14, 0x90170110},
6215 {0x15, 0x0421101f},
Hui Wang11580292015-08-03 11:03:49 +08006216 {0x1a, 0x04a11020}),
Hui Wange8818fa2014-09-03 11:31:04 +08006217 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006218 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08006219 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08006220 {0x16, 0x01014020},
Hui Wang11580292015-08-03 11:03:49 +08006221 {0x19, 0x01a19030}),
Hui Wange8818fa2014-09-03 11:31:04 +08006222 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006223 ALC292_STANDARD_PINS,
Hui Wange8818fa2014-09-03 11:31:04 +08006224 {0x12, 0x90a60140},
Hui Wange8818fa2014-09-03 11:31:04 +08006225 {0x16, 0x01014020},
6226 {0x18, 0x02a19031},
Hui Wang11580292015-08-03 11:03:49 +08006227 {0x19, 0x01a1903e}),
David Henningsson76c21322014-06-24 14:46:54 +02006228 SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006229 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08006230 {0x12, 0x90a60140}),
David Henningsson76c21322014-06-24 14:46:54 +02006231 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006232 ALC292_STANDARD_PINS,
David Henningsson76c21322014-06-24 14:46:54 +02006233 {0x13, 0x90a60140},
David Henningsson76c21322014-06-24 14:46:54 +02006234 {0x16, 0x21014020},
Hui Wang11580292015-08-03 11:03:49 +08006235 {0x19, 0x21a19030}),
David Henningssone03fdbd2014-06-27 08:41:59 +02006236 SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
David Henningssonaec856d2014-09-03 10:23:05 +02006237 ALC292_STANDARD_PINS,
Hui Wang11580292015-08-03 11:03:49 +08006238 {0x13, 0x90a60140}),
Hui Wang3f6409702016-09-11 11:26:16 +08006239 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
Hui Wangf771d5b2016-10-18 10:59:09 +08006240 ALC295_STANDARD_PINS,
6241 {0x17, 0x21014020},
6242 {0x18, 0x21a19030}),
6243 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6244 ALC295_STANDARD_PINS,
6245 {0x17, 0x21014040},
6246 {0x18, 0x21a19050}),
Hui Wang0fe87712017-03-23 10:00:25 +08006247 SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6248 ALC295_STANDARD_PINS),
Kailang Yang977e6272015-05-18 15:31:20 +08006249 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
Woodrow Shen703867e2015-08-05 12:34:12 +08006250 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02006251 {0x17, 0x90170110}),
6252 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6253 ALC298_STANDARD_PINS,
Woodrow Shen703867e2015-08-05 12:34:12 +08006254 {0x17, 0x90170140}),
6255 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
6256 ALC298_STANDARD_PINS,
Takashi Iwai9f502ff2015-08-05 12:09:45 +02006257 {0x17, 0x90170150}),
Kai-Heng Fengebc3e952017-02-16 15:26:54 +08006258 SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
6259 {0x12, 0xb7a60140},
6260 {0x13, 0xb7a60150},
6261 {0x17, 0x90170110},
6262 {0x1a, 0x03011020},
6263 {0x21, 0x03211030}),
Hui Wange1918932014-05-26 16:22:44 +08006264 {}
6265};
Takashi Iwai1d045db2011-07-07 18:23:21 +02006266
Takashi Iwai546bb672012-03-07 08:37:19 +01006267static void alc269_fill_coef(struct hda_codec *codec)
Takashi Iwai1d045db2011-07-07 18:23:21 +02006268{
Kailang Yang526af6e2012-03-07 08:25:20 +01006269 struct alc_spec *spec = codec->spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006270 int val;
6271
Kailang Yang526af6e2012-03-07 08:25:20 +01006272 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
Takashi Iwai546bb672012-03-07 08:37:19 +01006273 return;
Kailang Yang526af6e2012-03-07 08:25:20 +01006274
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006275 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006276 alc_write_coef_idx(codec, 0xf, 0x960b);
6277 alc_write_coef_idx(codec, 0xe, 0x8817);
6278 }
6279
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006280 if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006281 alc_write_coef_idx(codec, 0xf, 0x960b);
6282 alc_write_coef_idx(codec, 0xe, 0x8814);
6283 }
6284
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006285 if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006286 /* Power up output pin */
Takashi Iwai98b24882014-08-18 13:47:50 +02006287 alc_update_coef_idx(codec, 0x04, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006288 }
6289
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006290 if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006291 val = alc_read_coef_idx(codec, 0xd);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02006292 if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006293 /* Capless ramp up clock control */
6294 alc_write_coef_idx(codec, 0xd, val | (1<<10));
6295 }
6296 val = alc_read_coef_idx(codec, 0x17);
Takashi Iwaif3ee07d2014-08-15 17:35:00 +02006297 if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006298 /* Class D power on reset */
6299 alc_write_coef_idx(codec, 0x17, val | (1<<7));
6300 }
6301 }
6302
Takashi Iwai98b24882014-08-18 13:47:50 +02006303 /* HP */
6304 alc_update_coef_idx(codec, 0x4, 0, 1<<11);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006305}
6306
6307/*
6308 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02006309static int patch_alc269(struct hda_codec *codec)
6310{
6311 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02006312 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006313
Takashi Iwai3de95172012-05-07 18:03:15 +02006314 err = alc_alloc_spec(codec, 0x0b);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006315 if (err < 0)
Takashi Iwai3de95172012-05-07 18:03:15 +02006316 return err;
6317
6318 spec = codec->spec;
Takashi Iwai08c189f2012-12-19 15:22:24 +01006319 spec->gen.shared_mic_vref_pin = 0x18;
Kailang Yangd7852cb2019-05-23 14:43:04 +08006320 codec->power_save_node = 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006321
Takashi Iwai225068a2015-05-29 10:42:14 +02006322#ifdef CONFIG_PM
6323 codec->patch_ops.suspend = alc269_suspend;
6324 codec->patch_ops.resume = alc269_resume;
6325#endif
6326 spec->shutup = alc269_shutup;
6327
Takashi Iwai1727a772013-01-10 09:52:52 +01006328 snd_hda_pick_fixup(codec, alc269_fixup_models,
Herton Ronaldo Krzesinski9f720bb2012-09-27 10:38:14 -03006329 alc269_fixup_tbl, alc269_fixups);
Hui Wange1918932014-05-26 16:22:44 +08006330 snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
David Henningsson214eef72014-07-22 14:09:35 +02006331 snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
6332 alc269_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01006333 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Herton Ronaldo Krzesinski9f720bb2012-09-27 10:38:14 -03006334
6335 alc_auto_parse_customize_define(codec);
6336
Takashi Iwai7504b6c2013-03-18 11:25:51 +01006337 if (has_cdefine_beep(codec))
6338 spec->gen.beep_nid = 0x01;
6339
Takashi Iwai7639a062015-03-03 10:07:24 +01006340 switch (codec->core.vendor_id) {
Kailang Yang065380f2013-01-10 10:25:48 +01006341 case 0x10ec0269:
Takashi Iwai1d045db2011-07-07 18:23:21 +02006342 spec->codec_variant = ALC269_TYPE_ALC269VA;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006343 switch (alc_get_coef0(codec) & 0x00f0) {
6344 case 0x0010:
Takashi Iwai5100cd02014-02-15 10:03:19 +01006345 if (codec->bus->pci &&
6346 codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006347 spec->cdefine.platform_type == 1)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02006348 err = alc_codec_rename(codec, "ALC271X");
Takashi Iwai1d045db2011-07-07 18:23:21 +02006349 spec->codec_variant = ALC269_TYPE_ALC269VB;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006350 break;
6351 case 0x0020:
Takashi Iwai5100cd02014-02-15 10:03:19 +01006352 if (codec->bus->pci &&
6353 codec->bus->pci->subsystem_vendor == 0x17aa &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006354 codec->bus->pci->subsystem_device == 0x21f3)
Takashi Iwai20ca0c32011-10-17 16:00:35 +02006355 err = alc_codec_rename(codec, "ALC3202");
Takashi Iwai1d045db2011-07-07 18:23:21 +02006356 spec->codec_variant = ALC269_TYPE_ALC269VC;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006357 break;
Kailang Yangadcc70b2012-05-25 08:08:38 +02006358 case 0x0030:
6359 spec->codec_variant = ALC269_TYPE_ALC269VD;
6360 break;
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006361 default:
Takashi Iwai1d045db2011-07-07 18:23:21 +02006362 alc_fix_pll_init(codec, 0x20, 0x04, 15);
Takashi Iwai1bb7e432011-10-17 16:50:59 +02006363 }
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006364 if (err < 0)
6365 goto error;
Takashi Iwai546bb672012-03-07 08:37:19 +01006366 spec->init_hook = alc269_fill_coef;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006367 alc269_fill_coef(codec);
Kailang Yang065380f2013-01-10 10:25:48 +01006368 break;
6369
6370 case 0x10ec0280:
6371 case 0x10ec0290:
6372 spec->codec_variant = ALC269_TYPE_ALC280;
6373 break;
6374 case 0x10ec0282:
Kailang Yang065380f2013-01-10 10:25:48 +01006375 spec->codec_variant = ALC269_TYPE_ALC282;
Kailang Yang7b5c7a02014-03-18 16:15:54 +08006376 spec->shutup = alc282_shutup;
6377 spec->init_hook = alc282_init;
Kailang Yang065380f2013-01-10 10:25:48 +01006378 break;
Kailang Yang2af02be2013-08-22 10:03:50 +02006379 case 0x10ec0233:
6380 case 0x10ec0283:
6381 spec->codec_variant = ALC269_TYPE_ALC283;
6382 spec->shutup = alc283_shutup;
6383 spec->init_hook = alc283_init;
6384 break;
Kailang Yang065380f2013-01-10 10:25:48 +01006385 case 0x10ec0284:
6386 case 0x10ec0292:
6387 spec->codec_variant = ALC269_TYPE_ALC284;
6388 break;
Kailang Yang161ebf22013-10-24 11:36:33 +02006389 case 0x10ec0285:
6390 case 0x10ec0293:
6391 spec->codec_variant = ALC269_TYPE_ALC285;
6392 break;
Kailang Yang7fc7d042013-04-25 11:04:43 +02006393 case 0x10ec0286:
Kailang Yang7c665932014-04-14 15:09:44 +08006394 case 0x10ec0288:
Kailang Yang7fc7d042013-04-25 11:04:43 +02006395 spec->codec_variant = ALC269_TYPE_ALC286;
Kailang Yangf7ae9ba2014-06-30 16:10:37 +08006396 spec->shutup = alc286_shutup;
Kailang Yang7fc7d042013-04-25 11:04:43 +02006397 break;
Kailang Yang506b62c2014-12-18 17:07:44 +08006398 case 0x10ec0298:
6399 spec->codec_variant = ALC269_TYPE_ALC298;
6400 break;
Kailang Yangd197dfc2018-04-25 15:31:52 +08006401 case 0x10ec0235:
Kailang Yang1d04c9d2013-10-24 11:35:18 +02006402 case 0x10ec0255:
6403 spec->codec_variant = ALC269_TYPE_ALC255;
6404 break;
Kailang Yang61ae3fb2017-10-20 15:06:34 +08006405 case 0x10ec0236:
Kailang Yang4344aec2014-12-17 17:39:05 +08006406 case 0x10ec0256:
6407 spec->codec_variant = ALC269_TYPE_ALC256;
David Henningsson7d1b6e22015-04-21 10:48:46 +02006408 spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
Kailang Yangd32b6662015-04-23 15:10:53 +08006409 alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
Kailang Yang4344aec2014-12-17 17:39:05 +08006410 break;
Kailang Yang2435d6b2017-12-05 15:38:24 +08006411 case 0x10ec0257:
6412 spec->codec_variant = ALC269_TYPE_ALC257;
6413 spec->gen.mixer_nid = 0;
6414 break;
Kailang Yang42314302016-02-03 15:03:50 +08006415 case 0x10ec0225:
Kailang Yang7d727862016-05-24 16:46:07 +08006416 case 0x10ec0295:
Takashi Iwaiddf39e0f2017-05-16 09:11:33 +02006417 spec->codec_variant = ALC269_TYPE_ALC225;
6418 break;
Kailang Yangf6e94c22017-01-04 14:49:07 +08006419 case 0x10ec0299:
Kailang Yang42314302016-02-03 15:03:50 +08006420 spec->codec_variant = ALC269_TYPE_ALC225;
Takashi Iwaiddf39e0f2017-05-16 09:11:33 +02006421 spec->gen.mixer_nid = 0; /* no loopback on ALC299 */
Kailang Yang42314302016-02-03 15:03:50 +08006422 break;
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08006423 case 0x10ec0234:
6424 case 0x10ec0274:
6425 case 0x10ec0294:
6426 spec->codec_variant = ALC269_TYPE_ALC294;
6427 break;
Kailang Yang6fbae352016-05-30 16:44:20 +08006428 case 0x10ec0700:
6429 case 0x10ec0701:
6430 case 0x10ec0703:
6431 spec->codec_variant = ALC269_TYPE_ALC700;
6432 spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
Kailang Yang193fd092017-11-22 15:21:32 +08006433 alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
Kailang Yang6fbae352016-05-30 16:44:20 +08006434 break;
6435
Takashi Iwai1d045db2011-07-07 18:23:21 +02006436 }
6437
Kailang Yangad60d502013-06-28 12:03:01 +02006438 if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
Kailang Yang97a26572013-11-29 00:35:26 -05006439 spec->has_alc5505_dsp = 1;
Kailang Yangad60d502013-06-28 12:03:01 +02006440 spec->init_hook = alc5505_dsp_init;
6441 }
6442
Takashi Iwaia4297b52011-08-23 18:40:12 +02006443 /* automatic parse from the BIOS config */
6444 err = alc269_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006445 if (err < 0)
6446 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006447
David Henningsson7d1b6e22015-04-21 10:48:46 +02006448 if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
6449 set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006450
Takashi Iwai1727a772013-01-10 09:52:52 +01006451 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01006452
Takashi Iwai1d045db2011-07-07 18:23:21 +02006453 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006454
6455 error:
6456 alc_free(codec);
6457 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006458}
6459
6460/*
6461 * ALC861
6462 */
6463
Takashi Iwai1d045db2011-07-07 18:23:21 +02006464static int alc861_parse_auto_config(struct hda_codec *codec)
6465{
Takashi Iwai1d045db2011-07-07 18:23:21 +02006466 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006467 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
6468 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006469}
6470
Takashi Iwai1d045db2011-07-07 18:23:21 +02006471/* Pin config fixes */
6472enum {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006473 ALC861_FIXUP_FSC_AMILO_PI1505,
6474 ALC861_FIXUP_AMP_VREF_0F,
6475 ALC861_FIXUP_NO_JACK_DETECT,
6476 ALC861_FIXUP_ASUS_A6RP,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01006477 ALC660_FIXUP_ASUS_W7J,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006478};
6479
Takashi Iwai31150f22012-01-30 10:54:08 +01006480/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
6481static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01006482 const struct hda_fixup *fix, int action)
Takashi Iwai31150f22012-01-30 10:54:08 +01006483{
6484 struct alc_spec *spec = codec->spec;
6485 unsigned int val;
6486
Takashi Iwai1727a772013-01-10 09:52:52 +01006487 if (action != HDA_FIXUP_ACT_INIT)
Takashi Iwai31150f22012-01-30 10:54:08 +01006488 return;
Takashi Iwaid3f02d62013-01-10 10:12:22 +01006489 val = snd_hda_codec_get_pin_target(codec, 0x0f);
Takashi Iwai31150f22012-01-30 10:54:08 +01006490 if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
6491 val |= AC_PINCTL_IN_EN;
6492 val |= AC_PINCTL_VREF_50;
Takashi Iwaicdd03ce2012-04-20 12:34:50 +02006493 snd_hda_set_pin_ctl(codec, 0x0f, val);
Takashi Iwai08c189f2012-12-19 15:22:24 +01006494 spec->gen.keep_vref_in_automute = 1;
Takashi Iwai31150f22012-01-30 10:54:08 +01006495}
6496
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006497/* suppress the jack-detection */
6498static void alc_fixup_no_jack_detect(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01006499 const struct hda_fixup *fix, int action)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006500{
Takashi Iwai1727a772013-01-10 09:52:52 +01006501 if (action == HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006502 codec->no_jack_detect = 1;
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02006503}
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006504
Takashi Iwai1727a772013-01-10 09:52:52 +01006505static const struct hda_fixup alc861_fixups[] = {
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006506 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006507 .type = HDA_FIXUP_PINS,
6508 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006509 { 0x0b, 0x0221101f }, /* HP */
6510 { 0x0f, 0x90170310 }, /* speaker */
6511 { }
6512 }
6513 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006514 [ALC861_FIXUP_AMP_VREF_0F] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006515 .type = HDA_FIXUP_FUNC,
Takashi Iwai31150f22012-01-30 10:54:08 +01006516 .v.func = alc861_fixup_asus_amp_vref_0f,
Takashi Iwai3b25eb62012-01-25 09:55:46 +01006517 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006518 [ALC861_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006519 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006520 .v.func = alc_fixup_no_jack_detect,
6521 },
6522 [ALC861_FIXUP_ASUS_A6RP] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006523 .type = HDA_FIXUP_FUNC,
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006524 .v.func = alc861_fixup_asus_amp_vref_0f,
6525 .chained = true,
6526 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01006527 },
6528 [ALC660_FIXUP_ASUS_W7J] = {
6529 .type = HDA_FIXUP_VERBS,
6530 .v.verbs = (const struct hda_verb[]) {
6531 /* ASUS W7J needs a magic pin setup on unused NID 0x10
6532 * for enabling outputs
6533 */
6534 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6535 { }
6536 },
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006537 }
Takashi Iwai1d045db2011-07-07 18:23:21 +02006538};
6539
6540static const struct snd_pci_quirk alc861_fixup_tbl[] = {
Takashi Iwai6ddf0fd2013-11-29 12:47:34 +01006541 SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie7ca2372013-12-02 15:27:19 +01006542 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
Takashi Iwaie652f4c2012-02-13 11:56:25 +01006543 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
6544 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
6545 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
6546 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6547 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6548 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006549 {}
6550};
6551
6552/*
6553 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02006554static int patch_alc861(struct hda_codec *codec)
6555{
6556 struct alc_spec *spec;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006557 int err;
6558
Takashi Iwai3de95172012-05-07 18:03:15 +02006559 err = alc_alloc_spec(codec, 0x15);
6560 if (err < 0)
6561 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006562
Takashi Iwai3de95172012-05-07 18:03:15 +02006563 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01006564 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006565
Takashi Iwai225068a2015-05-29 10:42:14 +02006566#ifdef CONFIG_PM
6567 spec->power_hook = alc_power_eapd;
6568#endif
6569
Takashi Iwai1727a772013-01-10 09:52:52 +01006570 snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
6571 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006572
Takashi Iwaicb4e4822011-08-23 17:34:25 +02006573 /* automatic parse from the BIOS config */
6574 err = alc861_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006575 if (err < 0)
6576 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006577
Takashi Iwai7504b6c2013-03-18 11:25:51 +01006578 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006579 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006580
Takashi Iwai1727a772013-01-10 09:52:52 +01006581 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01006582
Takashi Iwai1d045db2011-07-07 18:23:21 +02006583 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006584
6585 error:
6586 alc_free(codec);
6587 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006588}
6589
6590/*
6591 * ALC861-VD support
6592 *
6593 * Based on ALC882
6594 *
6595 * In addition, an independent DAC
6596 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02006597static int alc861vd_parse_auto_config(struct hda_codec *codec)
6598{
Takashi Iwai1d045db2011-07-07 18:23:21 +02006599 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006600 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6601 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006602}
6603
Takashi Iwai1d045db2011-07-07 18:23:21 +02006604enum {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006605 ALC660VD_FIX_ASUS_GPIO1,
6606 ALC861VD_FIX_DALLAS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006607};
6608
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006609/* exclude VREF80 */
6610static void alc861vd_fixup_dallas(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01006611 const struct hda_fixup *fix, int action)
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006612{
Takashi Iwai1727a772013-01-10 09:52:52 +01006613 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwaib78562b2012-12-17 20:06:49 +01006614 snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
6615 snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006616 }
6617}
6618
Takashi Iwai1727a772013-01-10 09:52:52 +01006619static const struct hda_fixup alc861vd_fixups[] = {
Takashi Iwai1d045db2011-07-07 18:23:21 +02006620 [ALC660VD_FIX_ASUS_GPIO1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006621 .type = HDA_FIXUP_VERBS,
Takashi Iwai1d045db2011-07-07 18:23:21 +02006622 .v.verbs = (const struct hda_verb[]) {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006623 /* reset GPIO1 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02006624 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6625 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6626 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6627 { }
6628 }
6629 },
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006630 [ALC861VD_FIX_DALLAS] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006631 .type = HDA_FIXUP_FUNC,
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006632 .v.func = alc861vd_fixup_dallas,
6633 },
Takashi Iwai1d045db2011-07-07 18:23:21 +02006634};
6635
6636static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006637 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006638 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
Takashi Iwai8fdcb6f2011-08-23 17:28:55 +02006639 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
Takashi Iwai1d045db2011-07-07 18:23:21 +02006640 {}
6641};
6642
Takashi Iwai1d045db2011-07-07 18:23:21 +02006643/*
6644 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02006645static int patch_alc861vd(struct hda_codec *codec)
6646{
6647 struct alc_spec *spec;
Takashi Iwaicb4e4822011-08-23 17:34:25 +02006648 int err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006649
Takashi Iwai3de95172012-05-07 18:03:15 +02006650 err = alc_alloc_spec(codec, 0x0b);
6651 if (err < 0)
6652 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006653
Takashi Iwai3de95172012-05-07 18:03:15 +02006654 spec = codec->spec;
Takashi Iwai7504b6c2013-03-18 11:25:51 +01006655 spec->gen.beep_nid = 0x23;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006656
Takashi Iwai225068a2015-05-29 10:42:14 +02006657 spec->shutup = alc_eapd_shutup;
6658
Takashi Iwai1727a772013-01-10 09:52:52 +01006659 snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
6660 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006661
Takashi Iwaicb4e4822011-08-23 17:34:25 +02006662 /* automatic parse from the BIOS config */
6663 err = alc861vd_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006664 if (err < 0)
6665 goto error;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006666
Takashi Iwai7504b6c2013-03-18 11:25:51 +01006667 if (!spec->gen.no_analog)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006668 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
Takashi Iwai1d045db2011-07-07 18:23:21 +02006669
Takashi Iwai1727a772013-01-10 09:52:52 +01006670 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01006671
Takashi Iwai1d045db2011-07-07 18:23:21 +02006672 return 0;
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02006673
6674 error:
6675 alc_free(codec);
6676 return err;
Takashi Iwai1d045db2011-07-07 18:23:21 +02006677}
6678
6679/*
6680 * ALC662 support
6681 *
6682 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
6683 * configuration. Each pin widget can choose any input DACs and a mixer.
6684 * Each ADC is connected from a mixer of all inputs. This makes possible
6685 * 6-channel independent captures.
6686 *
6687 * In addition, an independent DAC for the multi-playback (not used in this
6688 * driver yet).
6689 */
Takashi Iwai1d045db2011-07-07 18:23:21 +02006690
6691/*
6692 * BIOS auto configuration
6693 */
6694
Kailang Yangbc9f98a2007-04-12 13:06:07 +02006695static int alc662_parse_auto_config(struct hda_codec *codec)
6696{
Takashi Iwai4c6d72d2011-05-02 11:30:18 +02006697 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006698 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
6699 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6700 const hda_nid_t *ssids;
Takashi Iwaiee979a142008-09-02 15:42:20 +02006701
Takashi Iwai7639a062015-03-03 10:07:24 +01006702 if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
6703 codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
6704 codec->core.vendor_id == 0x10ec0671)
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006705 ssids = alc663_ssids;
Kailang Yang6227cdc2010-02-25 08:36:52 +01006706 else
Takashi Iwai3e6179b2011-07-08 16:55:13 +02006707 ssids = alc662_ssids;
6708 return alc_parse_auto_config(codec, alc662_ignore, ssids);
Kailang Yangbc9f98a2007-04-12 13:06:07 +02006709}
6710
Todd Broch6be79482010-12-07 16:51:05 -08006711static void alc272_fixup_mario(struct hda_codec *codec,
Takashi Iwai1727a772013-01-10 09:52:52 +01006712 const struct hda_fixup *fix, int action)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01006713{
Takashi Iwai9bb1f062013-01-10 17:14:29 +01006714 if (action != HDA_FIXUP_ACT_PRE_PROBE)
Takashi Iwai6fc398c2011-01-13 14:36:37 +01006715 return;
Todd Broch6be79482010-12-07 16:51:05 -08006716 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
6717 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
6718 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
6719 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
6720 (0 << AC_AMPCAP_MUTE_SHIFT)))
Takashi Iwai4e76a882014-02-25 12:21:03 +01006721 codec_warn(codec, "failed to override amp caps for NID 0x2\n");
Todd Broch6be79482010-12-07 16:51:05 -08006722}
6723
Takashi Iwai8e383952013-10-30 17:41:12 +01006724static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
6725 { .channels = 2,
6726 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
6727 { .channels = 4,
6728 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
6729 SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
6730 { }
6731};
6732
6733/* override the 2.1 chmap */
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01006734static void alc_fixup_bass_chmap(struct hda_codec *codec,
Takashi Iwai8e383952013-10-30 17:41:12 +01006735 const struct hda_fixup *fix, int action)
6736{
6737 if (action == HDA_FIXUP_ACT_BUILD) {
6738 struct alc_spec *spec = codec->spec;
Takashi Iwaibbbc7e82015-02-27 17:43:19 +01006739 spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
Takashi Iwai8e383952013-10-30 17:41:12 +01006740 }
6741}
6742
Takashi Iwaibf686652014-01-13 16:18:25 +01006743/* avoid D3 for keeping GPIO up */
6744static unsigned int gpio_led_power_filter(struct hda_codec *codec,
6745 hda_nid_t nid,
6746 unsigned int power_state)
6747{
6748 struct alc_spec *spec = codec->spec;
Takashi Iwai7639a062015-03-03 10:07:24 +01006749 if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
Takashi Iwaibf686652014-01-13 16:18:25 +01006750 return AC_PWRST_D0;
6751 return power_state;
6752}
6753
Takashi Iwai3e887f32014-01-10 17:50:58 +01006754static void alc662_fixup_led_gpio1(struct hda_codec *codec,
6755 const struct hda_fixup *fix, int action)
6756{
6757 struct alc_spec *spec = codec->spec;
6758 static const struct hda_verb gpio_init[] = {
6759 { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
6760 { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
6761 {}
6762 };
6763
6764 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
Takashi Iwai0f32fd192014-11-19 12:16:14 +01006765 spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
Takashi Iwai3e887f32014-01-10 17:50:58 +01006766 spec->gpio_led = 0;
Takashi Iwai0f32fd192014-11-19 12:16:14 +01006767 spec->mute_led_polarity = 1;
6768 spec->gpio_mute_led_mask = 0x01;
Takashi Iwai3e887f32014-01-10 17:50:58 +01006769 snd_hda_add_verbs(codec, gpio_init);
Takashi Iwaibf686652014-01-13 16:18:25 +01006770 codec->power_filter = gpio_led_power_filter;
Takashi Iwai3e887f32014-01-10 17:50:58 +01006771 }
6772}
6773
Kailang Yangf3f91852014-10-24 15:43:46 +08006774static struct coef_fw alc668_coefs[] = {
6775 WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
6776 WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
6777 WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0),
6778 WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
6779 WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
6780 WRITE_COEF(0x13, 0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
6781 WRITE_COEF(0x19, 0x0), WRITE_COEF(0x1a, 0x0), WRITE_COEF(0x1b, 0x0),
6782 WRITE_COEF(0x1c, 0x0), WRITE_COEF(0x1d, 0x0), WRITE_COEF(0x1e, 0x7418),
6783 WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
6784 WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
6785 WRITE_COEF(0x27, 0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
6786 WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
6787 WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac, 0x0),
6788 WRITE_COEF(0xad, 0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
6789 WRITE_COEF(0xb0, 0x0), WRITE_COEF(0xb1, 0x0), WRITE_COEF(0xb2, 0x0),
6790 WRITE_COEF(0xb3, 0x0), WRITE_COEF(0xb4, 0x0), WRITE_COEF(0xb5, 0x1040),
6791 WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
6792 WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
6793 WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
6794 WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
6795 {}
6796};
6797
6798static void alc668_restore_default_value(struct hda_codec *codec)
6799{
6800 alc_process_coef_fw(codec, alc668_coefs);
6801}
6802
David Henningsson6cb3b702010-09-09 08:51:44 +02006803enum {
Daniel T Chen2df03512010-10-10 22:39:28 -04006804 ALC662_FIXUP_ASPIRE,
Takashi Iwai3e887f32014-01-10 17:50:58 +01006805 ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02006806 ALC662_FIXUP_IDEAPAD,
Todd Broch6be79482010-12-07 16:51:05 -08006807 ALC272_FIXUP_MARIO,
Anisse Astierd2ebd472011-01-20 12:36:21 +01006808 ALC662_FIXUP_CZC_P10T,
David Henningsson94024cd2011-04-29 14:10:55 +02006809 ALC662_FIXUP_SKU_IGNORE,
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02006810 ALC662_FIXUP_HP_RP5800,
Takashi Iwai53c334a2011-08-23 18:27:14 +02006811 ALC662_FIXUP_ASUS_MODE1,
6812 ALC662_FIXUP_ASUS_MODE2,
6813 ALC662_FIXUP_ASUS_MODE3,
6814 ALC662_FIXUP_ASUS_MODE4,
6815 ALC662_FIXUP_ASUS_MODE5,
6816 ALC662_FIXUP_ASUS_MODE6,
6817 ALC662_FIXUP_ASUS_MODE7,
6818 ALC662_FIXUP_ASUS_MODE8,
Takashi Iwai1565cc32012-02-13 12:03:25 +01006819 ALC662_FIXUP_NO_JACK_DETECT,
David Henningssonedfe3bf2012-06-12 13:15:12 +02006820 ALC662_FIXUP_ZOTAC_Z68,
Takashi Iwai125821a2012-06-22 14:30:29 +02006821 ALC662_FIXUP_INV_DMIC,
David Henningsson1f8b46c2015-05-12 14:38:15 +02006822 ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson73bdd592013-04-15 15:44:14 +02006823 ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02006824 ALC662_FIXUP_HEADSET_MODE,
David Henningsson73bdd592013-04-15 15:44:14 +02006825 ALC668_FIXUP_HEADSET_MODE,
David Henningsson8e54b4a2014-02-07 09:31:07 +01006826 ALC662_FIXUP_BASS_MODE4_CHMAP,
David Henningsson61a75f12014-02-07 09:31:08 +01006827 ALC662_FIXUP_BASS_16,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01006828 ALC662_FIXUP_BASS_1A,
David Henningsson8e54b4a2014-02-07 09:31:07 +01006829 ALC662_FIXUP_BASS_CHMAP,
Hui Wang493a52a2014-01-14 14:07:36 +08006830 ALC668_FIXUP_AUTO_MUTE,
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02006831 ALC668_FIXUP_DELL_DISABLE_AAMIX,
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02006832 ALC668_FIXUP_DELL_XPS13,
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02006833 ALC662_FIXUP_ASUS_Nx50,
Mikhail Paulyshka67dc18e2017-04-21 08:52:42 +02006834 ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07006835 ALC668_FIXUP_ASUS_Nx51,
Takashi Iwai3c091582018-10-09 14:20:17 +02006836 ALC668_FIXUP_MIC_COEF,
Takashi Iwai17f333b2018-10-07 09:44:17 +02006837 ALC668_FIXUP_ASUS_G751,
Kailang Yang78f4f7c2016-06-07 11:31:34 +08006838 ALC891_FIXUP_HEADSET_MODE,
6839 ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08006840 ALC662_FIXUP_ACER_VERITON,
Takashi Iwai1a3f0992016-10-20 12:14:51 +02006841 ALC892_FIXUP_ASROCK_MOBO,
David Henningsson6cb3b702010-09-09 08:51:44 +02006842};
6843
Takashi Iwai1727a772013-01-10 09:52:52 +01006844static const struct hda_fixup alc662_fixups[] = {
Daniel T Chen2df03512010-10-10 22:39:28 -04006845 [ALC662_FIXUP_ASPIRE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006846 .type = HDA_FIXUP_PINS,
6847 .v.pins = (const struct hda_pintbl[]) {
Daniel T Chen2df03512010-10-10 22:39:28 -04006848 { 0x15, 0x99130112 }, /* subwoofer */
6849 { }
6850 }
6851 },
Takashi Iwai3e887f32014-01-10 17:50:58 +01006852 [ALC662_FIXUP_LED_GPIO1] = {
6853 .type = HDA_FIXUP_FUNC,
6854 .v.func = alc662_fixup_led_gpio1,
6855 },
David Henningsson6cb3b702010-09-09 08:51:44 +02006856 [ALC662_FIXUP_IDEAPAD] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006857 .type = HDA_FIXUP_PINS,
6858 .v.pins = (const struct hda_pintbl[]) {
David Henningsson6cb3b702010-09-09 08:51:44 +02006859 { 0x17, 0x99130112 }, /* subwoofer */
6860 { }
Takashi Iwai3e887f32014-01-10 17:50:58 +01006861 },
6862 .chained = true,
6863 .chain_id = ALC662_FIXUP_LED_GPIO1,
David Henningsson6cb3b702010-09-09 08:51:44 +02006864 },
Todd Broch6be79482010-12-07 16:51:05 -08006865 [ALC272_FIXUP_MARIO] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006866 .type = HDA_FIXUP_FUNC,
Takashi Iwaib5bfbc62011-01-13 14:22:32 +01006867 .v.func = alc272_fixup_mario,
Anisse Astierd2ebd472011-01-20 12:36:21 +01006868 },
6869 [ALC662_FIXUP_CZC_P10T] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006870 .type = HDA_FIXUP_VERBS,
Anisse Astierd2ebd472011-01-20 12:36:21 +01006871 .v.verbs = (const struct hda_verb[]) {
6872 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6873 {}
6874 }
6875 },
David Henningsson94024cd2011-04-29 14:10:55 +02006876 [ALC662_FIXUP_SKU_IGNORE] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006877 .type = HDA_FIXUP_FUNC,
Takashi Iwai23d30f22012-05-07 17:17:32 +02006878 .v.func = alc_fixup_sku_ignore,
Takashi Iwaic6b35872011-03-28 12:05:31 +02006879 },
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02006880 [ALC662_FIXUP_HP_RP5800] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006881 .type = HDA_FIXUP_PINS,
6882 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02006883 { 0x14, 0x0221201f }, /* HP out */
6884 { }
6885 },
6886 .chained = true,
6887 .chain_id = ALC662_FIXUP_SKU_IGNORE
6888 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02006889 [ALC662_FIXUP_ASUS_MODE1] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006890 .type = HDA_FIXUP_PINS,
6891 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006892 { 0x14, 0x99130110 }, /* speaker */
6893 { 0x18, 0x01a19c20 }, /* mic */
6894 { 0x19, 0x99a3092f }, /* int-mic */
6895 { 0x21, 0x0121401f }, /* HP out */
6896 { }
6897 },
6898 .chained = true,
6899 .chain_id = ALC662_FIXUP_SKU_IGNORE
6900 },
6901 [ALC662_FIXUP_ASUS_MODE2] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006902 .type = HDA_FIXUP_PINS,
6903 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai2996bdb2011-08-18 16:02:24 +02006904 { 0x14, 0x99130110 }, /* speaker */
6905 { 0x18, 0x01a19820 }, /* mic */
6906 { 0x19, 0x99a3092f }, /* int-mic */
6907 { 0x1b, 0x0121401f }, /* HP out */
6908 { }
6909 },
Takashi Iwai53c334a2011-08-23 18:27:14 +02006910 .chained = true,
6911 .chain_id = ALC662_FIXUP_SKU_IGNORE
6912 },
6913 [ALC662_FIXUP_ASUS_MODE3] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006914 .type = HDA_FIXUP_PINS,
6915 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006916 { 0x14, 0x99130110 }, /* speaker */
6917 { 0x15, 0x0121441f }, /* HP */
6918 { 0x18, 0x01a19840 }, /* mic */
6919 { 0x19, 0x99a3094f }, /* int-mic */
6920 { 0x21, 0x01211420 }, /* HP2 */
6921 { }
6922 },
6923 .chained = true,
6924 .chain_id = ALC662_FIXUP_SKU_IGNORE
6925 },
6926 [ALC662_FIXUP_ASUS_MODE4] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006927 .type = HDA_FIXUP_PINS,
6928 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006929 { 0x14, 0x99130110 }, /* speaker */
6930 { 0x16, 0x99130111 }, /* speaker */
6931 { 0x18, 0x01a19840 }, /* mic */
6932 { 0x19, 0x99a3094f }, /* int-mic */
6933 { 0x21, 0x0121441f }, /* HP */
6934 { }
6935 },
6936 .chained = true,
6937 .chain_id = ALC662_FIXUP_SKU_IGNORE
6938 },
6939 [ALC662_FIXUP_ASUS_MODE5] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006940 .type = HDA_FIXUP_PINS,
6941 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006942 { 0x14, 0x99130110 }, /* speaker */
6943 { 0x15, 0x0121441f }, /* HP */
6944 { 0x16, 0x99130111 }, /* speaker */
6945 { 0x18, 0x01a19840 }, /* mic */
6946 { 0x19, 0x99a3094f }, /* int-mic */
6947 { }
6948 },
6949 .chained = true,
6950 .chain_id = ALC662_FIXUP_SKU_IGNORE
6951 },
6952 [ALC662_FIXUP_ASUS_MODE6] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006953 .type = HDA_FIXUP_PINS,
6954 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006955 { 0x14, 0x99130110 }, /* speaker */
6956 { 0x15, 0x01211420 }, /* HP2 */
6957 { 0x18, 0x01a19840 }, /* mic */
6958 { 0x19, 0x99a3094f }, /* int-mic */
6959 { 0x1b, 0x0121441f }, /* HP */
6960 { }
6961 },
6962 .chained = true,
6963 .chain_id = ALC662_FIXUP_SKU_IGNORE
6964 },
6965 [ALC662_FIXUP_ASUS_MODE7] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006966 .type = HDA_FIXUP_PINS,
6967 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006968 { 0x14, 0x99130110 }, /* speaker */
6969 { 0x17, 0x99130111 }, /* speaker */
6970 { 0x18, 0x01a19840 }, /* mic */
6971 { 0x19, 0x99a3094f }, /* int-mic */
6972 { 0x1b, 0x01214020 }, /* HP */
6973 { 0x21, 0x0121401f }, /* HP */
6974 { }
6975 },
6976 .chained = true,
6977 .chain_id = ALC662_FIXUP_SKU_IGNORE
6978 },
6979 [ALC662_FIXUP_ASUS_MODE8] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006980 .type = HDA_FIXUP_PINS,
6981 .v.pins = (const struct hda_pintbl[]) {
Takashi Iwai53c334a2011-08-23 18:27:14 +02006982 { 0x14, 0x99130110 }, /* speaker */
6983 { 0x12, 0x99a30970 }, /* int-mic */
6984 { 0x15, 0x01214020 }, /* HP */
6985 { 0x17, 0x99130111 }, /* speaker */
6986 { 0x18, 0x01a19840 }, /* mic */
6987 { 0x21, 0x0121401f }, /* HP */
6988 { }
6989 },
6990 .chained = true,
6991 .chain_id = ALC662_FIXUP_SKU_IGNORE
Takashi Iwai2996bdb2011-08-18 16:02:24 +02006992 },
Takashi Iwai1565cc32012-02-13 12:03:25 +01006993 [ALC662_FIXUP_NO_JACK_DETECT] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006994 .type = HDA_FIXUP_FUNC,
Takashi Iwai1565cc32012-02-13 12:03:25 +01006995 .v.func = alc_fixup_no_jack_detect,
6996 },
David Henningssonedfe3bf2012-06-12 13:15:12 +02006997 [ALC662_FIXUP_ZOTAC_Z68] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01006998 .type = HDA_FIXUP_PINS,
6999 .v.pins = (const struct hda_pintbl[]) {
David Henningssonedfe3bf2012-06-12 13:15:12 +02007000 { 0x1b, 0x02214020 }, /* Front HP */
7001 { }
7002 }
7003 },
Takashi Iwai125821a2012-06-22 14:30:29 +02007004 [ALC662_FIXUP_INV_DMIC] = {
Takashi Iwai1727a772013-01-10 09:52:52 +01007005 .type = HDA_FIXUP_FUNC,
David Henningsson9d36a7d2014-10-07 10:18:42 +02007006 .v.func = alc_fixup_inv_dmic,
Takashi Iwai125821a2012-06-22 14:30:29 +02007007 },
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007008 [ALC668_FIXUP_DELL_XPS13] = {
7009 .type = HDA_FIXUP_FUNC,
7010 .v.func = alc_fixup_dell_xps13,
7011 .chained = true,
7012 .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
7013 },
Gabriele Mazzotta5e6db662014-05-20 18:58:26 +02007014 [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
7015 .type = HDA_FIXUP_FUNC,
7016 .v.func = alc_fixup_disable_aamix,
7017 .chained = true,
7018 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7019 },
Hui Wang493a52a2014-01-14 14:07:36 +08007020 [ALC668_FIXUP_AUTO_MUTE] = {
7021 .type = HDA_FIXUP_FUNC,
7022 .v.func = alc_fixup_auto_mute_via_amp,
7023 .chained = true,
7024 .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
7025 },
David Henningsson1f8b46c2015-05-12 14:38:15 +02007026 [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
7027 .type = HDA_FIXUP_PINS,
7028 .v.pins = (const struct hda_pintbl[]) {
7029 { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7030 /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
7031 { }
7032 },
7033 .chained = true,
7034 .chain_id = ALC662_FIXUP_HEADSET_MODE
7035 },
7036 [ALC662_FIXUP_HEADSET_MODE] = {
7037 .type = HDA_FIXUP_FUNC,
7038 .v.func = alc_fixup_headset_mode_alc662,
7039 },
David Henningsson73bdd592013-04-15 15:44:14 +02007040 [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
7041 .type = HDA_FIXUP_PINS,
7042 .v.pins = (const struct hda_pintbl[]) {
7043 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7044 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7045 { }
7046 },
7047 .chained = true,
7048 .chain_id = ALC668_FIXUP_HEADSET_MODE
7049 },
7050 [ALC668_FIXUP_HEADSET_MODE] = {
7051 .type = HDA_FIXUP_FUNC,
7052 .v.func = alc_fixup_headset_mode_alc668,
7053 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007054 [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
Takashi Iwai8e383952013-10-30 17:41:12 +01007055 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007056 .v.func = alc_fixup_bass_chmap,
Takashi Iwai8e383952013-10-30 17:41:12 +01007057 .chained = true,
7058 .chain_id = ALC662_FIXUP_ASUS_MODE4
7059 },
David Henningsson61a75f12014-02-07 09:31:08 +01007060 [ALC662_FIXUP_BASS_16] = {
7061 .type = HDA_FIXUP_PINS,
7062 .v.pins = (const struct hda_pintbl[]) {
7063 {0x16, 0x80106111}, /* bass speaker */
7064 {}
7065 },
7066 .chained = true,
7067 .chain_id = ALC662_FIXUP_BASS_CHMAP,
7068 },
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007069 [ALC662_FIXUP_BASS_1A] = {
7070 .type = HDA_FIXUP_PINS,
7071 .v.pins = (const struct hda_pintbl[]) {
7072 {0x1a, 0x80106111}, /* bass speaker */
7073 {}
7074 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007075 .chained = true,
7076 .chain_id = ALC662_FIXUP_BASS_CHMAP,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007077 },
David Henningsson8e54b4a2014-02-07 09:31:07 +01007078 [ALC662_FIXUP_BASS_CHMAP] = {
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007079 .type = HDA_FIXUP_FUNC,
Takashi Iwaieb9ca3a2013-11-28 15:24:34 +01007080 .v.func = alc_fixup_bass_chmap,
Takashi Iwaia30c9aa2013-11-21 08:00:20 +01007081 },
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02007082 [ALC662_FIXUP_ASUS_Nx50] = {
7083 .type = HDA_FIXUP_FUNC,
7084 .v.func = alc_fixup_auto_mute_via_amp,
7085 .chained = true,
7086 .chain_id = ALC662_FIXUP_BASS_1A
7087 },
Mikhail Paulyshka67dc18e2017-04-21 08:52:42 +02007088 [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = {
7089 .type = HDA_FIXUP_FUNC,
7090 .v.func = alc_fixup_headset_mode_alc668,
7091 .chain_id = ALC662_FIXUP_BASS_CHMAP
7092 },
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007093 [ALC668_FIXUP_ASUS_Nx51] = {
7094 .type = HDA_FIXUP_PINS,
7095 .v.pins = (const struct hda_pintbl[]) {
Mikhail Paulyshka67dc18e2017-04-21 08:52:42 +02007096 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7097 { 0x1a, 0x90170151 }, /* bass speaker */
7098 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007099 {}
7100 },
7101 .chained = true,
Mikhail Paulyshka67dc18e2017-04-21 08:52:42 +02007102 .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE,
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007103 },
Takashi Iwai3c091582018-10-09 14:20:17 +02007104 [ALC668_FIXUP_MIC_COEF] = {
Takashi Iwai17f333b2018-10-07 09:44:17 +02007105 .type = HDA_FIXUP_VERBS,
7106 .v.verbs = (const struct hda_verb[]) {
7107 { 0x20, AC_VERB_SET_COEF_INDEX, 0xc3 },
7108 { 0x20, AC_VERB_SET_PROC_COEF, 0x4000 },
7109 {}
7110 },
7111 },
Takashi Iwai3c091582018-10-09 14:20:17 +02007112 [ALC668_FIXUP_ASUS_G751] = {
7113 .type = HDA_FIXUP_PINS,
7114 .v.pins = (const struct hda_pintbl[]) {
7115 { 0x16, 0x0421101f }, /* HP */
7116 {}
7117 },
7118 .chained = true,
7119 .chain_id = ALC668_FIXUP_MIC_COEF
7120 },
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007121 [ALC891_FIXUP_HEADSET_MODE] = {
7122 .type = HDA_FIXUP_FUNC,
7123 .v.func = alc_fixup_headset_mode,
7124 },
7125 [ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
7126 .type = HDA_FIXUP_PINS,
7127 .v.pins = (const struct hda_pintbl[]) {
7128 { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
7129 { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
7130 { }
7131 },
7132 .chained = true,
7133 .chain_id = ALC891_FIXUP_HEADSET_MODE
7134 },
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08007135 [ALC662_FIXUP_ACER_VERITON] = {
7136 .type = HDA_FIXUP_PINS,
7137 .v.pins = (const struct hda_pintbl[]) {
7138 { 0x15, 0x50170120 }, /* no internal speaker */
7139 { }
7140 }
7141 },
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007142 [ALC892_FIXUP_ASROCK_MOBO] = {
7143 .type = HDA_FIXUP_PINS,
7144 .v.pins = (const struct hda_pintbl[]) {
7145 { 0x15, 0x40f000f0 }, /* disabled */
7146 { 0x16, 0x40f000f0 }, /* disabled */
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007147 { }
7148 }
7149 },
David Henningsson6cb3b702010-09-09 08:51:44 +02007150};
7151
Takashi Iwaia9111322011-05-02 11:30:18 +02007152static const struct snd_pci_quirk alc662_fixup_tbl[] = {
Takashi Iwai53c334a2011-08-23 18:27:14 +02007153 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
Takashi Iwaid3d38352013-08-19 20:05:50 +02007154 SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
David Henningsson02f6ff92015-12-07 11:29:31 +01007155 SND_PCI_QUIRK(0x1025, 0x0241, "Packard Bell DOTS", ALC662_FIXUP_INV_DMIC),
David Henningssona6c47a82011-02-10 15:39:19 +01007156 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
David Henningsson94024cd2011-04-29 14:10:55 +02007157 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
Takashi Iwai125821a2012-06-22 14:30:29 +02007158 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
Takashi Iwai18019282013-08-16 08:17:05 +02007159 SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
Daniel T Chen2df03512010-10-10 22:39:28 -04007160 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
David Henningsson73bdd592013-04-15 15:44:14 +02007161 SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7162 SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaic5d019c2014-07-22 17:33:32 +02007163 SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
Gabriele Mazzotta033b0a72014-05-26 17:11:46 +02007164 SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
Niranjan Sivakumar467e1432015-09-05 18:20:35 +02007165 SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
David Henningsson09d20142013-11-20 11:43:30 +01007166 SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
David Henningssonad8ff992013-11-07 09:28:59 +01007167 SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang8dc9abb2014-04-16 15:53:12 +08007168 SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
7169 SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Kailang Yang6a98e342014-10-27 16:20:30 +08007170 SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
Takashi Iwaie59ea3e2011-06-29 17:21:00 +02007171 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
Kaho Ng2da2dc92016-05-09 00:27:49 +08007172 SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
Bobi Mihalca83a9efb2016-03-23 13:32:33 +02007173 SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwaidb8948e2016-01-18 09:17:30 +01007174 SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
Bobi Mihalca9d4dc582016-03-23 13:26:11 +02007175 SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
Takashi Iwai17f333b2018-10-07 09:44:17 +02007176 SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
David Henningsson8e54b4a2014-02-07 09:31:07 +01007177 SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
David Henningsson61a75f12014-02-07 09:31:08 +01007178 SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
Yura Pakhuchiy3231e202016-05-07 23:53:36 +07007179 SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
7180 SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
Takashi Iwai5b2c3ca2017-01-04 21:38:16 +01007181 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
David Henningsson61a75f12014-02-07 09:31:08 +01007182 SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
David Henningsson8e54b4a2014-02-07 09:31:07 +01007183 SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Takashi Iwai1565cc32012-02-13 12:03:25 +01007184 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
Takashi Iwai53c334a2011-08-23 18:27:14 +02007185 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
Daniel T Chena0e90ac2010-11-20 10:20:35 -05007186 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
Valentine Sinitsynd4118582010-10-01 22:24:08 +06007187 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
David Henningsson6cb3b702010-09-09 08:51:44 +02007188 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Takashi Iwai1a3f0992016-10-20 12:14:51 +02007189 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
David Henningssonedfe3bf2012-06-12 13:15:12 +02007190 SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
Shrirang Bagul9b51fe32016-08-01 13:16:17 +08007191 SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
Anisse Astierd2ebd472011-01-20 12:36:21 +01007192 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
Takashi Iwai53c334a2011-08-23 18:27:14 +02007193
7194#if 0
7195 /* Below is a quirk table taken from the old code.
7196 * Basically the device should work as is without the fixup table.
7197 * If BIOS doesn't give a proper info, enable the corresponding
7198 * fixup entry.
Jesper Juhl7d7eb9e2012-04-12 22:11:25 +02007199 */
Takashi Iwai53c334a2011-08-23 18:27:14 +02007200 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
7201 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
7202 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
7203 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
7204 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7205 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7206 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7207 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
7208 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
7209 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7210 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
7211 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
7212 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
7213 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
7214 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
7215 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7216 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
7217 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
7218 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7219 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
7220 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
7221 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7222 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
7223 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
7224 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
7225 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7226 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
7227 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
7228 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7229 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
7230 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7231 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7232 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
7233 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
7234 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
7235 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
7236 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
7237 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
7238 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
7239 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
7240 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
7241 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
7242 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7243 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
7244 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
7245 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
7246 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
7247 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
7248 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
7249 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
7250#endif
David Henningsson6cb3b702010-09-09 08:51:44 +02007251 {}
7252};
7253
Takashi Iwai1727a772013-01-10 09:52:52 +01007254static const struct hda_model_fixup alc662_fixup_models[] = {
Todd Broch6be79482010-12-07 16:51:05 -08007255 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
Takashi Iwai53c334a2011-08-23 18:27:14 +02007256 {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
7257 {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
7258 {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
7259 {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
7260 {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
7261 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
7262 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
7263 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
Takashi Iwai6e72aa52012-06-25 10:52:25 +02007264 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
David Henningssone32aa852013-06-17 11:04:02 +02007265 {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
Todd Broch6be79482010-12-07 16:51:05 -08007266 {}
7267};
David Henningsson6cb3b702010-09-09 08:51:44 +02007268
Hui Wang532895c2014-05-29 15:59:19 +08007269static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007270 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
7271 {0x17, 0x02211010},
7272 {0x18, 0x01a19030},
7273 {0x1a, 0x01813040},
7274 {0x21, 0x01014020}),
Hui Wang27359242019-07-16 15:21:34 +08007275 SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
7276 {0x16, 0x01813030},
7277 {0x17, 0x02211010},
7278 {0x18, 0x01a19040},
7279 {0x21, 0x01014020}),
David Henningsson1f8b46c2015-05-12 14:38:15 +02007280 SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
David Henningsson1f8b46c2015-05-12 14:38:15 +02007281 {0x14, 0x01014010},
David Henningsson1f8b46c2015-05-12 14:38:15 +02007282 {0x18, 0x01a19020},
David Henningsson1f8b46c2015-05-12 14:38:15 +02007283 {0x1a, 0x0181302f},
Hui Wang11580292015-08-03 11:03:49 +08007284 {0x1b, 0x0221401f}),
David Henningsson76c21322014-06-24 14:46:54 +02007285 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7286 {0x12, 0x99a30130},
7287 {0x14, 0x90170110},
7288 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08007289 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02007290 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7291 {0x12, 0x99a30140},
7292 {0x14, 0x90170110},
7293 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08007294 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02007295 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
7296 {0x12, 0x99a30150},
7297 {0x14, 0x90170110},
7298 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08007299 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02007300 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
David Henningsson76c21322014-06-24 14:46:54 +02007301 {0x14, 0x90170110},
7302 {0x15, 0x0321101f},
Hui Wang11580292015-08-03 11:03:49 +08007303 {0x16, 0x03011020}),
David Henningsson76c21322014-06-24 14:46:54 +02007304 SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
7305 {0x12, 0x90a60130},
7306 {0x14, 0x90170110},
Hui Wang11580292015-08-03 11:03:49 +08007307 {0x15, 0x0321101f}),
Hui Wang532895c2014-05-29 15:59:19 +08007308 {}
7309};
7310
Takashi Iwai1d045db2011-07-07 18:23:21 +02007311/*
7312 */
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007313static int patch_alc662(struct hda_codec *codec)
7314{
7315 struct alc_spec *spec;
Takashi Iwai3de95172012-05-07 18:03:15 +02007316 int err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007317
Takashi Iwai3de95172012-05-07 18:03:15 +02007318 err = alc_alloc_spec(codec, 0x0b);
7319 if (err < 0)
7320 return err;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007321
Takashi Iwai3de95172012-05-07 18:03:15 +02007322 spec = codec->spec;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02007323
Takashi Iwai225068a2015-05-29 10:42:14 +02007324 spec->shutup = alc_eapd_shutup;
7325
Takashi Iwai53c334a2011-08-23 18:27:14 +02007326 /* handle multiple HPs as is */
7327 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
7328
Takashi Iwai2c3bf9a2008-06-04 12:39:38 +02007329 alc_fix_pll_init(codec, 0x20, 0x04, 15);
7330
Takashi Iwai7639a062015-03-03 10:07:24 +01007331 switch (codec->core.vendor_id) {
Kailang Yangf3f91852014-10-24 15:43:46 +08007332 case 0x10ec0668:
7333 spec->init_hook = alc668_restore_default_value;
7334 break;
Kailang Yangf3f91852014-10-24 15:43:46 +08007335 }
Kailang Yang8663ff72012-06-29 09:35:52 +02007336
Takashi Iwai1727a772013-01-10 09:52:52 +01007337 snd_hda_pick_fixup(codec, alc662_fixup_models,
Takashi Iwai8e5a0502012-06-21 15:49:33 +02007338 alc662_fixup_tbl, alc662_fixups);
Hui Wang532895c2014-05-29 15:59:19 +08007339 snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
Takashi Iwai1727a772013-01-10 09:52:52 +01007340 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
Takashi Iwai8e5a0502012-06-21 15:49:33 +02007341
7342 alc_auto_parse_customize_define(codec);
7343
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007344 if (has_cdefine_beep(codec))
7345 spec->gen.beep_nid = 0x01;
7346
Takashi Iwai1bb7e432011-10-17 16:50:59 +02007347 if ((alc_get_coef0(codec) & (1 << 14)) &&
Takashi Iwai5100cd02014-02-15 10:03:19 +01007348 codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007349 spec->cdefine.platform_type == 1) {
Wei Yongjun6134b1a2013-04-18 11:12:59 +08007350 err = alc_codec_rename(codec, "ALC272X");
7351 if (err < 0)
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007352 goto error;
Takashi Iwai20ca0c32011-10-17 16:00:35 +02007353 }
Kailang Yang274693f2009-12-03 10:07:50 +01007354
Takashi Iwaib9c51062011-08-24 18:08:07 +02007355 /* automatic parse from the BIOS config */
7356 err = alc662_parse_auto_config(codec);
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007357 if (err < 0)
7358 goto error;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007359
Takashi Iwai7504b6c2013-03-18 11:25:51 +01007360 if (!spec->gen.no_analog && spec->gen.beep_nid) {
Takashi Iwai7639a062015-03-03 10:07:24 +01007361 switch (codec->core.vendor_id) {
Kailang Yangda00c242010-03-19 11:23:45 +01007362 case 0x10ec0662:
7363 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7364 break;
7365 case 0x10ec0272:
7366 case 0x10ec0663:
7367 case 0x10ec0665:
Kailang Yang9ad54542013-11-26 15:41:40 +08007368 case 0x10ec0668:
Kailang Yangda00c242010-03-19 11:23:45 +01007369 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
7370 break;
7371 case 0x10ec0273:
7372 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
7373 break;
7374 }
Kailang Yangcec27c82010-02-04 14:18:18 +01007375 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01007376
Takashi Iwai1727a772013-01-10 09:52:52 +01007377 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
Takashi Iwai589876e2012-02-20 15:47:55 +01007378
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007379 return 0;
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007380
Takashi Iwaie16fb6d2011-10-17 16:39:09 +02007381 error:
7382 alc_free(codec);
7383 return err;
Kailang Yangb478b992011-05-18 11:51:15 +02007384}
7385
Kailang Yangbc9f98a2007-04-12 13:06:07 +02007386/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007387 * ALC680 support
7388 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007389
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007390static int alc680_parse_auto_config(struct hda_codec *codec)
7391{
Takashi Iwai3e6179b2011-07-08 16:55:13 +02007392 return alc_parse_auto_config(codec, NULL, NULL);
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007393}
7394
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007395/*
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007396 */
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007397static int patch_alc680(struct hda_codec *codec)
7398{
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007399 int err;
7400
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02007401 /* ALC680 has no aa-loopback mixer */
Takashi Iwai3de95172012-05-07 18:03:15 +02007402 err = alc_alloc_spec(codec, 0);
7403 if (err < 0)
7404 return err;
Takashi Iwai1f0f4b82011-06-27 10:52:59 +02007405
Takashi Iwai1ebec5f2011-08-15 13:21:48 +02007406 /* automatic parse from the BIOS config */
7407 err = alc680_parse_auto_config(codec);
7408 if (err < 0) {
7409 alc_free(codec);
7410 return err;
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007411 }
7412
Kailang Yangd1eb57f2010-06-23 16:25:26 +02007413 return 0;
7414}
7415
7416/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07007417 * patch entries
7418 */
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007419static const struct hda_device_id snd_hda_id_realtek[] = {
7420 HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
Kailang Yang42314302016-02-03 15:03:50 +08007421 HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007422 HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
7423 HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007424 HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007425 HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
Kailang Yang61ae3fb2017-10-20 15:06:34 +08007426 HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007427 HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
7428 HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
Kailang Yang2435d6b2017-12-05 15:38:24 +08007429 HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007430 HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
7431 HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
7432 HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
7433 HDA_CODEC_ENTRY(0x10ec0268, "ALC268", patch_alc268),
7434 HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
7435 HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
7436 HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007437 HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007438 HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
7439 HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
7440 HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
7441 HDA_CODEC_ENTRY(0x10ec0282, "ALC282", patch_alc269),
7442 HDA_CODEC_ENTRY(0x10ec0283, "ALC283", patch_alc269),
7443 HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
7444 HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
7445 HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
7446 HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
7447 HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
7448 HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
7449 HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
Kailang Yangdcd4f0d2016-05-04 15:50:18 +08007450 HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
Kailang Yang7d727862016-05-24 16:46:07 +08007451 HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007452 HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
Kailang Yangf6e94c22017-01-04 14:49:07 +08007453 HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007454 HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
7455 HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
7456 HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),
7457 HDA_CODEC_ENTRY(0x10ec0862, "ALC861-VD", patch_alc861vd),
7458 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100002, "ALC662 rev2", patch_alc882),
7459 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100101, "ALC662 rev1", patch_alc662),
7460 HDA_CODEC_REV_ENTRY(0x10ec0662, 0x100300, "ALC662 rev3", patch_alc662),
7461 HDA_CODEC_ENTRY(0x10ec0663, "ALC663", patch_alc662),
7462 HDA_CODEC_ENTRY(0x10ec0665, "ALC665", patch_alc662),
7463 HDA_CODEC_ENTRY(0x10ec0667, "ALC667", patch_alc662),
7464 HDA_CODEC_ENTRY(0x10ec0668, "ALC668", patch_alc662),
7465 HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
7466 HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
7467 HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
Kailang Yang6fbae352016-05-30 16:44:20 +08007468 HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
7469 HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
7470 HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
Kailang Yang78f4f7c2016-06-07 11:31:34 +08007471 HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007472 HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
7473 HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
7474 HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
7475 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100101, "ALC889A", patch_alc882),
7476 HDA_CODEC_REV_ENTRY(0x10ec0885, 0x100103, "ALC889A", patch_alc882),
7477 HDA_CODEC_ENTRY(0x10ec0885, "ALC885", patch_alc882),
7478 HDA_CODEC_ENTRY(0x10ec0887, "ALC887", patch_alc882),
7479 HDA_CODEC_REV_ENTRY(0x10ec0888, 0x100101, "ALC1200", patch_alc882),
7480 HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
7481 HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
7482 HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
7483 HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
7484 HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
Linus Torvalds1da177e2005-04-16 15:20:36 -07007485 {} /* terminator */
7486};
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007487MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_realtek);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01007488
7489MODULE_LICENSE("GPL");
7490MODULE_DESCRIPTION("Realtek HD-audio codec");
7491
Takashi Iwaid8a766a2015-02-17 15:25:37 +01007492static struct hda_codec_driver realtek_driver = {
Takashi Iwaib9a94a92015-10-01 16:20:04 +02007493 .id = snd_hda_id_realtek,
Takashi Iwai1289e9e2008-11-27 15:47:11 +01007494};
7495
Takashi Iwaid8a766a2015-02-17 15:25:37 +01007496module_hda_codec_driver(realtek_driver);