xref: /linux/sound/hda/codecs/realtek/alc882.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 //
3 // Realtek ALC882/883/885/888/889 codec support
4 //
5 // ALC882 is almost identical with ALC880 but has cleaner and more flexible
6 // configuration.  Each pin widget can choose any input DACs and a mixer.
7 // Each ADC is connected from a mixer of all inputs.  This makes possible
8 // 6-channel independent captures.
9 //
10 // In addition, an independent DAC for the multi-playback (not used in this
11 // driver yet).
12 //
13 
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include "realtek.h"
17 
18 /*
19  * Pin config fixes
20  */
21 enum {
22 	ALC882_FIXUP_ABIT_AW9D_MAX,
23 	ALC882_FIXUP_LENOVO_Y530,
24 	ALC882_FIXUP_PB_M5210,
25 	ALC882_FIXUP_ACER_ASPIRE_7736,
26 	ALC882_FIXUP_ASUS_W90V,
27 	ALC889_FIXUP_CD,
28 	ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
29 	ALC889_FIXUP_VAIO_TT,
30 	ALC888_FIXUP_EEE1601,
31 	ALC886_FIXUP_EAPD,
32 	ALC882_FIXUP_EAPD,
33 	ALC883_FIXUP_EAPD,
34 	ALC883_FIXUP_ACER_EAPD,
35 	ALC882_FIXUP_GPIO1,
36 	ALC882_FIXUP_GPIO2,
37 	ALC882_FIXUP_GPIO3,
38 	ALC889_FIXUP_COEF,
39 	ALC882_FIXUP_ASUS_W2JC,
40 	ALC882_FIXUP_ACER_ASPIRE_4930G,
41 	ALC882_FIXUP_ACER_ASPIRE_8930G,
42 	ALC882_FIXUP_ASPIRE_8930G_VERBS,
43 	ALC885_FIXUP_MACPRO_GPIO,
44 	ALC889_FIXUP_DAC_ROUTE,
45 	ALC889_FIXUP_MBP_VREF,
46 	ALC889_FIXUP_IMAC91_VREF,
47 	ALC889_FIXUP_MBA11_VREF,
48 	ALC889_FIXUP_MBA21_VREF,
49 	ALC889_FIXUP_MP11_VREF,
50 	ALC889_FIXUP_MP41_VREF,
51 	ALC882_FIXUP_INV_DMIC,
52 	ALC882_FIXUP_NO_PRIMARY_HP,
53 	ALC887_FIXUP_ASUS_BASS,
54 	ALC887_FIXUP_BASS_CHMAP,
55 	ALC1220_FIXUP_GB_DUAL_CODECS,
56 	ALC1220_FIXUP_GB_X570,
57 	ALC1220_FIXUP_CLEVO_P950,
58 	ALC1220_FIXUP_CLEVO_PB51ED,
59 	ALC1220_FIXUP_CLEVO_PB51ED_PINS,
60 	ALC887_FIXUP_ASUS_AUDIO,
61 	ALC887_FIXUP_ASUS_HMIC,
62 	ALCS1200A_FIXUP_MIC_VREF,
63 	ALC888VD_FIXUP_MIC_100VREF,
64 	ALC898_FIXUP_CLEVO_P775TM1,
65 };
66 
67 static void alc889_fixup_coef(struct hda_codec *codec,
68 			      const struct hda_fixup *fix, int action)
69 {
70 	if (action != HDA_FIXUP_ACT_INIT)
71 		return;
72 	alc_update_coef_idx(codec, 7, 0, 0x2030);
73 }
74 
75 /* set up GPIO at initialization */
76 static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
77 				     const struct hda_fixup *fix, int action)
78 {
79 	struct alc_spec *spec = codec->spec;
80 
81 	spec->gpio_write_delay = true;
82 	alc_fixup_gpio3(codec, fix, action);
83 }
84 
85 /* Fix the connection of some pins for ALC889:
86  * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
87  * work correctly (bko#42740)
88  */
89 static void alc889_fixup_dac_route(struct hda_codec *codec,
90 				   const struct hda_fixup *fix, int action)
91 {
92 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
93 		/* fake the connections during parsing the tree */
94 		static const hda_nid_t conn1[] = { 0x0c, 0x0d };
95 		static const hda_nid_t conn2[] = { 0x0e, 0x0f };
96 		snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
97 		snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn1), conn1);
98 		snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn2), conn2);
99 		snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn2), conn2);
100 	} else if (action == HDA_FIXUP_ACT_PROBE) {
101 		/* restore the connections */
102 		static const hda_nid_t conn[] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
103 		snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn);
104 		snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
105 		snd_hda_override_conn_list(codec, 0x18, ARRAY_SIZE(conn), conn);
106 		snd_hda_override_conn_list(codec, 0x1a, ARRAY_SIZE(conn), conn);
107 	}
108 }
109 
110 /* Set VREF on HP pin */
111 static void alc889_fixup_mbp_vref(struct hda_codec *codec,
112 				  const struct hda_fixup *fix, int action)
113 {
114 	static const hda_nid_t nids[] = { 0x14, 0x15, 0x19 };
115 	struct alc_spec *spec = codec->spec;
116 	int i;
117 
118 	if (action != HDA_FIXUP_ACT_INIT)
119 		return;
120 	for (i = 0; i < ARRAY_SIZE(nids); i++) {
121 		unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
122 		if (get_defcfg_device(val) != AC_JACK_HP_OUT)
123 			continue;
124 		val = snd_hda_codec_get_pin_target(codec, nids[i]);
125 		val |= AC_PINCTL_VREF_80;
126 		snd_hda_set_pin_ctl(codec, nids[i], val);
127 		spec->gen.keep_vref_in_automute = 1;
128 		break;
129 	}
130 }
131 
132 static void alc889_fixup_mac_pins(struct hda_codec *codec,
133 				  const hda_nid_t *nids, int num_nids)
134 {
135 	struct alc_spec *spec = codec->spec;
136 	int i;
137 
138 	for (i = 0; i < num_nids; i++) {
139 		unsigned int val;
140 		val = snd_hda_codec_get_pin_target(codec, nids[i]);
141 		val |= AC_PINCTL_VREF_50;
142 		snd_hda_set_pin_ctl(codec, nids[i], val);
143 	}
144 	spec->gen.keep_vref_in_automute = 1;
145 }
146 
147 /* Set VREF on speaker pins on imac91 */
148 static void alc889_fixup_imac91_vref(struct hda_codec *codec,
149 				     const struct hda_fixup *fix, int action)
150 {
151 	static const hda_nid_t nids[] = { 0x18, 0x1a };
152 
153 	if (action == HDA_FIXUP_ACT_INIT)
154 		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
155 }
156 
157 /* Set VREF on speaker pins on mba11 */
158 static void alc889_fixup_mba11_vref(struct hda_codec *codec,
159 				    const struct hda_fixup *fix, int action)
160 {
161 	static const hda_nid_t nids[] = { 0x18 };
162 
163 	if (action == HDA_FIXUP_ACT_INIT)
164 		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
165 }
166 
167 /* Set VREF on speaker pins on mba21 */
168 static void alc889_fixup_mba21_vref(struct hda_codec *codec,
169 				    const struct hda_fixup *fix, int action)
170 {
171 	static const hda_nid_t nids[] = { 0x18, 0x19 };
172 
173 	if (action == HDA_FIXUP_ACT_INIT)
174 		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
175 }
176 
177 /* Don't take HP output as primary
178  * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
179  * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
180  */
181 static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
182 				       const struct hda_fixup *fix, int action)
183 {
184 	struct alc_spec *spec = codec->spec;
185 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
186 		spec->gen.no_primary_hp = 1;
187 		spec->gen.no_multi_io = 1;
188 	}
189 }
190 
191 static void alc1220_fixup_gb_x570(struct hda_codec *codec,
192 				     const struct hda_fixup *fix,
193 				     int action)
194 {
195 	static const hda_nid_t conn1[] = { 0x0c };
196 	static const struct coef_fw gb_x570_coefs[] = {
197 		WRITE_COEF(0x07, 0x03c0),
198 		WRITE_COEF(0x1a, 0x01c1),
199 		WRITE_COEF(0x1b, 0x0202),
200 		WRITE_COEF(0x43, 0x3005),
201 		{}
202 	};
203 
204 	switch (action) {
205 	case HDA_FIXUP_ACT_PRE_PROBE:
206 		snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
207 		snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
208 		break;
209 	case HDA_FIXUP_ACT_INIT:
210 		alc_process_coef_fw(codec, gb_x570_coefs);
211 		break;
212 	}
213 }
214 
215 static void alc1220_fixup_clevo_p950(struct hda_codec *codec,
216 				     const struct hda_fixup *fix,
217 				     int action)
218 {
219 	static const hda_nid_t conn1[] = { 0x0c };
220 
221 	if (action != HDA_FIXUP_ACT_PRE_PROBE)
222 		return;
223 
224 	alc_update_coef_idx(codec, 0x7, 0, 0x3c3);
225 	/* We therefore want to make sure 0x14 (front headphone) and
226 	 * 0x1b (speakers) use the stereo DAC 0x02
227 	 */
228 	snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn1), conn1);
229 	snd_hda_override_conn_list(codec, 0x1b, ARRAY_SIZE(conn1), conn1);
230 }
231 
232 static void alc1220_fixup_clevo_pb51ed(struct hda_codec *codec,
233 				     const struct hda_fixup *fix,
234 				     int action)
235 {
236 	alc1220_fixup_clevo_p950(codec, fix, action);
237 	alc_fixup_headset_mode_no_hp_mic(codec, fix, action);
238 }
239 
240 /* On Clevo P775TM1, VREF of pin 0x1b enables the external headphone amp */
241 static void alc898_fixup_clevo_p775tm1(struct hda_codec *codec,
242 				       const struct hda_fixup *fix, int action)
243 {
244 	struct alc_spec *spec = codec->spec;
245 
246 	if (action != HDA_FIXUP_ACT_PRE_PROBE)
247 		return;
248 
249 	snd_hda_set_pin_ctl_cache(codec, 0x1b, PIN_VREF80);
250 	spec->gen.keep_vref_in_automute = 1;
251 }
252 
253 static void alc887_asus_hp_automute_hook(struct hda_codec *codec,
254 					 struct hda_jack_callback *jack)
255 {
256 	struct alc_spec *spec = codec->spec;
257 	unsigned int vref;
258 
259 	snd_hda_gen_hp_automute(codec, jack);
260 
261 	if (spec->gen.hp_jack_present)
262 		vref = AC_PINCTL_VREF_80;
263 	else
264 		vref = AC_PINCTL_VREF_HIZ;
265 	snd_hda_set_pin_ctl(codec, 0x19, PIN_HP | vref);
266 }
267 
268 static void alc887_fixup_asus_jack(struct hda_codec *codec,
269 				     const struct hda_fixup *fix, int action)
270 {
271 	struct alc_spec *spec = codec->spec;
272 	if (action != HDA_FIXUP_ACT_PROBE)
273 		return;
274 	snd_hda_set_pin_ctl_cache(codec, 0x1b, PIN_HP);
275 	spec->gen.hp_automute_hook = alc887_asus_hp_automute_hook;
276 }
277 
278 static const struct hda_fixup alc882_fixups[] = {
279 	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
280 		.type = HDA_FIXUP_PINS,
281 		.v.pins = (const struct hda_pintbl[]) {
282 			{ 0x15, 0x01080104 }, /* side */
283 			{ 0x16, 0x01011012 }, /* rear */
284 			{ 0x17, 0x01016011 }, /* clfe */
285 			{ }
286 		}
287 	},
288 	[ALC882_FIXUP_LENOVO_Y530] = {
289 		.type = HDA_FIXUP_PINS,
290 		.v.pins = (const struct hda_pintbl[]) {
291 			{ 0x15, 0x99130112 }, /* rear int speakers */
292 			{ 0x16, 0x99130111 }, /* subwoofer */
293 			{ }
294 		}
295 	},
296 	[ALC882_FIXUP_PB_M5210] = {
297 		.type = HDA_FIXUP_PINCTLS,
298 		.v.pins = (const struct hda_pintbl[]) {
299 			{ 0x19, PIN_VREF50 },
300 			{}
301 		}
302 	},
303 	[ALC882_FIXUP_ACER_ASPIRE_7736] = {
304 		.type = HDA_FIXUP_FUNC,
305 		.v.func = alc_fixup_sku_ignore,
306 	},
307 	[ALC882_FIXUP_ASUS_W90V] = {
308 		.type = HDA_FIXUP_PINS,
309 		.v.pins = (const struct hda_pintbl[]) {
310 			{ 0x16, 0x99130110 }, /* fix sequence for CLFE */
311 			{ }
312 		}
313 	},
314 	[ALC889_FIXUP_CD] = {
315 		.type = HDA_FIXUP_PINS,
316 		.v.pins = (const struct hda_pintbl[]) {
317 			{ 0x1c, 0x993301f0 }, /* CD */
318 			{ }
319 		}
320 	},
321 	[ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
322 		.type = HDA_FIXUP_PINS,
323 		.v.pins = (const struct hda_pintbl[]) {
324 			{ 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
325 			{ }
326 		},
327 		.chained = true,
328 		.chain_id = ALC889_FIXUP_CD,
329 	},
330 	[ALC889_FIXUP_VAIO_TT] = {
331 		.type = HDA_FIXUP_PINS,
332 		.v.pins = (const struct hda_pintbl[]) {
333 			{ 0x17, 0x90170111 }, /* hidden surround speaker */
334 			{ }
335 		}
336 	},
337 	[ALC888_FIXUP_EEE1601] = {
338 		.type = HDA_FIXUP_VERBS,
339 		.v.verbs = (const struct hda_verb[]) {
340 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
341 			{ 0x20, AC_VERB_SET_PROC_COEF,  0x0838 },
342 			{ }
343 		}
344 	},
345 	[ALC886_FIXUP_EAPD] = {
346 		.type = HDA_FIXUP_VERBS,
347 		.v.verbs = (const struct hda_verb[]) {
348 			/* change to EAPD mode */
349 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
350 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0068 },
351 			{ }
352 		}
353 	},
354 	[ALC882_FIXUP_EAPD] = {
355 		.type = HDA_FIXUP_VERBS,
356 		.v.verbs = (const struct hda_verb[]) {
357 			/* change to EAPD mode */
358 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
359 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
360 			{ }
361 		}
362 	},
363 	[ALC883_FIXUP_EAPD] = {
364 		.type = HDA_FIXUP_VERBS,
365 		.v.verbs = (const struct hda_verb[]) {
366 			/* change to EAPD mode */
367 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
368 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
369 			{ }
370 		}
371 	},
372 	[ALC883_FIXUP_ACER_EAPD] = {
373 		.type = HDA_FIXUP_VERBS,
374 		.v.verbs = (const struct hda_verb[]) {
375 			/* eanable EAPD on Acer laptops */
376 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
377 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
378 			{ }
379 		}
380 	},
381 	[ALC882_FIXUP_GPIO1] = {
382 		.type = HDA_FIXUP_FUNC,
383 		.v.func = alc_fixup_gpio1,
384 	},
385 	[ALC882_FIXUP_GPIO2] = {
386 		.type = HDA_FIXUP_FUNC,
387 		.v.func = alc_fixup_gpio2,
388 	},
389 	[ALC882_FIXUP_GPIO3] = {
390 		.type = HDA_FIXUP_FUNC,
391 		.v.func = alc_fixup_gpio3,
392 	},
393 	[ALC882_FIXUP_ASUS_W2JC] = {
394 		.type = HDA_FIXUP_FUNC,
395 		.v.func = alc_fixup_gpio1,
396 		.chained = true,
397 		.chain_id = ALC882_FIXUP_EAPD,
398 	},
399 	[ALC889_FIXUP_COEF] = {
400 		.type = HDA_FIXUP_FUNC,
401 		.v.func = alc889_fixup_coef,
402 	},
403 	[ALC882_FIXUP_ACER_ASPIRE_4930G] = {
404 		.type = HDA_FIXUP_PINS,
405 		.v.pins = (const struct hda_pintbl[]) {
406 			{ 0x16, 0x99130111 }, /* CLFE speaker */
407 			{ 0x17, 0x99130112 }, /* surround speaker */
408 			{ }
409 		},
410 		.chained = true,
411 		.chain_id = ALC882_FIXUP_GPIO1,
412 	},
413 	[ALC882_FIXUP_ACER_ASPIRE_8930G] = {
414 		.type = HDA_FIXUP_PINS,
415 		.v.pins = (const struct hda_pintbl[]) {
416 			{ 0x16, 0x99130111 }, /* CLFE speaker */
417 			{ 0x1b, 0x99130112 }, /* surround speaker */
418 			{ }
419 		},
420 		.chained = true,
421 		.chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
422 	},
423 	[ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
424 		/* additional init verbs for Acer Aspire 8930G */
425 		.type = HDA_FIXUP_VERBS,
426 		.v.verbs = (const struct hda_verb[]) {
427 			/* Enable all DACs */
428 			/* DAC DISABLE/MUTE 1? */
429 			/*  setting bits 1-5 disables DAC nids 0x02-0x06
430 			 *  apparently. Init=0x38 */
431 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
432 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
433 			/* DAC DISABLE/MUTE 2? */
434 			/*  some bit here disables the other DACs.
435 			 *  Init=0x4900 */
436 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
437 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
438 			/* DMIC fix
439 			 * This laptop has a stereo digital microphone.
440 			 * The mics are only 1cm apart which makes the stereo
441 			 * useless. However, either the mic or the ALC889
442 			 * makes the signal become a difference/sum signal
443 			 * instead of standard stereo, which is annoying.
444 			 * So instead we flip this bit which makes the
445 			 * codec replicate the sum signal to both channels,
446 			 * turning it into a normal mono mic.
447 			 */
448 			/* DMIC_CONTROL? Init value = 0x0001 */
449 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
450 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
451 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
452 			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
453 			{ }
454 		},
455 		.chained = true,
456 		.chain_id = ALC882_FIXUP_GPIO1,
457 	},
458 	[ALC885_FIXUP_MACPRO_GPIO] = {
459 		.type = HDA_FIXUP_FUNC,
460 		.v.func = alc885_fixup_macpro_gpio,
461 	},
462 	[ALC889_FIXUP_DAC_ROUTE] = {
463 		.type = HDA_FIXUP_FUNC,
464 		.v.func = alc889_fixup_dac_route,
465 	},
466 	[ALC889_FIXUP_MBP_VREF] = {
467 		.type = HDA_FIXUP_FUNC,
468 		.v.func = alc889_fixup_mbp_vref,
469 		.chained = true,
470 		.chain_id = ALC882_FIXUP_GPIO1,
471 	},
472 	[ALC889_FIXUP_IMAC91_VREF] = {
473 		.type = HDA_FIXUP_FUNC,
474 		.v.func = alc889_fixup_imac91_vref,
475 		.chained = true,
476 		.chain_id = ALC882_FIXUP_GPIO1,
477 	},
478 	[ALC889_FIXUP_MBA11_VREF] = {
479 		.type = HDA_FIXUP_FUNC,
480 		.v.func = alc889_fixup_mba11_vref,
481 		.chained = true,
482 		.chain_id = ALC889_FIXUP_MBP_VREF,
483 	},
484 	[ALC889_FIXUP_MBA21_VREF] = {
485 		.type = HDA_FIXUP_FUNC,
486 		.v.func = alc889_fixup_mba21_vref,
487 		.chained = true,
488 		.chain_id = ALC889_FIXUP_MBP_VREF,
489 	},
490 	[ALC889_FIXUP_MP11_VREF] = {
491 		.type = HDA_FIXUP_FUNC,
492 		.v.func = alc889_fixup_mba11_vref,
493 		.chained = true,
494 		.chain_id = ALC885_FIXUP_MACPRO_GPIO,
495 	},
496 	[ALC889_FIXUP_MP41_VREF] = {
497 		.type = HDA_FIXUP_FUNC,
498 		.v.func = alc889_fixup_mbp_vref,
499 		.chained = true,
500 		.chain_id = ALC885_FIXUP_MACPRO_GPIO,
501 	},
502 	[ALC882_FIXUP_INV_DMIC] = {
503 		.type = HDA_FIXUP_FUNC,
504 		.v.func = alc_fixup_inv_dmic,
505 	},
506 	[ALC882_FIXUP_NO_PRIMARY_HP] = {
507 		.type = HDA_FIXUP_FUNC,
508 		.v.func = alc882_fixup_no_primary_hp,
509 	},
510 	[ALC887_FIXUP_ASUS_BASS] = {
511 		.type = HDA_FIXUP_PINS,
512 		.v.pins = (const struct hda_pintbl[]) {
513 			{0x16, 0x99130130}, /* bass speaker */
514 			{}
515 		},
516 		.chained = true,
517 		.chain_id = ALC887_FIXUP_BASS_CHMAP,
518 	},
519 	[ALC887_FIXUP_BASS_CHMAP] = {
520 		.type = HDA_FIXUP_FUNC,
521 		.v.func = alc_fixup_bass_chmap,
522 	},
523 	[ALC1220_FIXUP_GB_DUAL_CODECS] = {
524 		.type = HDA_FIXUP_FUNC,
525 		.v.func = alc1220_fixup_gb_dual_codecs,
526 	},
527 	[ALC1220_FIXUP_GB_X570] = {
528 		.type = HDA_FIXUP_FUNC,
529 		.v.func = alc1220_fixup_gb_x570,
530 	},
531 	[ALC1220_FIXUP_CLEVO_P950] = {
532 		.type = HDA_FIXUP_FUNC,
533 		.v.func = alc1220_fixup_clevo_p950,
534 	},
535 	[ALC1220_FIXUP_CLEVO_PB51ED] = {
536 		.type = HDA_FIXUP_FUNC,
537 		.v.func = alc1220_fixup_clevo_pb51ed,
538 	},
539 	[ALC1220_FIXUP_CLEVO_PB51ED_PINS] = {
540 		.type = HDA_FIXUP_PINS,
541 		.v.pins = (const struct hda_pintbl[]) {
542 			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
543 			{}
544 		},
545 		.chained = true,
546 		.chain_id = ALC1220_FIXUP_CLEVO_PB51ED,
547 	},
548 	[ALC887_FIXUP_ASUS_AUDIO] = {
549 		.type = HDA_FIXUP_PINS,
550 		.v.pins = (const struct hda_pintbl[]) {
551 			{ 0x15, 0x02a14150 }, /* use as headset mic, without its own jack detect */
552 			{ 0x19, 0x22219420 },
553 			{}
554 		},
555 	},
556 	[ALC887_FIXUP_ASUS_HMIC] = {
557 		.type = HDA_FIXUP_FUNC,
558 		.v.func = alc887_fixup_asus_jack,
559 		.chained = true,
560 		.chain_id = ALC887_FIXUP_ASUS_AUDIO,
561 	},
562 	[ALCS1200A_FIXUP_MIC_VREF] = {
563 		.type = HDA_FIXUP_PINCTLS,
564 		.v.pins = (const struct hda_pintbl[]) {
565 			{ 0x18, PIN_VREF50 }, /* rear mic */
566 			{ 0x19, PIN_VREF50 }, /* front mic */
567 			{}
568 		}
569 	},
570 	[ALC888VD_FIXUP_MIC_100VREF] = {
571 		.type = HDA_FIXUP_PINCTLS,
572 		.v.pins = (const struct hda_pintbl[]) {
573 			{ 0x18, PIN_VREF100 }, /* headset mic */
574 			{}
575 		}
576 	},
577 	[ALC898_FIXUP_CLEVO_P775TM1] = {
578 		.type = HDA_FIXUP_FUNC,
579 		.v.func = alc898_fixup_clevo_p775tm1,
580 		.chained = true,
581 		.chain_id = ALC882_FIXUP_EAPD,
582 	},
583 };
584 
585 static const struct hda_quirk alc882_fixup_tbl[] = {
586 	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
587 	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
588 	SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
589 	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
590 	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
591 	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
592 	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
593 	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
594 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
595 	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
596 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
597 	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
598 		      ALC882_FIXUP_ACER_ASPIRE_8930G),
599 	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
600 		      ALC882_FIXUP_ACER_ASPIRE_8930G),
601 	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
602 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
603 	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
604 	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
605 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
606 	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
607 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
608 	SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
609 		      ALC882_FIXUP_ACER_ASPIRE_4930G),
610 	SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
611 	SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
612 	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
613 	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
614 	SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
615 	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
616 	SND_PCI_QUIRK(0x1043, 0x2390, "Asus D700SA", ALC887_FIXUP_ASUS_HMIC),
617 	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
618 	SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
619 	SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
620 	SND_PCI_QUIRK(0x1043, 0x8797, "ASUS TUF B550M-PLUS", ALCS1200A_FIXUP_MIC_VREF),
621 	SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
622 	SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
623 	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
624 	SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
625 	SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
626 
627 	/* All Apple entries are in codec SSIDs */
628 	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
629 	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
630 	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
631 	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
632 	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
633 	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
634 	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
635 	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
636 	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
637 	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
638 	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
639 	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
640 	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
641 	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
642 	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
643 	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
644 	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
645 	SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 4,1/5,1", ALC889_FIXUP_MP41_VREF),
646 	SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
647 	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
648 	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
649 	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
650 
651 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
652 	SND_PCI_QUIRK(0x10ec, 0x12d8, "iBase Elo Touch", ALC888VD_FIXUP_MIC_100VREF),
653 	SND_PCI_QUIRK(0x13fe, 0x1009, "Advantech MIT-W101", ALC886_FIXUP_EAPD),
654 	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
655 	SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
656 	SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_GB_X570),
657 	SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_GB_X570),
658 	SND_PCI_QUIRK(0x1458, 0xa0d5, "Gigabyte X570S Aorus Master", ALC1220_FIXUP_GB_X570),
659 	SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950),
660 	SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
661 	SND_PCI_QUIRK(0x1462, 0x1229, "MSI-GP73", ALC1220_FIXUP_CLEVO_P950),
662 	SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
663 	SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
664 	SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
665 	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
666 	SND_PCI_QUIRK(0x1462, 0xcc34, "MSI Godlike X570", ALC1220_FIXUP_GB_DUAL_CODECS),
667 	SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
668 	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
669 	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
670 	SND_PCI_QUIRK(0x1558, 0x3702, "Clevo X370SN[VW]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
671 	SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
672 	SND_PCI_QUIRK(0x1558, 0x5802, "Clevo X58[05]WN[RST]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
673 	SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
674 	SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
675 	SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
676 	SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
677 	SND_PCI_QUIRK(0x1558, 0x65f1, "Clevo PC50HS", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
678 	SND_PCI_QUIRK(0x1558, 0x65f5, "Clevo PD50PN[NRT]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
679 	SND_PCI_QUIRK(0x1558, 0x66a2, "Clevo PE60RNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
680 	SND_PCI_QUIRK(0x1558, 0x66a6, "Clevo PE60SN[CDE]-[GS]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
681 	SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
682 	SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
683 	SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
684 	SND_PCI_QUIRK(0x1558, 0x67f1, "Clevo PC70H[PRS]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
685 	SND_PCI_QUIRK(0x1558, 0x67f5, "Clevo PD70PN[NRT]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
686 	SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
687 	SND_PCI_QUIRK(0x1558, 0x7709, "Clevo P775TM1", ALC898_FIXUP_CLEVO_P775TM1),
688 	SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170SM", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
689 	SND_PCI_QUIRK(0x1558, 0x7715, "Clevo X170KM-G", ALC1220_FIXUP_CLEVO_PB51ED),
690 	SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
691 	SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950),
692 	SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950),
693 	SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
694 	SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
695 	SND_PCI_QUIRK(0x1558, 0x95e3, "Clevo P955[ER]T", ALC1220_FIXUP_CLEVO_P950),
696 	SND_PCI_QUIRK(0x1558, 0x95e4, "Clevo P955ER", ALC1220_FIXUP_CLEVO_P950),
697 	SND_PCI_QUIRK(0x1558, 0x95e5, "Clevo P955EE6", ALC1220_FIXUP_CLEVO_P950),
698 	SND_PCI_QUIRK(0x1558, 0x95e6, "Clevo P950R[CDF]", ALC1220_FIXUP_CLEVO_P950),
699 	SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
700 	SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
701 	SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950),
702 	SND_PCI_QUIRK(0x1558, 0xd502, "Clevo PD50SNE", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
703 	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
704 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
705 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
706 	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
707 	{}
708 };
709 
710 static const struct hda_model_fixup alc882_fixup_models[] = {
711 	{.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"},
712 	{.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"},
713 	{.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"},
714 	{.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"},
715 	{.id = ALC889_FIXUP_CD, .name = "cd"},
716 	{.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"},
717 	{.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"},
718 	{.id = ALC888_FIXUP_EEE1601, .name = "eee1601"},
719 	{.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"},
720 	{.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"},
721 	{.id = ALC882_FIXUP_GPIO1, .name = "gpio1"},
722 	{.id = ALC882_FIXUP_GPIO2, .name = "gpio2"},
723 	{.id = ALC882_FIXUP_GPIO3, .name = "gpio3"},
724 	{.id = ALC889_FIXUP_COEF, .name = "alc889-coef"},
725 	{.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"},
726 	{.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
727 	{.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
728 	{.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
729 	{.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"},
730 	{.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"},
731 	{.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"},
732 	{.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"},
733 	{.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"},
734 	{.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"},
735 	{.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"},
736 	{.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"},
737 	{.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
738 	{.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
739 	{.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"},
740 	{.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"},
741 	{.id = ALC1220_FIXUP_GB_X570, .name = "gb-x570"},
742 	{.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"},
743 	{.id = ALC898_FIXUP_CLEVO_P775TM1, .name = "clevo-p775tm1"},
744 	{}
745 };
746 
747 static const struct snd_hda_pin_quirk alc882_pin_fixup_tbl[] = {
748 	SND_HDA_PIN_QUIRK(0x10ec1220, 0x1043, "ASUS", ALC1220_FIXUP_CLEVO_P950,
749 		{0x14, 0x01014010},
750 		{0x15, 0x01011012},
751 		{0x16, 0x01016011},
752 		{0x18, 0x01a19040},
753 		{0x19, 0x02a19050},
754 		{0x1a, 0x0181304f},
755 		{0x1b, 0x0221401f},
756 		{0x1e, 0x01456130}),
757 	SND_HDA_PIN_QUIRK(0x10ec1220, 0x1462, "MS-7C35", ALC1220_FIXUP_CLEVO_P950,
758 		{0x14, 0x01015010},
759 		{0x15, 0x01011012},
760 		{0x16, 0x01011011},
761 		{0x18, 0x01a11040},
762 		{0x19, 0x02a19050},
763 		{0x1a, 0x0181104f},
764 		{0x1b, 0x0221401f},
765 		{0x1e, 0x01451130}),
766 	{}
767 };
768 
769 /*
770  * BIOS auto configuration
771  */
772 /* almost identical with ALC880 parser... */
773 static int alc882_parse_auto_config(struct hda_codec *codec)
774 {
775 	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
776 	static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
777 	return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
778 }
779 
780 /*
781  */
782 static int alc882_probe(struct hda_codec *codec, const struct hda_device_id *id)
783 {
784 	struct alc_spec *spec;
785 	int err;
786 
787 	err = alc_alloc_spec(codec, 0x0b);
788 	if (err < 0)
789 		return err;
790 
791 	spec = codec->spec;
792 
793 	switch (codec->core.vendor_id) {
794 	case 0x10ec0882:
795 	case 0x10ec0885:
796 	case 0x10ec0900:
797 	case 0x10ec0b00:
798 	case 0x10ec1220:
799 		break;
800 	default:
801 		/* ALC883 and variants */
802 		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
803 		break;
804 	}
805 
806 	alc_pre_init(codec);
807 
808 	snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
809 		       alc882_fixups);
810 	snd_hda_pick_pin_fixup(codec, alc882_pin_fixup_tbl, alc882_fixups, true);
811 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
812 
813 	alc_auto_parse_customize_define(codec);
814 
815 	if (has_cdefine_beep(codec))
816 		spec->gen.beep_nid = 0x01;
817 
818 	/* automatic parse from the BIOS config */
819 	err = alc882_parse_auto_config(codec);
820 	if (err < 0)
821 		goto error;
822 
823 	if (!spec->gen.no_analog && spec->gen.beep_nid) {
824 		err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
825 		if (err < 0)
826 			goto error;
827 	}
828 
829 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
830 
831 	return 0;
832 
833  error:
834 	snd_hda_gen_remove(codec);
835 	return err;
836 }
837 
838 static const struct hda_codec_ops alc882_codec_ops = {
839 	.probe = alc882_probe,
840 	.remove = snd_hda_gen_remove,
841 	.build_controls = alc_build_controls,
842 	.build_pcms = snd_hda_gen_build_pcms,
843 	.init = alc_init,
844 	.unsol_event = snd_hda_jack_unsol_event,
845 	.resume = alc_resume,
846 	.suspend = alc_suspend,
847 	.check_power_status = snd_hda_gen_check_power_status,
848 	.stream_pm = snd_hda_gen_stream_pm,
849 };
850 
851 /*
852  * driver entries
853  */
854 static const struct hda_device_id snd_hda_id_alc882[] = {
855 	HDA_CODEC_ID_REV(0x10ec0662, 0x100002, "ALC662 rev2"),
856 	HDA_CODEC_ID(0x10ec0882, "ALC882"),
857 	HDA_CODEC_ID(0x10ec0883, "ALC883"),
858 	HDA_CODEC_ID_REV(0x10ec0885, 0x100101, "ALC889A"),
859 	HDA_CODEC_ID_REV(0x10ec0885, 0x100103, "ALC889A"),
860 	HDA_CODEC_ID(0x10ec0885, "ALC885"),
861 	HDA_CODEC_ID(0x10ec0887, "ALC887"),
862 	HDA_CODEC_ID_REV(0x10ec0888, 0x100101, "ALC1200"),
863 	HDA_CODEC_ID(0x10ec0888, "ALC888"),
864 	HDA_CODEC_ID(0x10ec0889, "ALC889"),
865 	HDA_CODEC_ID(0x10ec0899, "ALC898"),
866 	HDA_CODEC_ID(0x10ec0900, "ALC1150"),
867 	HDA_CODEC_ID(0x10ec0b00, "ALCS1200A"),
868 	HDA_CODEC_ID(0x10ec1168, "ALC1220"),
869 	HDA_CODEC_ID(0x10ec1220, "ALC1220"),
870 	{} /* terminator */
871 };
872 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_alc882);
873 
874 MODULE_LICENSE("GPL");
875 MODULE_DESCRIPTION("Realtek ALC882 and compatible HD-audio codecs");
876 MODULE_IMPORT_NS("SND_HDA_CODEC_REALTEK");
877 
878 static struct hda_codec_driver alc882_driver = {
879 	.id = snd_hda_id_alc882,
880 	.ops = &alc882_codec_ops,
881 };
882 
883 module_hda_codec_driver(alc882_driver);
884