xref: /linux/sound/hda/codecs/realtek/realtek.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 //
3 // Realtek HD-audio codec support code
4 //
5 
6 #include <linux/init.h>
7 #include <linux/module.h>
8 #include "realtek.h"
9 
10 static int __alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
11 				 unsigned int coef_idx)
12 {
13 	unsigned int val;
14 
15 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
16 	val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
17 	return val;
18 }
19 
20 int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
21 			unsigned int coef_idx)
22 {
23 	guard(coef_mutex)(codec);
24 	return __alc_read_coefex_idx(codec, nid, coef_idx);
25 }
26 EXPORT_SYMBOL_NS_GPL(alc_read_coefex_idx, "SND_HDA_CODEC_REALTEK");
27 
28 static void __alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
29 				   unsigned int coef_idx, unsigned int coef_val)
30 {
31 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
32 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
33 }
34 
35 void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
36 			  unsigned int coef_idx, unsigned int coef_val)
37 {
38 	guard(coef_mutex)(codec);
39 	__alc_write_coefex_idx(codec, nid, coef_idx, coef_val);
40 }
41 EXPORT_SYMBOL_NS_GPL(alc_write_coefex_idx, "SND_HDA_CODEC_REALTEK");
42 
43 static void __alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
44 				    unsigned int coef_idx, unsigned int mask,
45 				    unsigned int bits_set)
46 {
47 	unsigned int val = __alc_read_coefex_idx(codec, nid, coef_idx);
48 
49 	if (val != -1)
50 		__alc_write_coefex_idx(codec, nid, coef_idx,
51 				       (val & ~mask) | bits_set);
52 }
53 
54 void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
55 			   unsigned int coef_idx, unsigned int mask,
56 			   unsigned int bits_set)
57 {
58 	guard(coef_mutex)(codec);
59 	__alc_update_coefex_idx(codec, nid, coef_idx, mask, bits_set);
60 }
61 EXPORT_SYMBOL_NS_GPL(alc_update_coefex_idx, "SND_HDA_CODEC_REALTEK");
62 
63 /* a special bypass for COEF 0; read the cached value at the second time */
64 unsigned int alc_get_coef0(struct hda_codec *codec)
65 {
66 	struct alc_spec *spec = codec->spec;
67 
68 	if (!spec->coef0)
69 		spec->coef0 = alc_read_coef_idx(codec, 0);
70 	return spec->coef0;
71 }
72 EXPORT_SYMBOL_NS_GPL(alc_get_coef0, "SND_HDA_CODEC_REALTEK");
73 
74 void alc_process_coef_fw(struct hda_codec *codec, const struct coef_fw *fw)
75 {
76 	guard(coef_mutex)(codec);
77 	for (; fw->nid; fw++) {
78 		if (fw->mask == (unsigned short)-1)
79 			__alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
80 		else
81 			__alc_update_coefex_idx(codec, fw->nid, fw->idx,
82 						fw->mask, fw->val);
83 	}
84 }
85 EXPORT_SYMBOL_NS_GPL(alc_process_coef_fw, "SND_HDA_CODEC_REALTEK");
86 
87 /*
88  * GPIO setup tables, used in initialization
89  */
90 
91 /* Enable GPIO mask and set output */
92 void alc_setup_gpio(struct hda_codec *codec, unsigned int mask)
93 {
94 	struct alc_spec *spec = codec->spec;
95 
96 	spec->gpio_mask |= mask;
97 	spec->gpio_dir |= mask;
98 	spec->gpio_data |= mask;
99 }
100 EXPORT_SYMBOL_NS_GPL(alc_setup_gpio, "SND_HDA_CODEC_REALTEK");
101 
102 void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask,
103 			  bool on)
104 {
105 	struct alc_spec *spec = codec->spec;
106 	unsigned int oldval = spec->gpio_data;
107 
108 	if (on)
109 		spec->gpio_data |= mask;
110 	else
111 		spec->gpio_data &= ~mask;
112 	if (oldval != spec->gpio_data)
113 		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
114 				    spec->gpio_data);
115 }
116 EXPORT_SYMBOL_NS_GPL(alc_update_gpio_data, "SND_HDA_CODEC_REALTEK");
117 
118 static void alc_write_gpio(struct hda_codec *codec)
119 {
120 	struct alc_spec *spec = codec->spec;
121 
122 	if (!spec->gpio_mask)
123 		return;
124 
125 	snd_hda_codec_set_gpio(codec, spec->gpio_mask, spec->gpio_dir,
126 			       spec->gpio_data,
127 			       spec->gpio_write_delay ? 1 : 0);
128 }
129 
130 void alc_fixup_gpio(struct hda_codec *codec, int action, unsigned int mask)
131 {
132 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
133 		alc_setup_gpio(codec, mask);
134 }
135 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio, "SND_HDA_CODEC_REALTEK");
136 
137 void alc_fixup_gpio1(struct hda_codec *codec,
138 		     const struct hda_fixup *fix, int action)
139 {
140 	alc_fixup_gpio(codec, action, 0x01);
141 }
142 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio1, "SND_HDA_CODEC_REALTEK");
143 
144 void alc_fixup_gpio2(struct hda_codec *codec,
145 		     const struct hda_fixup *fix, int action)
146 {
147 	alc_fixup_gpio(codec, action, 0x02);
148 }
149 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio2, "SND_HDA_CODEC_REALTEK");
150 
151 void alc_fixup_gpio3(struct hda_codec *codec,
152 		     const struct hda_fixup *fix, int action)
153 {
154 	alc_fixup_gpio(codec, action, 0x03);
155 }
156 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio3, "SND_HDA_CODEC_REALTEK");
157 
158 void alc_fixup_gpio4(struct hda_codec *codec,
159 		     const struct hda_fixup *fix, int action)
160 {
161 	alc_fixup_gpio(codec, action, 0x04);
162 }
163 EXPORT_SYMBOL_NS_GPL(alc_fixup_gpio4, "SND_HDA_CODEC_REALTEK");
164 
165 void alc_fixup_micmute_led(struct hda_codec *codec,
166 			   const struct hda_fixup *fix, int action)
167 {
168 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
169 		snd_hda_gen_add_micmute_led_cdev(codec, NULL);
170 }
171 EXPORT_SYMBOL_NS_GPL(alc_fixup_micmute_led, "SND_HDA_CODEC_REALTEK");
172 
173 /*
174  * Fix hardware PLL issue
175  * On some codecs, the analog PLL gating control must be off while
176  * the default value is 1.
177  */
178 void alc_fix_pll(struct hda_codec *codec)
179 {
180 	struct alc_spec *spec = codec->spec;
181 
182 	if (spec->pll_nid)
183 		alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
184 				      1 << spec->pll_coef_bit, 0);
185 }
186 EXPORT_SYMBOL_NS_GPL(alc_fix_pll, "SND_HDA_CODEC_REALTEK");
187 
188 void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
189 		      unsigned int coef_idx, unsigned int coef_bit)
190 {
191 	struct alc_spec *spec = codec->spec;
192 	spec->pll_nid = nid;
193 	spec->pll_coef_idx = coef_idx;
194 	spec->pll_coef_bit = coef_bit;
195 	alc_fix_pll(codec);
196 }
197 EXPORT_SYMBOL_NS_GPL(alc_fix_pll_init, "SND_HDA_CODEC_REALTEK");
198 
199 /* update the master volume per volume-knob's unsol event */
200 void alc_update_knob_master(struct hda_codec *codec,
201 			    struct hda_jack_callback *jack)
202 {
203 	unsigned int val;
204 	struct snd_kcontrol *kctl;
205 
206 	kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
207 	if (!kctl)
208 		return;
209 
210 	struct snd_ctl_elem_value *uctl __free(kfree) =
211 		kzalloc_obj(*uctl);
212 	if (!uctl)
213 		return;
214 	val = snd_hda_codec_read(codec, jack->nid, 0,
215 				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
216 	val &= HDA_AMP_VOLMASK;
217 	uctl->value.integer.value[0] = val;
218 	uctl->value.integer.value[1] = val;
219 	kctl->put(kctl, uctl);
220 }
221 EXPORT_SYMBOL_NS_GPL(alc_update_knob_master, "SND_HDA_CODEC_REALTEK");
222 
223 /* Change EAPD to verb control */
224 void alc_fill_eapd_coef(struct hda_codec *codec)
225 {
226 	int coef;
227 
228 	coef = alc_get_coef0(codec);
229 
230 	switch (codec->core.vendor_id) {
231 	case 0x10ec0262:
232 		alc_update_coef_idx(codec, 0x7, 0, 1<<5);
233 		break;
234 	case 0x10ec0267:
235 	case 0x10ec0268:
236 		alc_update_coef_idx(codec, 0x7, 0, 1<<13);
237 		break;
238 	case 0x10ec0269:
239 		if ((coef & 0x00f0) == 0x0010)
240 			alc_update_coef_idx(codec, 0xd, 0, 1<<14);
241 		if ((coef & 0x00f0) == 0x0020)
242 			alc_update_coef_idx(codec, 0x4, 1<<15, 0);
243 		if ((coef & 0x00f0) == 0x0030)
244 			alc_update_coef_idx(codec, 0x10, 1<<9, 0);
245 		break;
246 	case 0x10ec0280:
247 	case 0x10ec0284:
248 	case 0x10ec0290:
249 	case 0x10ec0292:
250 		alc_update_coef_idx(codec, 0x4, 1<<15, 0);
251 		break;
252 	case 0x10ec0225:
253 	case 0x10ec0295:
254 	case 0x10ec0299:
255 		alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
256 		fallthrough;
257 	case 0x10ec0215:
258 	case 0x10ec0236:
259 	case 0x10ec0245:
260 	case 0x10ec0256:
261 	case 0x10ec0257:
262 	case 0x10ec0285:
263 	case 0x10ec0289:
264 		alc_update_coef_idx(codec, 0x36, 1<<13, 0);
265 		fallthrough;
266 	case 0x10ec0230:
267 	case 0x10ec0233:
268 	case 0x10ec0235:
269 	case 0x10ec0255:
270 	case 0x19e58326:
271 	case 0x10ec0282:
272 	case 0x10ec0283:
273 	case 0x10ec0286:
274 	case 0x10ec0288:
275 	case 0x10ec0298:
276 	case 0x10ec0300:
277 		alc_update_coef_idx(codec, 0x10, 1<<9, 0);
278 		break;
279 	case 0x10ec0275:
280 		alc_update_coef_idx(codec, 0xe, 0, 1<<0);
281 		break;
282 	case 0x10ec0287:
283 		alc_update_coef_idx(codec, 0x10, 1<<9, 0);
284 		alc_write_coef_idx(codec, 0x8, 0x4ab7);
285 		break;
286 	case 0x10ec0293:
287 		alc_update_coef_idx(codec, 0xa, 1<<13, 0);
288 		break;
289 	case 0x10ec0234:
290 	case 0x10ec0274:
291 		alc_write_coef_idx(codec, 0x6e, 0x0c25);
292 		fallthrough;
293 	case 0x10ec0294:
294 	case 0x10ec0700:
295 	case 0x10ec0701:
296 	case 0x10ec0703:
297 	case 0x10ec0711:
298 		alc_update_coef_idx(codec, 0x10, 1<<15, 0);
299 		break;
300 	case 0x10ec0662:
301 		if ((coef & 0x00f0) == 0x0030)
302 			alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
303 		break;
304 	case 0x10ec0272:
305 	case 0x10ec0273:
306 	case 0x10ec0663:
307 	case 0x10ec0665:
308 	case 0x10ec0670:
309 	case 0x10ec0671:
310 	case 0x10ec0672:
311 		alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
312 		break;
313 	case 0x10ec0222:
314 	case 0x10ec0623:
315 		alc_update_coef_idx(codec, 0x19, 1<<13, 0);
316 		break;
317 	case 0x10ec0668:
318 		alc_update_coef_idx(codec, 0x7, 3<<13, 0);
319 		break;
320 	case 0x10ec0867:
321 		alc_update_coef_idx(codec, 0x4, 1<<10, 0);
322 		break;
323 	case 0x10ec0888:
324 		if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
325 			alc_update_coef_idx(codec, 0x7, 1<<5, 0);
326 		break;
327 	case 0x10ec0892:
328 	case 0x10ec0897:
329 		alc_update_coef_idx(codec, 0x7, 1<<5, 0);
330 		break;
331 	case 0x10ec0899:
332 	case 0x10ec0900:
333 	case 0x10ec0b00:
334 	case 0x10ec1168:
335 	case 0x10ec1220:
336 		alc_update_coef_idx(codec, 0x7, 1<<1, 0);
337 		break;
338 	}
339 }
340 EXPORT_SYMBOL_NS_GPL(alc_fill_eapd_coef, "SND_HDA_CODEC_REALTEK");
341 
342 /* turn on/off EAPD control (only if available) */
343 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
344 {
345 	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
346 		return;
347 	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
348 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
349 				    on ? 2 : 0);
350 }
351 
352 /* turn on/off EAPD controls of the codec */
353 void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
354 {
355 	/* We currently only handle front, HP */
356 	static const hda_nid_t pins[] = {
357 		0x0f, 0x10, 0x14, 0x15, 0x17, 0
358 	};
359 	const hda_nid_t *p;
360 	for (p = pins; *p; p++)
361 		set_eapd(codec, *p, on);
362 }
363 EXPORT_SYMBOL_NS_GPL(alc_auto_setup_eapd, "SND_HDA_CODEC_REALTEK");
364 
365 /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
366 int alc_find_ext_mic_pin(struct hda_codec *codec)
367 {
368 	struct alc_spec *spec = codec->spec;
369 	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
370 	hda_nid_t nid;
371 	unsigned int defcfg;
372 	int i;
373 
374 	for (i = 0; i < cfg->num_inputs; i++) {
375 		if (cfg->inputs[i].type != AUTO_PIN_MIC)
376 			continue;
377 		nid = cfg->inputs[i].pin;
378 		defcfg = snd_hda_codec_get_pincfg(codec, nid);
379 		if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
380 			continue;
381 		return nid;
382 	}
383 
384 	return 0;
385 }
386 EXPORT_SYMBOL_NS_GPL(alc_find_ext_mic_pin, "SND_HDA_CODEC_REALTEK");
387 
388 void alc_headset_mic_no_shutup(struct hda_codec *codec)
389 {
390 	const struct hda_pincfg *pin;
391 	int mic_pin = alc_find_ext_mic_pin(codec);
392 	int i;
393 
394 	/* don't shut up pins when unloading the driver; otherwise it breaks
395 	 * the default pin setup at the next load of the driver
396 	 */
397 	if (codec->bus->shutdown)
398 		return;
399 
400 	snd_array_for_each(&codec->init_pins, i, pin) {
401 		if (pin->nid != mic_pin)
402 			snd_hda_codec_write_sync(codec, pin->nid, 0,
403 					AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
404 	}
405 
406 	codec->pins_shutup = 1;
407 }
408 EXPORT_SYMBOL_NS_GPL(alc_headset_mic_no_shutup, "SND_HDA_CODEC_REALTEK");
409 
410 void alc_shutup_pins(struct hda_codec *codec)
411 {
412 	struct alc_spec *spec = codec->spec;
413 
414 	if (spec->no_shutup_pins)
415 		return;
416 
417 	switch (codec->core.vendor_id) {
418 	case 0x10ec0236:
419 	case 0x10ec0256:
420 	case 0x10ec0257:
421 	case 0x19e58326:
422 	case 0x10ec0283:
423 	case 0x10ec0285:
424 	case 0x10ec0286:
425 	case 0x10ec0287:
426 	case 0x10ec0288:
427 	case 0x10ec0295:
428 	case 0x10ec0298:
429 		alc_headset_mic_no_shutup(codec);
430 		break;
431 	default:
432 		snd_hda_shutup_pins(codec);
433 		break;
434 	}
435 }
436 EXPORT_SYMBOL_NS_GPL(alc_shutup_pins, "SND_HDA_CODEC_REALTEK");
437 
438 /* generic shutup callback;
439  * just turning off EAPD and a little pause for avoiding pop-noise
440  */
441 void alc_eapd_shutup(struct hda_codec *codec)
442 {
443 	struct alc_spec *spec = codec->spec;
444 
445 	alc_auto_setup_eapd(codec, false);
446 	if (!spec->no_depop_delay)
447 		msleep(200);
448 	alc_shutup_pins(codec);
449 }
450 EXPORT_SYMBOL_NS_GPL(alc_eapd_shutup, "SND_HDA_CODEC_REALTEK");
451 
452 /* additional initialization for ALC888 variants */
453 static void alc888_coef_init(struct hda_codec *codec)
454 {
455 	switch (alc_get_coef0(codec) & 0x00f0) {
456 	/* alc888-VA */
457 	case 0x00:
458 	/* alc888-VB */
459 	case 0x10:
460 		alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
461 		break;
462 	}
463 }
464 
465 /* generic EAPD initialization */
466 void alc_auto_init_amp(struct hda_codec *codec, int type)
467 {
468 	alc_auto_setup_eapd(codec, true);
469 	alc_write_gpio(codec);
470 	switch (type) {
471 	case ALC_INIT_DEFAULT:
472 		switch (codec->core.vendor_id) {
473 		case 0x10ec0260:
474 			alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
475 			break;
476 		case 0x10ec0880:
477 		case 0x10ec0882:
478 		case 0x10ec0883:
479 		case 0x10ec0885:
480 			alc_update_coef_idx(codec, 7, 0, 0x2030);
481 			break;
482 		case 0x10ec0888:
483 			alc888_coef_init(codec);
484 			break;
485 		}
486 		break;
487 	}
488 }
489 EXPORT_SYMBOL_NS_GPL(alc_auto_init_amp, "SND_HDA_CODEC_REALTEK");
490 
491 /* get a primary headphone pin if available */
492 hda_nid_t alc_get_hp_pin(struct alc_spec *spec)
493 {
494 	if (spec->gen.autocfg.hp_pins[0])
495 		return spec->gen.autocfg.hp_pins[0];
496 	if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
497 		return spec->gen.autocfg.line_out_pins[0];
498 	return 0;
499 }
500 EXPORT_SYMBOL_NS_GPL(alc_get_hp_pin, "SND_HDA_CODEC_REALTEK");
501 
502 /*
503  * Realtek SSID verification
504  */
505 
506 /* Could be any non-zero and even value. When used as fixup, tells
507  * the driver to ignore any present sku defines.
508  */
509 #define ALC_FIXUP_SKU_IGNORE (2)
510 
511 void alc_fixup_sku_ignore(struct hda_codec *codec,
512 			  const struct hda_fixup *fix, int action)
513 {
514 	struct alc_spec *spec = codec->spec;
515 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
516 		spec->cdefine.fixup = 1;
517 		spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
518 	}
519 }
520 EXPORT_SYMBOL_NS_GPL(alc_fixup_sku_ignore, "SND_HDA_CODEC_REALTEK");
521 
522 void alc_fixup_no_depop_delay(struct hda_codec *codec,
523 			      const struct hda_fixup *fix, int action)
524 {
525 	struct alc_spec *spec = codec->spec;
526 
527 	if (action == HDA_FIXUP_ACT_PROBE) {
528 		spec->no_depop_delay = 1;
529 		codec->depop_delay = 0;
530 	}
531 }
532 EXPORT_SYMBOL_NS_GPL(alc_fixup_no_depop_delay, "SND_HDA_CODEC_REALTEK");
533 
534 int alc_auto_parse_customize_define(struct hda_codec *codec)
535 {
536 	unsigned int ass, tmp, i;
537 	unsigned nid = 0;
538 	struct alc_spec *spec = codec->spec;
539 
540 	spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
541 
542 	if (spec->cdefine.fixup) {
543 		ass = spec->cdefine.sku_cfg;
544 		if (ass == ALC_FIXUP_SKU_IGNORE)
545 			return -1;
546 		goto do_sku;
547 	}
548 
549 	if (!codec->bus->pci)
550 		return -1;
551 	ass = codec->core.subsystem_id & 0xffff;
552 	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
553 		goto do_sku;
554 
555 	nid = 0x1d;
556 	if (codec->core.vendor_id == 0x10ec0260)
557 		nid = 0x17;
558 	ass = snd_hda_codec_get_pincfg(codec, nid);
559 
560 	if (!(ass & 1)) {
561 		codec_info(codec, "%s: SKU not ready 0x%08x\n",
562 			   codec->core.chip_name, ass);
563 		return -1;
564 	}
565 
566 	/* check sum */
567 	tmp = 0;
568 	for (i = 1; i < 16; i++) {
569 		if ((ass >> i) & 1)
570 			tmp++;
571 	}
572 	if (((ass >> 16) & 0xf) != tmp)
573 		return -1;
574 
575 	spec->cdefine.port_connectivity = ass >> 30;
576 	spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
577 	spec->cdefine.check_sum = (ass >> 16) & 0xf;
578 	spec->cdefine.customization = ass >> 8;
579 do_sku:
580 	spec->cdefine.sku_cfg = ass;
581 	spec->cdefine.external_amp = (ass & 0x38) >> 3;
582 	spec->cdefine.platform_type = (ass & 0x4) >> 2;
583 	spec->cdefine.swap = (ass & 0x2) >> 1;
584 	spec->cdefine.override = ass & 0x1;
585 
586 	codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
587 		   nid, spec->cdefine.sku_cfg);
588 	codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
589 		   spec->cdefine.port_connectivity);
590 	codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
591 	codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
592 	codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
593 	codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
594 	codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
595 	codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
596 	codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
597 
598 	return 0;
599 }
600 EXPORT_SYMBOL_NS_GPL(alc_auto_parse_customize_define, "SND_HDA_CODEC_REALTEK");
601 
602 /* return the position of NID in the list, or -1 if not found */
603 static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
604 {
605 	int i;
606 	for (i = 0; i < nums; i++)
607 		if (list[i] == nid)
608 			return i;
609 	return -1;
610 }
611 /* return true if the given NID is found in the list */
612 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
613 {
614 	return find_idx_in_nid_list(nid, list, nums) >= 0;
615 }
616 
617 /* check subsystem ID and set up device-specific initialization;
618  * return 1 if initialized, 0 if invalid SSID
619  */
620 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
621  *	31 ~ 16 :	Manufacture ID
622  *	15 ~ 8	:	SKU ID
623  *	7  ~ 0	:	Assembly ID
624  *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
625  */
626 int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
627 {
628 	unsigned int ass, tmp, i;
629 	unsigned nid;
630 	struct alc_spec *spec = codec->spec;
631 
632 	if (spec->cdefine.fixup) {
633 		ass = spec->cdefine.sku_cfg;
634 		if (ass == ALC_FIXUP_SKU_IGNORE)
635 			return 0;
636 		goto do_sku;
637 	}
638 
639 	ass = codec->core.subsystem_id & 0xffff;
640 	if (codec->bus->pci &&
641 	    ass != codec->bus->pci->subsystem_device && (ass & 1))
642 		goto do_sku;
643 
644 	/* invalid SSID, check the special NID pin defcfg instead */
645 	/*
646 	 * 31~30	: port connectivity
647 	 * 29~21	: reserve
648 	 * 20		: PCBEEP input
649 	 * 19~16	: Check sum (15:1)
650 	 * 15~1		: Custom
651 	 * 0		: override
652 	*/
653 	nid = 0x1d;
654 	if (codec->core.vendor_id == 0x10ec0260)
655 		nid = 0x17;
656 	ass = snd_hda_codec_get_pincfg(codec, nid);
657 	codec_dbg(codec,
658 		  "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
659 		   ass, nid);
660 	if (!(ass & 1))
661 		return 0;
662 	if ((ass >> 30) != 1)	/* no physical connection */
663 		return 0;
664 
665 	/* check sum */
666 	tmp = 0;
667 	for (i = 1; i < 16; i++) {
668 		if ((ass >> i) & 1)
669 			tmp++;
670 	}
671 	if (((ass >> 16) & 0xf) != tmp)
672 		return 0;
673 do_sku:
674 	codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
675 		   ass & 0xffff, codec->core.vendor_id);
676 	/*
677 	 * 0 : override
678 	 * 1 :	Swap Jack
679 	 * 2 : 0 --> Desktop, 1 --> Laptop
680 	 * 3~5 : External Amplifier control
681 	 * 7~6 : Reserved
682 	*/
683 	tmp = (ass & 0x38) >> 3;	/* external Amp control */
684 	if (spec->init_amp == ALC_INIT_UNDEFINED) {
685 		switch (tmp) {
686 		case 1:
687 			alc_setup_gpio(codec, 0x01);
688 			break;
689 		case 3:
690 			alc_setup_gpio(codec, 0x02);
691 			break;
692 		case 7:
693 			alc_setup_gpio(codec, 0x04);
694 			break;
695 		case 5:
696 		default:
697 			spec->init_amp = ALC_INIT_DEFAULT;
698 			break;
699 		}
700 	}
701 
702 	/* is laptop or Desktop and enable the function "Mute internal speaker
703 	 * when the external headphone out jack is plugged"
704 	 */
705 	if (!(ass & 0x8000))
706 		return 1;
707 	/*
708 	 * 10~8 : Jack location
709 	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
710 	 * 14~13: Resvered
711 	 * 15   : 1 --> enable the function "Mute internal speaker
712 	 *	        when the external headphone out jack is plugged"
713 	 */
714 	if (!alc_get_hp_pin(spec)) {
715 		hda_nid_t nid;
716 		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
717 		nid = ports[tmp];
718 		if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
719 				      spec->gen.autocfg.line_outs))
720 			return 1;
721 		spec->gen.autocfg.hp_pins[0] = nid;
722 	}
723 	return 1;
724 }
725 EXPORT_SYMBOL_NS_GPL(alc_subsystem_id, "SND_HDA_CODEC_REALTEK");
726 
727 /* Check the validity of ALC subsystem-id
728  * ports contains an array of 4 pin NIDs for port-A, E, D and I */
729 void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
730 {
731 	if (!alc_subsystem_id(codec, ports)) {
732 		struct alc_spec *spec = codec->spec;
733 		if (spec->init_amp == ALC_INIT_UNDEFINED) {
734 			codec_dbg(codec,
735 				  "realtek: Enable default setup for auto mode as fallback\n");
736 			spec->init_amp = ALC_INIT_DEFAULT;
737 		}
738 	}
739 }
740 EXPORT_SYMBOL_NS_GPL(alc_ssid_check, "SND_HDA_CODEC_REALTEK");
741 
742 /* inverted digital-mic */
743 void alc_fixup_inv_dmic(struct hda_codec *codec,
744 			const struct hda_fixup *fix, int action)
745 {
746 	struct alc_spec *spec = codec->spec;
747 
748 	spec->gen.inv_dmic_split = 1;
749 }
750 EXPORT_SYMBOL_NS_GPL(alc_fixup_inv_dmic, "SND_HDA_CODEC_REALTEK");
751 
752 int alc_build_controls(struct hda_codec *codec)
753 {
754 	int err;
755 
756 	err = snd_hda_gen_build_controls(codec);
757 	if (err < 0)
758 		return err;
759 
760 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
761 	return 0;
762 }
763 EXPORT_SYMBOL_NS_GPL(alc_build_controls, "SND_HDA_CODEC_REALTEK");
764 
765 int alc_init(struct hda_codec *codec)
766 {
767 	struct alc_spec *spec = codec->spec;
768 
769 	/* hibernation resume needs the full chip initialization */
770 	if (is_s4_resume(codec))
771 		alc_pre_init(codec);
772 
773 	if (spec->init_hook)
774 		spec->init_hook(codec);
775 
776 	spec->gen.skip_verbs = 1; /* applied in below */
777 	snd_hda_gen_init(codec);
778 	alc_fix_pll(codec);
779 	alc_auto_init_amp(codec, spec->init_amp);
780 	snd_hda_apply_verbs(codec); /* apply verbs here after own init */
781 
782 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
783 
784 	return 0;
785 }
786 EXPORT_SYMBOL_NS_GPL(alc_init, "SND_HDA_CODEC_REALTEK");
787 
788 void alc_shutup(struct hda_codec *codec)
789 {
790 	struct alc_spec *spec = codec->spec;
791 
792 	if (!snd_hda_get_bool_hint(codec, "shutup"))
793 		return; /* disabled explicitly by hints */
794 
795 	if (spec && spec->shutup)
796 		spec->shutup(codec);
797 	else
798 		alc_shutup_pins(codec);
799 }
800 EXPORT_SYMBOL_NS_GPL(alc_shutup, "SND_HDA_CODEC_REALTEK");
801 
802 void alc_power_eapd(struct hda_codec *codec)
803 {
804 	alc_auto_setup_eapd(codec, false);
805 }
806 EXPORT_SYMBOL_NS_GPL(alc_power_eapd, "SND_HDA_CODEC_REALTEK");
807 
808 int alc_suspend(struct hda_codec *codec)
809 {
810 	struct alc_spec *spec = codec->spec;
811 	alc_shutup(codec);
812 	if (spec && spec->power_hook)
813 		spec->power_hook(codec);
814 	return 0;
815 }
816 EXPORT_SYMBOL_NS_GPL(alc_suspend, "SND_HDA_CODEC_REALTEK");
817 
818 int alc_resume(struct hda_codec *codec)
819 {
820 	struct alc_spec *spec = codec->spec;
821 
822 	if (!spec->no_depop_delay)
823 		msleep(150); /* to avoid pop noise */
824 	snd_hda_codec_init(codec);
825 	snd_hda_regmap_sync(codec);
826 	hda_call_check_power_status(codec, 0x01);
827 	return 0;
828 }
829 EXPORT_SYMBOL_NS_GPL(alc_resume, "SND_HDA_CODEC_REALTEK");
830 
831 /*
832  * Rename codecs appropriately from COEF value or subvendor id
833  */
834 struct alc_codec_rename_table {
835 	unsigned int vendor_id;
836 	unsigned short coef_mask;
837 	unsigned short coef_bits;
838 	const char *name;
839 };
840 
841 struct alc_codec_rename_pci_table {
842 	unsigned int codec_vendor_id;
843 	unsigned short pci_subvendor;
844 	unsigned short pci_subdevice;
845 	const char *name;
846 };
847 
848 static const struct alc_codec_rename_table rename_tbl[] = {
849 	{ 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
850 	{ 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
851 	{ 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
852 	{ 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
853 	{ 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
854 	{ 0x10ec0269, 0xffff, 0xa023, "ALC259" },
855 	{ 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
856 	{ 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
857 	{ 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
858 	{ 0x10ec0662, 0xffff, 0x4020, "ALC656" },
859 	{ 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
860 	{ 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
861 	{ 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
862 	{ 0x10ec0899, 0x2000, 0x2000, "ALC899" },
863 	{ 0x10ec0892, 0xffff, 0x8020, "ALC661" },
864 	{ 0x10ec0892, 0xffff, 0x8011, "ALC661" },
865 	{ 0x10ec0892, 0xffff, 0x4011, "ALC656" },
866 	{ } /* terminator */
867 };
868 
869 static const struct alc_codec_rename_pci_table rename_pci_tbl[] = {
870 	{ 0x10ec0280, 0x1028, 0, "ALC3220" },
871 	{ 0x10ec0282, 0x1028, 0, "ALC3221" },
872 	{ 0x10ec0283, 0x1028, 0, "ALC3223" },
873 	{ 0x10ec0288, 0x1028, 0, "ALC3263" },
874 	{ 0x10ec0292, 0x1028, 0, "ALC3226" },
875 	{ 0x10ec0293, 0x1028, 0, "ALC3235" },
876 	{ 0x10ec0255, 0x1028, 0, "ALC3234" },
877 	{ 0x10ec0668, 0x1028, 0, "ALC3661" },
878 	{ 0x10ec0275, 0x1028, 0, "ALC3260" },
879 	{ 0x10ec0899, 0x1028, 0, "ALC3861" },
880 	{ 0x10ec0298, 0x1028, 0, "ALC3266" },
881 	{ 0x10ec0236, 0x1028, 0, "ALC3204" },
882 	{ 0x10ec0256, 0x1028, 0, "ALC3246" },
883 	{ 0x10ec0225, 0x1028, 0, "ALC3253" },
884 	{ 0x10ec0295, 0x1028, 0, "ALC3254" },
885 	{ 0x10ec0299, 0x1028, 0, "ALC3271" },
886 	{ 0x10ec0670, 0x1025, 0, "ALC669X" },
887 	{ 0x10ec0676, 0x1025, 0, "ALC679X" },
888 	{ 0x10ec0282, 0x1043, 0, "ALC3229" },
889 	{ 0x10ec0233, 0x1043, 0, "ALC3236" },
890 	{ 0x10ec0280, 0x103c, 0, "ALC3228" },
891 	{ 0x10ec0282, 0x103c, 0, "ALC3227" },
892 	{ 0x10ec0286, 0x103c, 0, "ALC3242" },
893 	{ 0x10ec0290, 0x103c, 0, "ALC3241" },
894 	{ 0x10ec0668, 0x103c, 0, "ALC3662" },
895 	{ 0x10ec0283, 0x17aa, 0, "ALC3239" },
896 	{ 0x10ec0292, 0x17aa, 0, "ALC3232" },
897 	{ 0x10ec0257, 0x12f0, 0, "ALC3328" },
898 	{ } /* terminator */
899 };
900 
901 static int alc_codec_rename_from_preset(struct hda_codec *codec)
902 {
903 	const struct alc_codec_rename_table *p;
904 	const struct alc_codec_rename_pci_table *q;
905 
906 	for (p = rename_tbl; p->vendor_id; p++) {
907 		if (p->vendor_id != codec->core.vendor_id)
908 			continue;
909 		if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
910 			return alc_codec_rename(codec, p->name);
911 	}
912 
913 	if (!codec->bus->pci)
914 		return 0;
915 	for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
916 		if (q->codec_vendor_id != codec->core.vendor_id)
917 			continue;
918 		if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
919 			continue;
920 		if (!q->pci_subdevice ||
921 		    q->pci_subdevice == codec->bus->pci->subsystem_device)
922 			return alc_codec_rename(codec, q->name);
923 	}
924 
925 	return 0;
926 }
927 
928 /*
929  * Digital-beep handlers
930  */
931 #ifdef CONFIG_SND_HDA_INPUT_BEEP
932 
933 /* additional beep mixers; private_value will be overwritten */
934 static const struct snd_kcontrol_new alc_beep_mixer[] = {
935 	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
936 	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
937 };
938 
939 /* set up and create beep controls */
940 int alc_set_beep_amp(struct alc_spec *spec, hda_nid_t nid, int idx, int dir)
941 {
942 	struct snd_kcontrol_new *knew;
943 	unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
944 	int i;
945 
946 	for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) {
947 		knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
948 					    &alc_beep_mixer[i]);
949 		if (!knew)
950 			return -ENOMEM;
951 		knew->private_value = beep_amp;
952 	}
953 	return 0;
954 }
955 EXPORT_SYMBOL_NS_GPL(alc_set_beep_amp, "SND_HDA_CODEC_REALTEK");
956 
957 static const struct snd_pci_quirk beep_allow_list[] = {
958 	SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
959 	SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
960 	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
961 	SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
962 	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
963 	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
964 	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
965 	SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
966 	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
967 	/* denylist -- no beep available */
968 	SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0),
969 	SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0),
970 	{}
971 };
972 
973 int alc_has_cdefine_beep(struct hda_codec *codec)
974 {
975 	struct alc_spec *spec = codec->spec;
976 	const struct snd_pci_quirk *q;
977 	q = snd_pci_quirk_lookup(codec->bus->pci, beep_allow_list);
978 	if (q)
979 		return q->value;
980 	return spec->cdefine.enable_pcbeep;
981 }
982 EXPORT_SYMBOL_NS_GPL(alc_has_cdefine_beep, "SND_HDA_CODEC_REALTEK");
983 
984 #endif /* CONFIG_SND_HDA_INPUT_BEEP */
985 
986 /* parse the BIOS configuration and set up the alc_spec */
987 /* return 1 if successful, 0 if the proper config is not found,
988  * or a negative error code
989  */
990 int alc_parse_auto_config(struct hda_codec *codec,
991 			  const hda_nid_t *ignore_nids,
992 			  const hda_nid_t *ssid_nids)
993 {
994 	struct alc_spec *spec = codec->spec;
995 	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
996 	int err;
997 
998 	err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
999 				       spec->parse_flags);
1000 	if (err < 0)
1001 		return err;
1002 
1003 	if (ssid_nids)
1004 		alc_ssid_check(codec, ssid_nids);
1005 
1006 	err = snd_hda_gen_parse_auto_config(codec, cfg);
1007 	if (err < 0)
1008 		return err;
1009 
1010 	return 1;
1011 }
1012 EXPORT_SYMBOL_NS_GPL(alc_parse_auto_config, "SND_HDA_CODEC_REALTEK");
1013 
1014 /* common preparation job for alc_spec */
1015 int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1016 {
1017 	struct alc_spec *spec = kzalloc_obj(*spec);
1018 	int err;
1019 
1020 	if (!spec)
1021 		return -ENOMEM;
1022 	codec->spec = spec;
1023 	snd_hda_gen_spec_init(&spec->gen);
1024 	spec->gen.mixer_nid = mixer_nid;
1025 	spec->gen.own_eapd_ctl = 1;
1026 	codec->single_adc_amp = 1;
1027 	/* FIXME: do we need this for all Realtek codec models? */
1028 	codec->spdif_status_reset = 1;
1029 	codec->forced_resume = 1;
1030 	mutex_init(&spec->coef_mutex);
1031 
1032 	err = alc_codec_rename_from_preset(codec);
1033 	if (err < 0) {
1034 		kfree(spec);
1035 		return err;
1036 	}
1037 	return 0;
1038 }
1039 EXPORT_SYMBOL_NS_GPL(alc_alloc_spec, "SND_HDA_CODEC_REALTEK");
1040 
1041 /* For dual-codec configuration, we need to disable some features to avoid
1042  * conflicts of kctls and PCM streams
1043  */
1044 void alc_fixup_dual_codecs(struct hda_codec *codec,
1045 			   const struct hda_fixup *fix, int action)
1046 {
1047 	struct alc_spec *spec = codec->spec;
1048 
1049 	if (action != HDA_FIXUP_ACT_PRE_PROBE)
1050 		return;
1051 	/* disable vmaster */
1052 	spec->gen.suppress_vmaster = 1;
1053 	/* auto-mute and auto-mic switch don't work with multiple codecs */
1054 	spec->gen.suppress_auto_mute = 1;
1055 	spec->gen.suppress_auto_mic = 1;
1056 	/* disable aamix as well */
1057 	spec->gen.mixer_nid = 0;
1058 	/* add location prefix to avoid conflicts */
1059 	codec->force_pin_prefix = 1;
1060 }
1061 EXPORT_SYMBOL_NS_GPL(alc_fixup_dual_codecs, "SND_HDA_CODEC_REALTEK");
1062 
1063 static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
1064 	{ .channels = 2,
1065 	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
1066 	{ .channels = 4,
1067 	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
1068 		   SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
1069 	{ }
1070 };
1071 
1072 /* override the 2.1 chmap */
1073 void alc_fixup_bass_chmap(struct hda_codec *codec,
1074 			  const struct hda_fixup *fix, int action)
1075 {
1076 	if (action == HDA_FIXUP_ACT_BUILD) {
1077 		struct alc_spec *spec = codec->spec;
1078 		spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
1079 	}
1080 }
1081 EXPORT_SYMBOL_NS_GPL(alc_fixup_bass_chmap, "SND_HDA_CODEC_REALTEK");
1082 
1083 /* exported as it's used by multiple codecs */
1084 void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
1085 				  const struct hda_fixup *fix,
1086 				  int action)
1087 {
1088 	alc_fixup_dual_codecs(codec, fix, action);
1089 	switch (action) {
1090 	case HDA_FIXUP_ACT_PRE_PROBE:
1091 		/* override card longname to provide a unique UCM profile */
1092 		strscpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
1093 		break;
1094 	case HDA_FIXUP_ACT_BUILD:
1095 		/* rename Capture controls depending on the codec */
1096 		rename_ctl(codec, "Capture Volume",
1097 			   codec->addr == 0 ?
1098 			   "Rear-Panel Capture Volume" :
1099 			   "Front-Panel Capture Volume");
1100 		rename_ctl(codec, "Capture Switch",
1101 			   codec->addr == 0 ?
1102 			   "Rear-Panel Capture Switch" :
1103 			   "Front-Panel Capture Switch");
1104 		break;
1105 	}
1106 }
1107 EXPORT_SYMBOL_NS_GPL(alc1220_fixup_gb_dual_codecs, "SND_HDA_CODEC_REALTEK");
1108 
1109 void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
1110 					    const struct hda_fixup *fix,
1111 					    int action)
1112 {
1113 	alc_fixup_dual_codecs(codec, fix, action);
1114 	switch (action) {
1115 	case HDA_FIXUP_ACT_PRE_PROBE:
1116 		/* override card longname to provide a unique UCM profile */
1117 		strscpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs");
1118 		break;
1119 	case HDA_FIXUP_ACT_BUILD:
1120 		/* rename Capture controls depending on the codec */
1121 		rename_ctl(codec, "Capture Volume",
1122 			   codec->addr == 0 ?
1123 			   "Rear-Panel Capture Volume" :
1124 			   "Front-Panel Capture Volume");
1125 		rename_ctl(codec, "Capture Switch",
1126 			   codec->addr == 0 ?
1127 			   "Rear-Panel Capture Switch" :
1128 			   "Front-Panel Capture Switch");
1129 		break;
1130 	}
1131 }
1132 EXPORT_SYMBOL_NS_GPL(alc233_alc662_fixup_lenovo_dual_codecs, "SND_HDA_CODEC_REALTEK");
1133 
1134 static void alc_shutup_dell_xps13(struct hda_codec *codec)
1135 {
1136 	struct alc_spec *spec = codec->spec;
1137 	int hp_pin = alc_get_hp_pin(spec);
1138 
1139 	/* Prevent pop noises when headphones are plugged in */
1140 	snd_hda_codec_write(codec, hp_pin, 0,
1141 			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
1142 	msleep(20);
1143 }
1144 
1145 void alc_fixup_dell_xps13(struct hda_codec *codec,
1146 			  const struct hda_fixup *fix, int action)
1147 {
1148 	struct alc_spec *spec = codec->spec;
1149 	struct hda_input_mux *imux = &spec->gen.input_mux;
1150 	int i;
1151 
1152 	switch (action) {
1153 	case HDA_FIXUP_ACT_PRE_PROBE:
1154 		/* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
1155 		 * it causes a click noise at start up
1156 		 */
1157 		snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
1158 		spec->shutup = alc_shutup_dell_xps13;
1159 		break;
1160 	case HDA_FIXUP_ACT_PROBE:
1161 		/* Make the internal mic the default input source. */
1162 		for (i = 0; i < imux->num_items; i++) {
1163 			if (spec->gen.imux_pins[i] == 0x12) {
1164 				spec->gen.cur_mux[0] = i;
1165 				break;
1166 			}
1167 		}
1168 		break;
1169 	}
1170 }
1171 EXPORT_SYMBOL_NS_GPL(alc_fixup_dell_xps13, "SND_HDA_CODEC_REALTEK");
1172 
1173 /*
1174  * headset handling
1175  */
1176 
1177 static void alc_hp_mute_disable(struct hda_codec *codec, unsigned int delay)
1178 {
1179 	if (delay <= 0)
1180 		delay = 75;
1181 	snd_hda_codec_write(codec, 0x21, 0,
1182 		    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
1183 	msleep(delay);
1184 	snd_hda_codec_write(codec, 0x21, 0,
1185 		    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
1186 	msleep(delay);
1187 }
1188 
1189 static void alc_hp_enable_unmute(struct hda_codec *codec, unsigned int delay)
1190 {
1191 	if (delay <= 0)
1192 		delay = 75;
1193 	snd_hda_codec_write(codec, 0x21, 0,
1194 		    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1195 	msleep(delay);
1196 	snd_hda_codec_write(codec, 0x21, 0,
1197 		    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
1198 	msleep(delay);
1199 }
1200 
1201 static const struct coef_fw alc225_pre_hsmode[] = {
1202 	UPDATE_COEF(0x4a, 1<<8, 0),
1203 	UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
1204 	UPDATE_COEF(0x63, 3<<14, 3<<14),
1205 	UPDATE_COEF(0x4a, 3<<4, 2<<4),
1206 	UPDATE_COEF(0x4a, 3<<10, 3<<10),
1207 	UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
1208 	UPDATE_COEF(0x4a, 3<<10, 0),
1209 	{}
1210 };
1211 
1212 static void alc_headset_mode_unplugged(struct hda_codec *codec)
1213 {
1214 	struct alc_spec *spec = codec->spec;
1215 	static const struct coef_fw coef0255[] = {
1216 		WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
1217 		WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
1218 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
1219 		WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
1220 		WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
1221 		{}
1222 	};
1223 	static const struct coef_fw coef0256[] = {
1224 		WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
1225 		WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
1226 		WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
1227 		WRITE_COEFEX(0x57, 0x03, 0x09a3), /* Direct Drive HP Amp control */
1228 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
1229 		{}
1230 	};
1231 	static const struct coef_fw coef0233[] = {
1232 		WRITE_COEF(0x1b, 0x0c0b),
1233 		WRITE_COEF(0x45, 0xc429),
1234 		UPDATE_COEF(0x35, 0x4000, 0),
1235 		WRITE_COEF(0x06, 0x2104),
1236 		WRITE_COEF(0x1a, 0x0001),
1237 		WRITE_COEF(0x26, 0x0004),
1238 		WRITE_COEF(0x32, 0x42a3),
1239 		{}
1240 	};
1241 	static const struct coef_fw coef0288[] = {
1242 		UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
1243 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1244 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1245 		UPDATE_COEF(0x66, 0x0008, 0),
1246 		UPDATE_COEF(0x67, 0x2000, 0),
1247 		{}
1248 	};
1249 	static const struct coef_fw coef0298[] = {
1250 		UPDATE_COEF(0x19, 0x1300, 0x0300),
1251 		{}
1252 	};
1253 	static const struct coef_fw coef0292[] = {
1254 		WRITE_COEF(0x76, 0x000e),
1255 		WRITE_COEF(0x6c, 0x2400),
1256 		WRITE_COEF(0x18, 0x7308),
1257 		WRITE_COEF(0x6b, 0xc429),
1258 		{}
1259 	};
1260 	static const struct coef_fw coef0293[] = {
1261 		UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
1262 		UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
1263 		UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
1264 		UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
1265 		WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
1266 		UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
1267 		{}
1268 	};
1269 	static const struct coef_fw coef0668[] = {
1270 		WRITE_COEF(0x15, 0x0d40),
1271 		WRITE_COEF(0xb7, 0x802b),
1272 		{}
1273 	};
1274 	static const struct coef_fw coef0225[] = {
1275 		UPDATE_COEF(0x63, 3<<14, 0),
1276 		{}
1277 	};
1278 	static const struct coef_fw coef0274[] = {
1279 		UPDATE_COEF(0x4a, 0x0100, 0),
1280 		UPDATE_COEFEX(0x57, 0x05, 0x4000, 0),
1281 		UPDATE_COEF(0x6b, 0xf000, 0x5000),
1282 		UPDATE_COEF(0x4a, 0x0010, 0),
1283 		UPDATE_COEF(0x4a, 0x0c00, 0x0c00),
1284 		WRITE_COEF(0x45, 0x5289),
1285 		UPDATE_COEF(0x4a, 0x0c00, 0),
1286 		{}
1287 	};
1288 
1289 	if (spec->no_internal_mic_pin) {
1290 		alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
1291 		return;
1292 	}
1293 
1294 	switch (codec->core.vendor_id) {
1295 	case 0x10ec0255:
1296 		alc_process_coef_fw(codec, coef0255);
1297 		break;
1298 	case 0x10ec0230:
1299 	case 0x10ec0236:
1300 	case 0x10ec0256:
1301 	case 0x19e58326:
1302 		alc_hp_mute_disable(codec, 75);
1303 		alc_process_coef_fw(codec, coef0256);
1304 		break;
1305 	case 0x10ec0234:
1306 	case 0x10ec0274:
1307 	case 0x10ec0294:
1308 		alc_process_coef_fw(codec, coef0274);
1309 		break;
1310 	case 0x10ec0233:
1311 	case 0x10ec0283:
1312 		alc_process_coef_fw(codec, coef0233);
1313 		break;
1314 	case 0x10ec0286:
1315 	case 0x10ec0288:
1316 		alc_process_coef_fw(codec, coef0288);
1317 		break;
1318 	case 0x10ec0298:
1319 		alc_process_coef_fw(codec, coef0298);
1320 		alc_process_coef_fw(codec, coef0288);
1321 		break;
1322 	case 0x10ec0292:
1323 		alc_process_coef_fw(codec, coef0292);
1324 		break;
1325 	case 0x10ec0293:
1326 		alc_process_coef_fw(codec, coef0293);
1327 		break;
1328 	case 0x10ec0668:
1329 		alc_process_coef_fw(codec, coef0668);
1330 		break;
1331 	case 0x10ec0215:
1332 	case 0x10ec0225:
1333 	case 0x10ec0285:
1334 	case 0x10ec0295:
1335 	case 0x10ec0289:
1336 	case 0x10ec0299:
1337 		alc_hp_mute_disable(codec, 75);
1338 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1339 		alc_process_coef_fw(codec, coef0225);
1340 		break;
1341 	case 0x10ec0867:
1342 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1343 		break;
1344 	}
1345 	codec_dbg(codec, "Headset jack set to unplugged mode.\n");
1346 }
1347 
1348 
1349 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
1350 				    hda_nid_t mic_pin)
1351 {
1352 	static const struct coef_fw coef0255[] = {
1353 		WRITE_COEFEX(0x57, 0x03, 0x8aa6),
1354 		WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
1355 		{}
1356 	};
1357 	static const struct coef_fw coef0256[] = {
1358 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
1359 		WRITE_COEFEX(0x57, 0x03, 0x09a3),
1360 		WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
1361 		{}
1362 	};
1363 	static const struct coef_fw coef0233[] = {
1364 		UPDATE_COEF(0x35, 0, 1<<14),
1365 		WRITE_COEF(0x06, 0x2100),
1366 		WRITE_COEF(0x1a, 0x0021),
1367 		WRITE_COEF(0x26, 0x008c),
1368 		{}
1369 	};
1370 	static const struct coef_fw coef0288[] = {
1371 		UPDATE_COEF(0x4f, 0x00c0, 0),
1372 		UPDATE_COEF(0x50, 0x2000, 0),
1373 		UPDATE_COEF(0x56, 0x0006, 0),
1374 		UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
1375 		UPDATE_COEF(0x66, 0x0008, 0x0008),
1376 		UPDATE_COEF(0x67, 0x2000, 0x2000),
1377 		{}
1378 	};
1379 	static const struct coef_fw coef0292[] = {
1380 		WRITE_COEF(0x19, 0xa208),
1381 		WRITE_COEF(0x2e, 0xacf0),
1382 		{}
1383 	};
1384 	static const struct coef_fw coef0293[] = {
1385 		UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
1386 		UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
1387 		UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
1388 		{}
1389 	};
1390 	static const struct coef_fw coef0688[] = {
1391 		WRITE_COEF(0xb7, 0x802b),
1392 		WRITE_COEF(0xb5, 0x1040),
1393 		UPDATE_COEF(0xc3, 0, 1<<12),
1394 		{}
1395 	};
1396 	static const struct coef_fw coef0225[] = {
1397 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
1398 		UPDATE_COEF(0x4a, 3<<4, 2<<4),
1399 		UPDATE_COEF(0x63, 3<<14, 0),
1400 		{}
1401 	};
1402 	static const struct coef_fw coef0274[] = {
1403 		UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
1404 		UPDATE_COEF(0x4a, 0x0010, 0),
1405 		UPDATE_COEF(0x6b, 0xf000, 0),
1406 		{}
1407 	};
1408 
1409 	switch (codec->core.vendor_id) {
1410 	case 0x10ec0255:
1411 		alc_write_coef_idx(codec, 0x45, 0xc489);
1412 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1413 		alc_process_coef_fw(codec, coef0255);
1414 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1415 		break;
1416 	case 0x10ec0230:
1417 	case 0x10ec0236:
1418 	case 0x10ec0256:
1419 	case 0x19e58326:
1420 		alc_write_coef_idx(codec, 0x45, 0xc489);
1421 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1422 		alc_process_coef_fw(codec, coef0256);
1423 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1424 		break;
1425 	case 0x10ec0234:
1426 	case 0x10ec0274:
1427 	case 0x10ec0294:
1428 		alc_write_coef_idx(codec, 0x45, 0x4689);
1429 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1430 		alc_process_coef_fw(codec, coef0274);
1431 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1432 		break;
1433 	case 0x10ec0233:
1434 	case 0x10ec0283:
1435 		alc_write_coef_idx(codec, 0x45, 0xc429);
1436 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1437 		alc_process_coef_fw(codec, coef0233);
1438 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1439 		break;
1440 	case 0x10ec0286:
1441 	case 0x10ec0288:
1442 	case 0x10ec0298:
1443 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1444 		alc_process_coef_fw(codec, coef0288);
1445 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1446 		break;
1447 	case 0x10ec0292:
1448 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1449 		alc_process_coef_fw(codec, coef0292);
1450 		break;
1451 	case 0x10ec0293:
1452 		/* Set to TRS mode */
1453 		alc_write_coef_idx(codec, 0x45, 0xc429);
1454 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1455 		alc_process_coef_fw(codec, coef0293);
1456 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1457 		break;
1458 	case 0x10ec0867:
1459 		alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
1460 		fallthrough;
1461 	case 0x10ec0221:
1462 	case 0x10ec0662:
1463 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1464 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1465 		break;
1466 	case 0x10ec0668:
1467 		alc_write_coef_idx(codec, 0x11, 0x0001);
1468 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1469 		alc_process_coef_fw(codec, coef0688);
1470 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1471 		break;
1472 	case 0x10ec0215:
1473 	case 0x10ec0225:
1474 	case 0x10ec0285:
1475 	case 0x10ec0295:
1476 	case 0x10ec0289:
1477 	case 0x10ec0299:
1478 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1479 		alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
1480 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1481 		alc_process_coef_fw(codec, coef0225);
1482 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1483 		break;
1484 	}
1485 	codec_dbg(codec, "Headset jack set to mic-in mode.\n");
1486 }
1487 
1488 static void alc_headset_mode_default(struct hda_codec *codec)
1489 {
1490 	static const struct coef_fw coef0225[] = {
1491 		UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
1492 		UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
1493 		UPDATE_COEF(0x49, 3<<8, 0<<8),
1494 		UPDATE_COEF(0x4a, 3<<4, 3<<4),
1495 		UPDATE_COEF(0x63, 3<<14, 0),
1496 		UPDATE_COEF(0x67, 0xf000, 0x3000),
1497 		{}
1498 	};
1499 	static const struct coef_fw coef0255[] = {
1500 		WRITE_COEF(0x45, 0xc089),
1501 		WRITE_COEF(0x45, 0xc489),
1502 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
1503 		WRITE_COEF(0x49, 0x0049),
1504 		{}
1505 	};
1506 	static const struct coef_fw coef0256[] = {
1507 		WRITE_COEF(0x45, 0xc489),
1508 		WRITE_COEFEX(0x57, 0x03, 0x0da3),
1509 		WRITE_COEF(0x49, 0x0049),
1510 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
1511 		WRITE_COEF(0x06, 0x6100),
1512 		{}
1513 	};
1514 	static const struct coef_fw coef0233[] = {
1515 		WRITE_COEF(0x06, 0x2100),
1516 		WRITE_COEF(0x32, 0x4ea3),
1517 		{}
1518 	};
1519 	static const struct coef_fw coef0288[] = {
1520 		UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
1521 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1522 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1523 		UPDATE_COEF(0x66, 0x0008, 0),
1524 		UPDATE_COEF(0x67, 0x2000, 0),
1525 		{}
1526 	};
1527 	static const struct coef_fw coef0292[] = {
1528 		WRITE_COEF(0x76, 0x000e),
1529 		WRITE_COEF(0x6c, 0x2400),
1530 		WRITE_COEF(0x6b, 0xc429),
1531 		WRITE_COEF(0x18, 0x7308),
1532 		{}
1533 	};
1534 	static const struct coef_fw coef0293[] = {
1535 		UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
1536 		WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
1537 		UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
1538 		{}
1539 	};
1540 	static const struct coef_fw coef0688[] = {
1541 		WRITE_COEF(0x11, 0x0041),
1542 		WRITE_COEF(0x15, 0x0d40),
1543 		WRITE_COEF(0xb7, 0x802b),
1544 		{}
1545 	};
1546 	static const struct coef_fw coef0274[] = {
1547 		WRITE_COEF(0x45, 0x4289),
1548 		UPDATE_COEF(0x4a, 0x0010, 0x0010),
1549 		UPDATE_COEF(0x6b, 0x0f00, 0),
1550 		UPDATE_COEF(0x49, 0x0300, 0x0300),
1551 		{}
1552 	};
1553 
1554 	switch (codec->core.vendor_id) {
1555 	case 0x10ec0215:
1556 	case 0x10ec0225:
1557 	case 0x10ec0285:
1558 	case 0x10ec0295:
1559 	case 0x10ec0289:
1560 	case 0x10ec0299:
1561 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1562 		alc_process_coef_fw(codec, coef0225);
1563 		alc_hp_enable_unmute(codec, 75);
1564 		break;
1565 	case 0x10ec0255:
1566 		alc_process_coef_fw(codec, coef0255);
1567 		break;
1568 	case 0x10ec0230:
1569 	case 0x10ec0236:
1570 	case 0x10ec0256:
1571 	case 0x19e58326:
1572 		alc_write_coef_idx(codec, 0x1b, 0x0e4b);
1573 		alc_write_coef_idx(codec, 0x45, 0xc089);
1574 		msleep(50);
1575 		alc_process_coef_fw(codec, coef0256);
1576 		alc_hp_enable_unmute(codec, 75);
1577 		break;
1578 	case 0x10ec0234:
1579 	case 0x10ec0274:
1580 	case 0x10ec0294:
1581 		alc_process_coef_fw(codec, coef0274);
1582 		break;
1583 	case 0x10ec0233:
1584 	case 0x10ec0283:
1585 		alc_process_coef_fw(codec, coef0233);
1586 		break;
1587 	case 0x10ec0286:
1588 	case 0x10ec0288:
1589 	case 0x10ec0298:
1590 		alc_process_coef_fw(codec, coef0288);
1591 		break;
1592 	case 0x10ec0292:
1593 		alc_process_coef_fw(codec, coef0292);
1594 		break;
1595 	case 0x10ec0293:
1596 		alc_process_coef_fw(codec, coef0293);
1597 		break;
1598 	case 0x10ec0668:
1599 		alc_process_coef_fw(codec, coef0688);
1600 		break;
1601 	case 0x10ec0867:
1602 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1603 		break;
1604 	}
1605 	codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
1606 }
1607 
1608 /* Iphone type */
1609 static void alc_headset_mode_ctia(struct hda_codec *codec)
1610 {
1611 	int val;
1612 
1613 	static const struct coef_fw coef0255[] = {
1614 		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
1615 		WRITE_COEF(0x1b, 0x0c2b),
1616 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
1617 		{}
1618 	};
1619 	static const struct coef_fw coef0256[] = {
1620 		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
1621 		WRITE_COEF(0x1b, 0x0e6b),
1622 		{}
1623 	};
1624 	static const struct coef_fw coef0233[] = {
1625 		WRITE_COEF(0x45, 0xd429),
1626 		WRITE_COEF(0x1b, 0x0c2b),
1627 		WRITE_COEF(0x32, 0x4ea3),
1628 		{}
1629 	};
1630 	static const struct coef_fw coef0288[] = {
1631 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1632 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1633 		UPDATE_COEF(0x66, 0x0008, 0),
1634 		UPDATE_COEF(0x67, 0x2000, 0),
1635 		{}
1636 	};
1637 	static const struct coef_fw coef0292[] = {
1638 		WRITE_COEF(0x6b, 0xd429),
1639 		WRITE_COEF(0x76, 0x0008),
1640 		WRITE_COEF(0x18, 0x7388),
1641 		{}
1642 	};
1643 	static const struct coef_fw coef0293[] = {
1644 		WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
1645 		UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
1646 		{}
1647 	};
1648 	static const struct coef_fw coef0688[] = {
1649 		WRITE_COEF(0x11, 0x0001),
1650 		WRITE_COEF(0x15, 0x0d60),
1651 		WRITE_COEF(0xc3, 0x0000),
1652 		{}
1653 	};
1654 	static const struct coef_fw coef0225_1[] = {
1655 		UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
1656 		UPDATE_COEF(0x63, 3<<14, 2<<14),
1657 		{}
1658 	};
1659 	static const struct coef_fw coef0225_2[] = {
1660 		UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
1661 		UPDATE_COEF(0x63, 3<<14, 1<<14),
1662 		{}
1663 	};
1664 
1665 	switch (codec->core.vendor_id) {
1666 	case 0x10ec0255:
1667 		alc_process_coef_fw(codec, coef0255);
1668 		break;
1669 	case 0x10ec0230:
1670 	case 0x10ec0236:
1671 	case 0x10ec0256:
1672 	case 0x19e58326:
1673 		alc_process_coef_fw(codec, coef0256);
1674 		alc_hp_enable_unmute(codec, 75);
1675 		break;
1676 	case 0x10ec0234:
1677 	case 0x10ec0274:
1678 	case 0x10ec0294:
1679 		alc_write_coef_idx(codec, 0x45, 0xd689);
1680 		break;
1681 	case 0x10ec0233:
1682 	case 0x10ec0283:
1683 		alc_process_coef_fw(codec, coef0233);
1684 		break;
1685 	case 0x10ec0298:
1686 		val = alc_read_coef_idx(codec, 0x50);
1687 		if (val & (1 << 12)) {
1688 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
1689 			alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
1690 			msleep(300);
1691 		} else {
1692 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
1693 			alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
1694 			msleep(300);
1695 		}
1696 		break;
1697 	case 0x10ec0286:
1698 	case 0x10ec0288:
1699 		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
1700 		msleep(300);
1701 		alc_process_coef_fw(codec, coef0288);
1702 		break;
1703 	case 0x10ec0292:
1704 		alc_process_coef_fw(codec, coef0292);
1705 		break;
1706 	case 0x10ec0293:
1707 		alc_process_coef_fw(codec, coef0293);
1708 		break;
1709 	case 0x10ec0668:
1710 		alc_process_coef_fw(codec, coef0688);
1711 		break;
1712 	case 0x10ec0215:
1713 	case 0x10ec0225:
1714 	case 0x10ec0285:
1715 	case 0x10ec0295:
1716 	case 0x10ec0289:
1717 	case 0x10ec0299:
1718 		val = alc_read_coef_idx(codec, 0x45);
1719 		if (val & (1 << 9))
1720 			alc_process_coef_fw(codec, coef0225_2);
1721 		else
1722 			alc_process_coef_fw(codec, coef0225_1);
1723 		alc_hp_enable_unmute(codec, 75);
1724 		break;
1725 	case 0x10ec0867:
1726 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1727 		break;
1728 	}
1729 	codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
1730 }
1731 
1732 /* Nokia type */
1733 static void alc_headset_mode_omtp(struct hda_codec *codec)
1734 {
1735 	static const struct coef_fw coef0255[] = {
1736 		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
1737 		WRITE_COEF(0x1b, 0x0c2b),
1738 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
1739 		{}
1740 	};
1741 	static const struct coef_fw coef0256[] = {
1742 		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
1743 		WRITE_COEF(0x1b, 0x0e6b),
1744 		{}
1745 	};
1746 	static const struct coef_fw coef0233[] = {
1747 		WRITE_COEF(0x45, 0xe429),
1748 		WRITE_COEF(0x1b, 0x0c2b),
1749 		WRITE_COEF(0x32, 0x4ea3),
1750 		{}
1751 	};
1752 	static const struct coef_fw coef0288[] = {
1753 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1754 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1755 		UPDATE_COEF(0x66, 0x0008, 0),
1756 		UPDATE_COEF(0x67, 0x2000, 0),
1757 		{}
1758 	};
1759 	static const struct coef_fw coef0292[] = {
1760 		WRITE_COEF(0x6b, 0xe429),
1761 		WRITE_COEF(0x76, 0x0008),
1762 		WRITE_COEF(0x18, 0x7388),
1763 		{}
1764 	};
1765 	static const struct coef_fw coef0293[] = {
1766 		WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
1767 		UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
1768 		{}
1769 	};
1770 	static const struct coef_fw coef0688[] = {
1771 		WRITE_COEF(0x11, 0x0001),
1772 		WRITE_COEF(0x15, 0x0d50),
1773 		WRITE_COEF(0xc3, 0x0000),
1774 		{}
1775 	};
1776 	static const struct coef_fw coef0225[] = {
1777 		UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
1778 		UPDATE_COEF(0x63, 3<<14, 2<<14),
1779 		{}
1780 	};
1781 
1782 	switch (codec->core.vendor_id) {
1783 	case 0x10ec0255:
1784 		alc_process_coef_fw(codec, coef0255);
1785 		break;
1786 	case 0x10ec0230:
1787 	case 0x10ec0236:
1788 	case 0x10ec0256:
1789 	case 0x19e58326:
1790 		alc_process_coef_fw(codec, coef0256);
1791 		alc_hp_enable_unmute(codec, 75);
1792 		break;
1793 	case 0x10ec0234:
1794 	case 0x10ec0274:
1795 	case 0x10ec0294:
1796 		alc_write_coef_idx(codec, 0x45, 0xe689);
1797 		break;
1798 	case 0x10ec0233:
1799 	case 0x10ec0283:
1800 		alc_process_coef_fw(codec, coef0233);
1801 		break;
1802 	case 0x10ec0298:
1803 		alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
1804 		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
1805 		msleep(300);
1806 		break;
1807 	case 0x10ec0286:
1808 	case 0x10ec0288:
1809 		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
1810 		msleep(300);
1811 		alc_process_coef_fw(codec, coef0288);
1812 		break;
1813 	case 0x10ec0292:
1814 		alc_process_coef_fw(codec, coef0292);
1815 		break;
1816 	case 0x10ec0293:
1817 		alc_process_coef_fw(codec, coef0293);
1818 		break;
1819 	case 0x10ec0668:
1820 		alc_process_coef_fw(codec, coef0688);
1821 		break;
1822 	case 0x10ec0215:
1823 	case 0x10ec0225:
1824 	case 0x10ec0285:
1825 	case 0x10ec0295:
1826 	case 0x10ec0289:
1827 	case 0x10ec0299:
1828 		alc_process_coef_fw(codec, coef0225);
1829 		alc_hp_enable_unmute(codec, 75);
1830 		break;
1831 	}
1832 	codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
1833 }
1834 
1835 static void alc_determine_headset_type(struct hda_codec *codec)
1836 {
1837 	int val;
1838 	bool is_ctia = false;
1839 	struct alc_spec *spec = codec->spec;
1840 	static const struct coef_fw coef0255[] = {
1841 		WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
1842 		WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
1843  conteol) */
1844 		{}
1845 	};
1846 	static const struct coef_fw coef0288[] = {
1847 		UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
1848 		{}
1849 	};
1850 	static const struct coef_fw coef0298[] = {
1851 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1852 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1853 		UPDATE_COEF(0x66, 0x0008, 0),
1854 		UPDATE_COEF(0x67, 0x2000, 0),
1855 		UPDATE_COEF(0x19, 0x1300, 0x1300),
1856 		{}
1857 	};
1858 	static const struct coef_fw coef0293[] = {
1859 		UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
1860 		WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
1861 		{}
1862 	};
1863 	static const struct coef_fw coef0688[] = {
1864 		WRITE_COEF(0x11, 0x0001),
1865 		WRITE_COEF(0xb7, 0x802b),
1866 		WRITE_COEF(0x15, 0x0d60),
1867 		WRITE_COEF(0xc3, 0x0c00),
1868 		{}
1869 	};
1870 	static const struct coef_fw coef0274[] = {
1871 		UPDATE_COEF(0x4a, 0x0010, 0),
1872 		UPDATE_COEF(0x4a, 0x8000, 0),
1873 		WRITE_COEF(0x45, 0xd289),
1874 		UPDATE_COEF(0x49, 0x0300, 0x0300),
1875 		{}
1876 	};
1877 
1878 	if (spec->no_internal_mic_pin) {
1879 		alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
1880 		return;
1881 	}
1882 
1883 	switch (codec->core.vendor_id) {
1884 	case 0x10ec0255:
1885 		alc_process_coef_fw(codec, coef0255);
1886 		msleep(300);
1887 		val = alc_read_coef_idx(codec, 0x46);
1888 		is_ctia = (val & 0x0070) == 0x0070;
1889 		break;
1890 	case 0x10ec0230:
1891 	case 0x10ec0236:
1892 	case 0x10ec0256:
1893 	case 0x19e58326:
1894 		alc_write_coef_idx(codec, 0x1b, 0x0e4b);
1895 		alc_write_coef_idx(codec, 0x06, 0x6104);
1896 		alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
1897 
1898 		alc_process_coef_fw(codec, coef0255);
1899 		msleep(300);
1900 		val = alc_read_coef_idx(codec, 0x46);
1901 		is_ctia = (val & 0x0070) == 0x0070;
1902 		if (!is_ctia) {
1903 			alc_write_coef_idx(codec, 0x45, 0xe089);
1904 			msleep(100);
1905 			val = alc_read_coef_idx(codec, 0x46);
1906 			if ((val & 0x0070) == 0x0070)
1907 				is_ctia = false;
1908 			else
1909 				is_ctia = true;
1910 		}
1911 		alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
1912 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1913 		break;
1914 	case 0x10ec0234:
1915 	case 0x10ec0274:
1916 	case 0x10ec0294:
1917 		alc_process_coef_fw(codec, coef0274);
1918 		msleep(850);
1919 		val = alc_read_coef_idx(codec, 0x46);
1920 		is_ctia = (val & 0x00f0) == 0x00f0;
1921 		break;
1922 	case 0x10ec0233:
1923 	case 0x10ec0283:
1924 		alc_write_coef_idx(codec, 0x45, 0xd029);
1925 		msleep(300);
1926 		val = alc_read_coef_idx(codec, 0x46);
1927 		is_ctia = (val & 0x0070) == 0x0070;
1928 		break;
1929 	case 0x10ec0298:
1930 		snd_hda_codec_write(codec, 0x21, 0,
1931 			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
1932 		msleep(100);
1933 		snd_hda_codec_write(codec, 0x21, 0,
1934 			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
1935 		msleep(200);
1936 
1937 		val = alc_read_coef_idx(codec, 0x50);
1938 		if (val & (1 << 12)) {
1939 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
1940 			alc_process_coef_fw(codec, coef0288);
1941 			msleep(350);
1942 			val = alc_read_coef_idx(codec, 0x50);
1943 			is_ctia = (val & 0x0070) == 0x0070;
1944 		} else {
1945 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
1946 			alc_process_coef_fw(codec, coef0288);
1947 			msleep(350);
1948 			val = alc_read_coef_idx(codec, 0x50);
1949 			is_ctia = (val & 0x0070) == 0x0070;
1950 		}
1951 		alc_process_coef_fw(codec, coef0298);
1952 		snd_hda_codec_write(codec, 0x21, 0,
1953 			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
1954 		msleep(75);
1955 		snd_hda_codec_write(codec, 0x21, 0,
1956 			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
1957 		break;
1958 	case 0x10ec0286:
1959 	case 0x10ec0288:
1960 		alc_process_coef_fw(codec, coef0288);
1961 		msleep(350);
1962 		val = alc_read_coef_idx(codec, 0x50);
1963 		is_ctia = (val & 0x0070) == 0x0070;
1964 		break;
1965 	case 0x10ec0292:
1966 		alc_write_coef_idx(codec, 0x6b, 0xd429);
1967 		msleep(300);
1968 		val = alc_read_coef_idx(codec, 0x6c);
1969 		is_ctia = (val & 0x001c) == 0x001c;
1970 		break;
1971 	case 0x10ec0293:
1972 		alc_process_coef_fw(codec, coef0293);
1973 		msleep(300);
1974 		val = alc_read_coef_idx(codec, 0x46);
1975 		is_ctia = (val & 0x0070) == 0x0070;
1976 		break;
1977 	case 0x10ec0668:
1978 		alc_process_coef_fw(codec, coef0688);
1979 		msleep(300);
1980 		val = alc_read_coef_idx(codec, 0xbe);
1981 		is_ctia = (val & 0x1c02) == 0x1c02;
1982 		break;
1983 	case 0x10ec0215:
1984 	case 0x10ec0225:
1985 	case 0x10ec0285:
1986 	case 0x10ec0295:
1987 	case 0x10ec0289:
1988 	case 0x10ec0299:
1989 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1990 		alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
1991 		val = alc_read_coef_idx(codec, 0x45);
1992 		if (val & (1 << 9)) {
1993 			alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
1994 			alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
1995 			msleep(800);
1996 			val = alc_read_coef_idx(codec, 0x46);
1997 			is_ctia = (val & 0x00f0) == 0x00f0;
1998 		} else {
1999 			alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
2000 			alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
2001 			msleep(800);
2002 			val = alc_read_coef_idx(codec, 0x46);
2003 			is_ctia = (val & 0x00f0) == 0x00f0;
2004 		}
2005 		if (!is_ctia) {
2006 			alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x38<<10);
2007 			alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
2008 			msleep(100);
2009 			val = alc_read_coef_idx(codec, 0x46);
2010 			if ((val & 0x00f0) == 0x00f0)
2011 				is_ctia = false;
2012 			else
2013 				is_ctia = true;
2014 		}
2015 		alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
2016 		alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
2017 		alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
2018 		break;
2019 	case 0x10ec0867:
2020 		is_ctia = true;
2021 		break;
2022 	}
2023 
2024 	codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
2025 		  str_yes_no(is_ctia));
2026 	spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
2027 }
2028 
2029 static void alc_update_headset_mode(struct hda_codec *codec)
2030 {
2031 	struct alc_spec *spec = codec->spec;
2032 
2033 	hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
2034 	hda_nid_t hp_pin = alc_get_hp_pin(spec);
2035 
2036 	int new_headset_mode;
2037 
2038 	if (!snd_hda_jack_detect(codec, hp_pin))
2039 		new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
2040 	else if (mux_pin == spec->headset_mic_pin)
2041 		new_headset_mode = ALC_HEADSET_MODE_HEADSET;
2042 	else if (mux_pin == spec->headphone_mic_pin)
2043 		new_headset_mode = ALC_HEADSET_MODE_MIC;
2044 	else
2045 		new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
2046 
2047 	if (new_headset_mode == spec->current_headset_mode) {
2048 		snd_hda_gen_update_outputs(codec);
2049 		return;
2050 	}
2051 
2052 	switch (new_headset_mode) {
2053 	case ALC_HEADSET_MODE_UNPLUGGED:
2054 		alc_headset_mode_unplugged(codec);
2055 		spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
2056 		spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
2057 		spec->gen.hp_jack_present = false;
2058 		break;
2059 	case ALC_HEADSET_MODE_HEADSET:
2060 		if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
2061 			alc_determine_headset_type(codec);
2062 		if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
2063 			alc_headset_mode_ctia(codec);
2064 		else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
2065 			alc_headset_mode_omtp(codec);
2066 		spec->gen.hp_jack_present = true;
2067 		break;
2068 	case ALC_HEADSET_MODE_MIC:
2069 		alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
2070 		spec->gen.hp_jack_present = false;
2071 		break;
2072 	case ALC_HEADSET_MODE_HEADPHONE:
2073 		alc_headset_mode_default(codec);
2074 		spec->gen.hp_jack_present = true;
2075 		break;
2076 	}
2077 	if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
2078 		snd_hda_set_pin_ctl_cache(codec, hp_pin,
2079 					  AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2080 		if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
2081 			snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
2082 						  PIN_VREFHIZ);
2083 	}
2084 	spec->current_headset_mode = new_headset_mode;
2085 
2086 	snd_hda_gen_update_outputs(codec);
2087 }
2088 
2089 static void alc_update_headset_mode_hook(struct hda_codec *codec,
2090 					 struct snd_kcontrol *kcontrol,
2091 					 struct snd_ctl_elem_value *ucontrol)
2092 {
2093 	alc_update_headset_mode(codec);
2094 }
2095 
2096 void alc_update_headset_jack_cb(struct hda_codec *codec,
2097 				struct hda_jack_callback *jack)
2098 {
2099 	snd_hda_gen_hp_automute(codec, jack);
2100 	alc_update_headset_mode(codec);
2101 }
2102 EXPORT_SYMBOL_NS_GPL(alc_update_headset_jack_cb, "SND_HDA_CODEC_REALTEK");
2103 
2104 static void alc_probe_headset_mode(struct hda_codec *codec)
2105 {
2106 	int i;
2107 	struct alc_spec *spec = codec->spec;
2108 	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
2109 
2110 	/* Find mic pins */
2111 	for (i = 0; i < cfg->num_inputs; i++) {
2112 		if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
2113 			spec->headset_mic_pin = cfg->inputs[i].pin;
2114 		if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
2115 			spec->headphone_mic_pin = cfg->inputs[i].pin;
2116 	}
2117 
2118 	WARN_ON(spec->gen.cap_sync_hook);
2119 	spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
2120 	spec->gen.automute_hook = alc_update_headset_mode;
2121 	spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
2122 }
2123 
2124 void alc_fixup_headset_mode(struct hda_codec *codec,
2125 			    const struct hda_fixup *fix, int action)
2126 {
2127 	struct alc_spec *spec = codec->spec;
2128 
2129 	switch (action) {
2130 	case HDA_FIXUP_ACT_PRE_PROBE:
2131 		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
2132 		break;
2133 	case HDA_FIXUP_ACT_PROBE:
2134 		alc_probe_headset_mode(codec);
2135 		break;
2136 	case HDA_FIXUP_ACT_INIT:
2137 		if (is_s3_resume(codec) || is_s4_resume(codec)) {
2138 			spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
2139 			spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
2140 		}
2141 		alc_update_headset_mode(codec);
2142 		break;
2143 	}
2144 }
2145 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mode, "SND_HDA_CODEC_REALTEK");
2146 
2147 void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2148 				      const struct hda_fixup *fix, int action)
2149 {
2150 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2151 		struct alc_spec *spec = codec->spec;
2152 		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
2153 	} else
2154 		alc_fixup_headset_mode(codec, fix, action);
2155 }
2156 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mode_no_hp_mic, "SND_HDA_CODEC_REALTEK");
2157 
2158 void alc_fixup_headset_mic(struct hda_codec *codec,
2159 			   const struct hda_fixup *fix, int action)
2160 {
2161 	struct alc_spec *spec = codec->spec;
2162 
2163 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
2164 		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
2165 }
2166 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mic, "SND_HDA_CODEC_REALTEK");
2167 
2168 /* update LED status via GPIO */
2169 void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
2170 			 int polarity, bool enabled)
2171 {
2172 	if (polarity)
2173 		enabled = !enabled;
2174 	alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
2175 }
2176 EXPORT_SYMBOL_NS_GPL(alc_update_gpio_led, "SND_HDA_CODEC_REALTEK");
2177 
2178 /* turn on/off mic-mute LED via GPIO per capture hook */
2179 static int micmute_led_set(struct led_classdev *led_cdev,
2180 			   enum led_brightness brightness)
2181 {
2182 	struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
2183 	struct alc_spec *spec = codec->spec;
2184 
2185 	alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
2186 			    spec->micmute_led_polarity, !brightness);
2187 	return 0;
2188 }
2189 
2190 /* turn on/off mute LED via GPIO per vmaster hook */
2191 static int gpio_mute_led_set(struct led_classdev *led_cdev,
2192 			     enum led_brightness brightness)
2193 {
2194 	struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
2195 	struct alc_spec *spec = codec->spec;
2196 
2197 	alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
2198 			    spec->mute_led_polarity, !brightness);
2199 	return 0;
2200 }
2201 
2202 /* setup mute and mic-mute GPIO bits, add hooks appropriately */
2203 void alc_fixup_hp_gpio_led(struct hda_codec *codec,
2204 			   int action,
2205 			   unsigned int mute_mask,
2206 			   unsigned int micmute_mask)
2207 {
2208 	struct alc_spec *spec = codec->spec;
2209 
2210 	alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
2211 
2212 	if (action != HDA_FIXUP_ACT_PRE_PROBE)
2213 		return;
2214 	if (mute_mask) {
2215 		spec->gpio_mute_led_mask = mute_mask;
2216 		snd_hda_gen_add_mute_led_cdev(codec, gpio_mute_led_set);
2217 	}
2218 	if (micmute_mask) {
2219 		spec->gpio_mic_led_mask = micmute_mask;
2220 		snd_hda_gen_add_micmute_led_cdev(codec, micmute_led_set);
2221 	}
2222 }
2223 EXPORT_SYMBOL_NS_GPL(alc_fixup_hp_gpio_led, "SND_HDA_CODEC_REALTEK");
2224 
2225 /* suppress the jack-detection */
2226 void alc_fixup_no_jack_detect(struct hda_codec *codec,
2227 			      const struct hda_fixup *fix, int action)
2228 {
2229 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
2230 		codec->no_jack_detect = 1;
2231 }
2232 EXPORT_SYMBOL_NS_GPL(alc_fixup_no_jack_detect, "SND_HDA_CODEC_REALTEK");
2233 
2234 void alc_fixup_disable_aamix(struct hda_codec *codec,
2235 			     const struct hda_fixup *fix, int action)
2236 {
2237 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2238 		struct alc_spec *spec = codec->spec;
2239 		/* Disable AA-loopback as it causes white noise */
2240 		spec->gen.mixer_nid = 0;
2241 	}
2242 }
2243 EXPORT_SYMBOL_NS_GPL(alc_fixup_disable_aamix, "SND_HDA_CODEC_REALTEK");
2244 
2245 void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
2246 				 const struct hda_fixup *fix, int action)
2247 {
2248 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2249 		struct alc_spec *spec = codec->spec;
2250 		spec->gen.auto_mute_via_amp = 1;
2251 	}
2252 }
2253 EXPORT_SYMBOL_NS_GPL(alc_fixup_auto_mute_via_amp, "SND_HDA_CODEC_REALTEK");
2254 
2255 MODULE_IMPORT_NS("SND_HDA_SCODEC_COMPONENT");
2256 MODULE_LICENSE("GPL");
2257 MODULE_DESCRIPTION("Realtek HD-audio codec helper");
2258