xref: /linux/sound/hda/codecs/realtek/realtek.c (revision 9ee4266827cfb67b9fbb89136ea6a8f3d7809f5c)
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 0x10ec0235:
1296 	case 0x10ec0255:
1297 		alc_process_coef_fw(codec, coef0255);
1298 		break;
1299 	case 0x10ec0230:
1300 	case 0x10ec0236:
1301 	case 0x10ec0256:
1302 	case 0x19e58326:
1303 		alc_hp_mute_disable(codec, 75);
1304 		alc_process_coef_fw(codec, coef0256);
1305 		break;
1306 	case 0x10ec0234:
1307 	case 0x10ec0274:
1308 	case 0x10ec0294:
1309 		alc_process_coef_fw(codec, coef0274);
1310 		break;
1311 	case 0x10ec0233:
1312 	case 0x10ec0283:
1313 		alc_process_coef_fw(codec, coef0233);
1314 		break;
1315 	case 0x10ec0286:
1316 	case 0x10ec0288:
1317 		alc_process_coef_fw(codec, coef0288);
1318 		break;
1319 	case 0x10ec0298:
1320 		alc_process_coef_fw(codec, coef0298);
1321 		alc_process_coef_fw(codec, coef0288);
1322 		break;
1323 	case 0x10ec0292:
1324 		alc_process_coef_fw(codec, coef0292);
1325 		break;
1326 	case 0x10ec0293:
1327 		alc_process_coef_fw(codec, coef0293);
1328 		break;
1329 	case 0x10ec0668:
1330 		alc_process_coef_fw(codec, coef0668);
1331 		break;
1332 	case 0x10ec0215:
1333 	case 0x10ec0225:
1334 	case 0x10ec0285:
1335 	case 0x10ec0295:
1336 	case 0x10ec0289:
1337 	case 0x10ec0299:
1338 		alc_hp_mute_disable(codec, 75);
1339 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1340 		alc_process_coef_fw(codec, coef0225);
1341 		break;
1342 	case 0x10ec0867:
1343 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1344 		break;
1345 	}
1346 	codec_dbg(codec, "Headset jack set to unplugged mode.\n");
1347 }
1348 
1349 
1350 static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
1351 				    hda_nid_t mic_pin)
1352 {
1353 	static const struct coef_fw coef0255[] = {
1354 		WRITE_COEFEX(0x57, 0x03, 0x8aa6),
1355 		WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
1356 		{}
1357 	};
1358 	static const struct coef_fw coef0256[] = {
1359 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/
1360 		WRITE_COEFEX(0x57, 0x03, 0x09a3),
1361 		WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
1362 		{}
1363 	};
1364 	static const struct coef_fw coef0233[] = {
1365 		UPDATE_COEF(0x35, 0, 1<<14),
1366 		WRITE_COEF(0x06, 0x2100),
1367 		WRITE_COEF(0x1a, 0x0021),
1368 		WRITE_COEF(0x26, 0x008c),
1369 		{}
1370 	};
1371 	static const struct coef_fw coef0288[] = {
1372 		UPDATE_COEF(0x4f, 0x00c0, 0),
1373 		UPDATE_COEF(0x50, 0x2000, 0),
1374 		UPDATE_COEF(0x56, 0x0006, 0),
1375 		UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
1376 		UPDATE_COEF(0x66, 0x0008, 0x0008),
1377 		UPDATE_COEF(0x67, 0x2000, 0x2000),
1378 		{}
1379 	};
1380 	static const struct coef_fw coef0292[] = {
1381 		WRITE_COEF(0x19, 0xa208),
1382 		WRITE_COEF(0x2e, 0xacf0),
1383 		{}
1384 	};
1385 	static const struct coef_fw coef0293[] = {
1386 		UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
1387 		UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
1388 		UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
1389 		{}
1390 	};
1391 	static const struct coef_fw coef0688[] = {
1392 		WRITE_COEF(0xb7, 0x802b),
1393 		WRITE_COEF(0xb5, 0x1040),
1394 		UPDATE_COEF(0xc3, 0, 1<<12),
1395 		{}
1396 	};
1397 	static const struct coef_fw coef0225[] = {
1398 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14),
1399 		UPDATE_COEF(0x4a, 3<<4, 2<<4),
1400 		UPDATE_COEF(0x63, 3<<14, 0),
1401 		{}
1402 	};
1403 	static const struct coef_fw coef0274[] = {
1404 		UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000),
1405 		UPDATE_COEF(0x4a, 0x0010, 0),
1406 		UPDATE_COEF(0x6b, 0xf000, 0),
1407 		{}
1408 	};
1409 
1410 	switch (codec->core.vendor_id) {
1411 	case 0x10ec0235:
1412 	case 0x10ec0255:
1413 		alc_write_coef_idx(codec, 0x45, 0xc489);
1414 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1415 		alc_process_coef_fw(codec, coef0255);
1416 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1417 		break;
1418 	case 0x10ec0230:
1419 	case 0x10ec0236:
1420 	case 0x10ec0256:
1421 	case 0x19e58326:
1422 		alc_write_coef_idx(codec, 0x45, 0xc489);
1423 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1424 		alc_process_coef_fw(codec, coef0256);
1425 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1426 		break;
1427 	case 0x10ec0234:
1428 	case 0x10ec0274:
1429 	case 0x10ec0294:
1430 		alc_write_coef_idx(codec, 0x45, 0x4689);
1431 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1432 		alc_process_coef_fw(codec, coef0274);
1433 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1434 		break;
1435 	case 0x10ec0233:
1436 	case 0x10ec0283:
1437 		alc_write_coef_idx(codec, 0x45, 0xc429);
1438 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1439 		alc_process_coef_fw(codec, coef0233);
1440 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1441 		break;
1442 	case 0x10ec0286:
1443 	case 0x10ec0288:
1444 	case 0x10ec0298:
1445 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1446 		alc_process_coef_fw(codec, coef0288);
1447 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1448 		break;
1449 	case 0x10ec0292:
1450 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1451 		alc_process_coef_fw(codec, coef0292);
1452 		break;
1453 	case 0x10ec0293:
1454 		/* Set to TRS mode */
1455 		alc_write_coef_idx(codec, 0x45, 0xc429);
1456 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1457 		alc_process_coef_fw(codec, coef0293);
1458 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1459 		break;
1460 	case 0x10ec0867:
1461 		alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
1462 		fallthrough;
1463 	case 0x10ec0221:
1464 	case 0x10ec0662:
1465 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1466 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1467 		break;
1468 	case 0x10ec0668:
1469 		alc_write_coef_idx(codec, 0x11, 0x0001);
1470 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1471 		alc_process_coef_fw(codec, coef0688);
1472 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1473 		break;
1474 	case 0x10ec0215:
1475 	case 0x10ec0225:
1476 	case 0x10ec0285:
1477 	case 0x10ec0295:
1478 	case 0x10ec0289:
1479 	case 0x10ec0299:
1480 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1481 		alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
1482 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
1483 		alc_process_coef_fw(codec, coef0225);
1484 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
1485 		break;
1486 	}
1487 	codec_dbg(codec, "Headset jack set to mic-in mode.\n");
1488 }
1489 
1490 static void alc_headset_mode_default(struct hda_codec *codec)
1491 {
1492 	static const struct coef_fw coef0225[] = {
1493 		UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
1494 		UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
1495 		UPDATE_COEF(0x49, 3<<8, 0<<8),
1496 		UPDATE_COEF(0x4a, 3<<4, 3<<4),
1497 		UPDATE_COEF(0x63, 3<<14, 0),
1498 		UPDATE_COEF(0x67, 0xf000, 0x3000),
1499 		{}
1500 	};
1501 	static const struct coef_fw coef0255[] = {
1502 		WRITE_COEF(0x45, 0xc089),
1503 		WRITE_COEF(0x45, 0xc489),
1504 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
1505 		WRITE_COEF(0x49, 0x0049),
1506 		{}
1507 	};
1508 	static const struct coef_fw coef0256[] = {
1509 		WRITE_COEF(0x45, 0xc489),
1510 		WRITE_COEFEX(0x57, 0x03, 0x0da3),
1511 		WRITE_COEF(0x49, 0x0049),
1512 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
1513 		WRITE_COEF(0x06, 0x6100),
1514 		{}
1515 	};
1516 	static const struct coef_fw coef0233[] = {
1517 		WRITE_COEF(0x06, 0x2100),
1518 		WRITE_COEF(0x32, 0x4ea3),
1519 		{}
1520 	};
1521 	static const struct coef_fw coef0288[] = {
1522 		UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
1523 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1524 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1525 		UPDATE_COEF(0x66, 0x0008, 0),
1526 		UPDATE_COEF(0x67, 0x2000, 0),
1527 		{}
1528 	};
1529 	static const struct coef_fw coef0292[] = {
1530 		WRITE_COEF(0x76, 0x000e),
1531 		WRITE_COEF(0x6c, 0x2400),
1532 		WRITE_COEF(0x6b, 0xc429),
1533 		WRITE_COEF(0x18, 0x7308),
1534 		{}
1535 	};
1536 	static const struct coef_fw coef0293[] = {
1537 		UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
1538 		WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
1539 		UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
1540 		{}
1541 	};
1542 	static const struct coef_fw coef0688[] = {
1543 		WRITE_COEF(0x11, 0x0041),
1544 		WRITE_COEF(0x15, 0x0d40),
1545 		WRITE_COEF(0xb7, 0x802b),
1546 		{}
1547 	};
1548 	static const struct coef_fw coef0274[] = {
1549 		WRITE_COEF(0x45, 0x4289),
1550 		UPDATE_COEF(0x4a, 0x0010, 0x0010),
1551 		UPDATE_COEF(0x6b, 0x0f00, 0),
1552 		UPDATE_COEF(0x49, 0x0300, 0x0300),
1553 		{}
1554 	};
1555 
1556 	switch (codec->core.vendor_id) {
1557 	case 0x10ec0215:
1558 	case 0x10ec0225:
1559 	case 0x10ec0285:
1560 	case 0x10ec0295:
1561 	case 0x10ec0289:
1562 	case 0x10ec0299:
1563 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1564 		alc_process_coef_fw(codec, coef0225);
1565 		alc_hp_enable_unmute(codec, 75);
1566 		break;
1567 	case 0x10ec0235:
1568 	case 0x10ec0255:
1569 		alc_process_coef_fw(codec, coef0255);
1570 		break;
1571 	case 0x10ec0230:
1572 	case 0x10ec0236:
1573 	case 0x10ec0256:
1574 	case 0x19e58326:
1575 		alc_write_coef_idx(codec, 0x1b, 0x0e4b);
1576 		alc_write_coef_idx(codec, 0x45, 0xc089);
1577 		msleep(50);
1578 		alc_process_coef_fw(codec, coef0256);
1579 		alc_hp_enable_unmute(codec, 75);
1580 		break;
1581 	case 0x10ec0234:
1582 	case 0x10ec0274:
1583 	case 0x10ec0294:
1584 		alc_process_coef_fw(codec, coef0274);
1585 		break;
1586 	case 0x10ec0233:
1587 	case 0x10ec0283:
1588 		alc_process_coef_fw(codec, coef0233);
1589 		break;
1590 	case 0x10ec0286:
1591 	case 0x10ec0288:
1592 	case 0x10ec0298:
1593 		alc_process_coef_fw(codec, coef0288);
1594 		break;
1595 	case 0x10ec0292:
1596 		alc_process_coef_fw(codec, coef0292);
1597 		break;
1598 	case 0x10ec0293:
1599 		alc_process_coef_fw(codec, coef0293);
1600 		break;
1601 	case 0x10ec0668:
1602 		alc_process_coef_fw(codec, coef0688);
1603 		break;
1604 	case 0x10ec0867:
1605 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1606 		break;
1607 	}
1608 	codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
1609 }
1610 
1611 /* Iphone type */
1612 static void alc_headset_mode_ctia(struct hda_codec *codec)
1613 {
1614 	int val;
1615 
1616 	static const struct coef_fw coef0255[] = {
1617 		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
1618 		WRITE_COEF(0x1b, 0x0c2b),
1619 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
1620 		{}
1621 	};
1622 	static const struct coef_fw coef0256[] = {
1623 		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
1624 		WRITE_COEF(0x1b, 0x0e6b),
1625 		{}
1626 	};
1627 	static const struct coef_fw coef0233[] = {
1628 		WRITE_COEF(0x45, 0xd429),
1629 		WRITE_COEF(0x1b, 0x0c2b),
1630 		WRITE_COEF(0x32, 0x4ea3),
1631 		{}
1632 	};
1633 	static const struct coef_fw coef0288[] = {
1634 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1635 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1636 		UPDATE_COEF(0x66, 0x0008, 0),
1637 		UPDATE_COEF(0x67, 0x2000, 0),
1638 		{}
1639 	};
1640 	static const struct coef_fw coef0292[] = {
1641 		WRITE_COEF(0x6b, 0xd429),
1642 		WRITE_COEF(0x76, 0x0008),
1643 		WRITE_COEF(0x18, 0x7388),
1644 		{}
1645 	};
1646 	static const struct coef_fw coef0293[] = {
1647 		WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
1648 		UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
1649 		{}
1650 	};
1651 	static const struct coef_fw coef0688[] = {
1652 		WRITE_COEF(0x11, 0x0001),
1653 		WRITE_COEF(0x15, 0x0d60),
1654 		WRITE_COEF(0xc3, 0x0000),
1655 		{}
1656 	};
1657 	static const struct coef_fw coef0225_1[] = {
1658 		UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
1659 		UPDATE_COEF(0x63, 3<<14, 2<<14),
1660 		{}
1661 	};
1662 	static const struct coef_fw coef0225_2[] = {
1663 		UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
1664 		UPDATE_COEF(0x63, 3<<14, 1<<14),
1665 		{}
1666 	};
1667 
1668 	switch (codec->core.vendor_id) {
1669 	case 0x10ec0235:
1670 	case 0x10ec0255:
1671 		alc_process_coef_fw(codec, coef0255);
1672 		break;
1673 	case 0x10ec0230:
1674 	case 0x10ec0236:
1675 	case 0x10ec0256:
1676 	case 0x19e58326:
1677 		alc_process_coef_fw(codec, coef0256);
1678 		alc_hp_enable_unmute(codec, 75);
1679 		break;
1680 	case 0x10ec0234:
1681 	case 0x10ec0274:
1682 	case 0x10ec0294:
1683 		alc_write_coef_idx(codec, 0x45, 0xd689);
1684 		break;
1685 	case 0x10ec0233:
1686 	case 0x10ec0283:
1687 		alc_process_coef_fw(codec, coef0233);
1688 		break;
1689 	case 0x10ec0298:
1690 		val = alc_read_coef_idx(codec, 0x50);
1691 		if (val & (1 << 12)) {
1692 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
1693 			alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
1694 			msleep(300);
1695 		} else {
1696 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
1697 			alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
1698 			msleep(300);
1699 		}
1700 		break;
1701 	case 0x10ec0286:
1702 	case 0x10ec0288:
1703 		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
1704 		msleep(300);
1705 		alc_process_coef_fw(codec, coef0288);
1706 		break;
1707 	case 0x10ec0292:
1708 		alc_process_coef_fw(codec, coef0292);
1709 		break;
1710 	case 0x10ec0293:
1711 		alc_process_coef_fw(codec, coef0293);
1712 		break;
1713 	case 0x10ec0668:
1714 		alc_process_coef_fw(codec, coef0688);
1715 		break;
1716 	case 0x10ec0215:
1717 	case 0x10ec0225:
1718 	case 0x10ec0285:
1719 	case 0x10ec0295:
1720 	case 0x10ec0289:
1721 	case 0x10ec0299:
1722 		val = alc_read_coef_idx(codec, 0x45);
1723 		if (val & (1 << 9))
1724 			alc_process_coef_fw(codec, coef0225_2);
1725 		else
1726 			alc_process_coef_fw(codec, coef0225_1);
1727 		alc_hp_enable_unmute(codec, 75);
1728 		break;
1729 	case 0x10ec0867:
1730 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1731 		break;
1732 	}
1733 	codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
1734 }
1735 
1736 /* Nokia type */
1737 static void alc_headset_mode_omtp(struct hda_codec *codec)
1738 {
1739 	static const struct coef_fw coef0255[] = {
1740 		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
1741 		WRITE_COEF(0x1b, 0x0c2b),
1742 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
1743 		{}
1744 	};
1745 	static const struct coef_fw coef0256[] = {
1746 		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
1747 		WRITE_COEF(0x1b, 0x0e6b),
1748 		{}
1749 	};
1750 	static const struct coef_fw coef0233[] = {
1751 		WRITE_COEF(0x45, 0xe429),
1752 		WRITE_COEF(0x1b, 0x0c2b),
1753 		WRITE_COEF(0x32, 0x4ea3),
1754 		{}
1755 	};
1756 	static const struct coef_fw coef0288[] = {
1757 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1758 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1759 		UPDATE_COEF(0x66, 0x0008, 0),
1760 		UPDATE_COEF(0x67, 0x2000, 0),
1761 		{}
1762 	};
1763 	static const struct coef_fw coef0292[] = {
1764 		WRITE_COEF(0x6b, 0xe429),
1765 		WRITE_COEF(0x76, 0x0008),
1766 		WRITE_COEF(0x18, 0x7388),
1767 		{}
1768 	};
1769 	static const struct coef_fw coef0293[] = {
1770 		WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
1771 		UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
1772 		{}
1773 	};
1774 	static const struct coef_fw coef0688[] = {
1775 		WRITE_COEF(0x11, 0x0001),
1776 		WRITE_COEF(0x15, 0x0d50),
1777 		WRITE_COEF(0xc3, 0x0000),
1778 		{}
1779 	};
1780 	static const struct coef_fw coef0225[] = {
1781 		UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
1782 		UPDATE_COEF(0x63, 3<<14, 2<<14),
1783 		{}
1784 	};
1785 
1786 	switch (codec->core.vendor_id) {
1787 	case 0x10ec0235:
1788 	case 0x10ec0255:
1789 		alc_process_coef_fw(codec, coef0255);
1790 		break;
1791 	case 0x10ec0230:
1792 	case 0x10ec0236:
1793 	case 0x10ec0256:
1794 	case 0x19e58326:
1795 		alc_process_coef_fw(codec, coef0256);
1796 		alc_hp_enable_unmute(codec, 75);
1797 		break;
1798 	case 0x10ec0234:
1799 	case 0x10ec0274:
1800 	case 0x10ec0294:
1801 		alc_write_coef_idx(codec, 0x45, 0xe689);
1802 		break;
1803 	case 0x10ec0233:
1804 	case 0x10ec0283:
1805 		alc_process_coef_fw(codec, coef0233);
1806 		break;
1807 	case 0x10ec0298:
1808 		alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
1809 		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
1810 		msleep(300);
1811 		break;
1812 	case 0x10ec0286:
1813 	case 0x10ec0288:
1814 		alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
1815 		msleep(300);
1816 		alc_process_coef_fw(codec, coef0288);
1817 		break;
1818 	case 0x10ec0292:
1819 		alc_process_coef_fw(codec, coef0292);
1820 		break;
1821 	case 0x10ec0293:
1822 		alc_process_coef_fw(codec, coef0293);
1823 		break;
1824 	case 0x10ec0668:
1825 		alc_process_coef_fw(codec, coef0688);
1826 		break;
1827 	case 0x10ec0215:
1828 	case 0x10ec0225:
1829 	case 0x10ec0285:
1830 	case 0x10ec0295:
1831 	case 0x10ec0289:
1832 	case 0x10ec0299:
1833 		alc_process_coef_fw(codec, coef0225);
1834 		alc_hp_enable_unmute(codec, 75);
1835 		break;
1836 	}
1837 	codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
1838 }
1839 
1840 static void alc_determine_headset_type(struct hda_codec *codec)
1841 {
1842 	int val;
1843 	bool is_ctia = false;
1844 	struct alc_spec *spec = codec->spec;
1845 	static const struct coef_fw coef0255[] = {
1846 		WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
1847 		WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
1848  conteol) */
1849 		{}
1850 	};
1851 	static const struct coef_fw coef0288[] = {
1852 		UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
1853 		{}
1854 	};
1855 	static const struct coef_fw coef0298[] = {
1856 		UPDATE_COEF(0x50, 0x2000, 0x2000),
1857 		UPDATE_COEF(0x56, 0x0006, 0x0006),
1858 		UPDATE_COEF(0x66, 0x0008, 0),
1859 		UPDATE_COEF(0x67, 0x2000, 0),
1860 		UPDATE_COEF(0x19, 0x1300, 0x1300),
1861 		{}
1862 	};
1863 	static const struct coef_fw coef0293[] = {
1864 		UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
1865 		WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
1866 		{}
1867 	};
1868 	static const struct coef_fw coef0688[] = {
1869 		WRITE_COEF(0x11, 0x0001),
1870 		WRITE_COEF(0xb7, 0x802b),
1871 		WRITE_COEF(0x15, 0x0d60),
1872 		WRITE_COEF(0xc3, 0x0c00),
1873 		{}
1874 	};
1875 	static const struct coef_fw coef0274[] = {
1876 		UPDATE_COEF(0x4a, 0x0010, 0),
1877 		UPDATE_COEF(0x4a, 0x8000, 0),
1878 		WRITE_COEF(0x45, 0xd289),
1879 		UPDATE_COEF(0x49, 0x0300, 0x0300),
1880 		{}
1881 	};
1882 
1883 	if (spec->no_internal_mic_pin) {
1884 		alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
1885 		return;
1886 	}
1887 
1888 	switch (codec->core.vendor_id) {
1889 	case 0x10ec0235:
1890 	case 0x10ec0255:
1891 		alc_process_coef_fw(codec, coef0255);
1892 		msleep(300);
1893 		val = alc_read_coef_idx(codec, 0x46);
1894 		is_ctia = (val & 0x0070) == 0x0070;
1895 		break;
1896 	case 0x10ec0230:
1897 	case 0x10ec0236:
1898 	case 0x10ec0256:
1899 	case 0x19e58326:
1900 		alc_write_coef_idx(codec, 0x1b, 0x0e4b);
1901 		alc_write_coef_idx(codec, 0x06, 0x6104);
1902 		alc_write_coefex_idx(codec, 0x57, 0x3, 0x09a3);
1903 
1904 		alc_process_coef_fw(codec, coef0255);
1905 		msleep(300);
1906 		val = alc_read_coef_idx(codec, 0x46);
1907 		is_ctia = (val & 0x0070) == 0x0070;
1908 		if (!is_ctia) {
1909 			alc_write_coef_idx(codec, 0x45, 0xe089);
1910 			msleep(100);
1911 			val = alc_read_coef_idx(codec, 0x46);
1912 			if ((val & 0x0070) == 0x0070)
1913 				is_ctia = false;
1914 			else
1915 				is_ctia = true;
1916 		}
1917 		alc_write_coefex_idx(codec, 0x57, 0x3, 0x0da3);
1918 		alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
1919 		break;
1920 	case 0x10ec0234:
1921 	case 0x10ec0274:
1922 	case 0x10ec0294:
1923 		alc_process_coef_fw(codec, coef0274);
1924 		msleep(850);
1925 		val = alc_read_coef_idx(codec, 0x46);
1926 		is_ctia = (val & 0x00f0) == 0x00f0;
1927 		break;
1928 	case 0x10ec0233:
1929 	case 0x10ec0283:
1930 		alc_write_coef_idx(codec, 0x45, 0xd029);
1931 		msleep(300);
1932 		val = alc_read_coef_idx(codec, 0x46);
1933 		is_ctia = (val & 0x0070) == 0x0070;
1934 		break;
1935 	case 0x10ec0298:
1936 		snd_hda_codec_write(codec, 0x21, 0,
1937 			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
1938 		msleep(100);
1939 		snd_hda_codec_write(codec, 0x21, 0,
1940 			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
1941 		msleep(200);
1942 
1943 		val = alc_read_coef_idx(codec, 0x50);
1944 		if (val & (1 << 12)) {
1945 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
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 		} else {
1951 			alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
1952 			alc_process_coef_fw(codec, coef0288);
1953 			msleep(350);
1954 			val = alc_read_coef_idx(codec, 0x50);
1955 			is_ctia = (val & 0x0070) == 0x0070;
1956 		}
1957 		alc_process_coef_fw(codec, coef0298);
1958 		snd_hda_codec_write(codec, 0x21, 0,
1959 			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
1960 		msleep(75);
1961 		snd_hda_codec_write(codec, 0x21, 0,
1962 			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
1963 		break;
1964 	case 0x10ec0286:
1965 	case 0x10ec0288:
1966 		alc_process_coef_fw(codec, coef0288);
1967 		msleep(350);
1968 		val = alc_read_coef_idx(codec, 0x50);
1969 		is_ctia = (val & 0x0070) == 0x0070;
1970 		break;
1971 	case 0x10ec0292:
1972 		alc_write_coef_idx(codec, 0x6b, 0xd429);
1973 		msleep(300);
1974 		val = alc_read_coef_idx(codec, 0x6c);
1975 		is_ctia = (val & 0x001c) == 0x001c;
1976 		break;
1977 	case 0x10ec0293:
1978 		alc_process_coef_fw(codec, coef0293);
1979 		msleep(300);
1980 		val = alc_read_coef_idx(codec, 0x46);
1981 		is_ctia = (val & 0x0070) == 0x0070;
1982 		break;
1983 	case 0x10ec0668:
1984 		alc_process_coef_fw(codec, coef0688);
1985 		msleep(300);
1986 		val = alc_read_coef_idx(codec, 0xbe);
1987 		is_ctia = (val & 0x1c02) == 0x1c02;
1988 		break;
1989 	case 0x10ec0215:
1990 	case 0x10ec0225:
1991 	case 0x10ec0285:
1992 	case 0x10ec0295:
1993 	case 0x10ec0289:
1994 	case 0x10ec0299:
1995 		alc_process_coef_fw(codec, alc225_pre_hsmode);
1996 		alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
1997 		val = alc_read_coef_idx(codec, 0x45);
1998 		if (val & (1 << 9)) {
1999 			alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
2000 			alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
2001 			msleep(800);
2002 			val = alc_read_coef_idx(codec, 0x46);
2003 			is_ctia = (val & 0x00f0) == 0x00f0;
2004 		} else {
2005 			alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
2006 			alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
2007 			msleep(800);
2008 			val = alc_read_coef_idx(codec, 0x46);
2009 			is_ctia = (val & 0x00f0) == 0x00f0;
2010 		}
2011 		if (!is_ctia) {
2012 			alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x38<<10);
2013 			alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
2014 			msleep(100);
2015 			val = alc_read_coef_idx(codec, 0x46);
2016 			if ((val & 0x00f0) == 0x00f0)
2017 				is_ctia = false;
2018 			else
2019 				is_ctia = true;
2020 		}
2021 		alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
2022 		alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
2023 		alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
2024 		break;
2025 	case 0x10ec0867:
2026 		is_ctia = true;
2027 		break;
2028 	}
2029 
2030 	codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
2031 		  str_yes_no(is_ctia));
2032 	spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
2033 }
2034 
2035 static void alc_update_headset_mode(struct hda_codec *codec)
2036 {
2037 	struct alc_spec *spec = codec->spec;
2038 
2039 	hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
2040 	hda_nid_t hp_pin = alc_get_hp_pin(spec);
2041 
2042 	int new_headset_mode;
2043 
2044 	if (!snd_hda_jack_detect(codec, hp_pin))
2045 		new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
2046 	else if (mux_pin == spec->headset_mic_pin)
2047 		new_headset_mode = ALC_HEADSET_MODE_HEADSET;
2048 	else if (mux_pin == spec->headphone_mic_pin)
2049 		new_headset_mode = ALC_HEADSET_MODE_MIC;
2050 	else
2051 		new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
2052 
2053 	if (new_headset_mode == spec->current_headset_mode) {
2054 		snd_hda_gen_update_outputs(codec);
2055 		return;
2056 	}
2057 
2058 	switch (new_headset_mode) {
2059 	case ALC_HEADSET_MODE_UNPLUGGED:
2060 		alc_headset_mode_unplugged(codec);
2061 		spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
2062 		spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
2063 		spec->gen.hp_jack_present = false;
2064 		break;
2065 	case ALC_HEADSET_MODE_HEADSET:
2066 		if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
2067 			alc_determine_headset_type(codec);
2068 		if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
2069 			alc_headset_mode_ctia(codec);
2070 		else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
2071 			alc_headset_mode_omtp(codec);
2072 		spec->gen.hp_jack_present = true;
2073 		break;
2074 	case ALC_HEADSET_MODE_MIC:
2075 		alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
2076 		spec->gen.hp_jack_present = false;
2077 		break;
2078 	case ALC_HEADSET_MODE_HEADPHONE:
2079 		alc_headset_mode_default(codec);
2080 		spec->gen.hp_jack_present = true;
2081 		break;
2082 	}
2083 	if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
2084 		snd_hda_set_pin_ctl_cache(codec, hp_pin,
2085 					  AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
2086 		if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
2087 			snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
2088 						  PIN_VREFHIZ);
2089 	}
2090 	spec->current_headset_mode = new_headset_mode;
2091 
2092 	snd_hda_gen_update_outputs(codec);
2093 }
2094 
2095 static void alc_update_headset_mode_hook(struct hda_codec *codec,
2096 					 struct snd_kcontrol *kcontrol,
2097 					 struct snd_ctl_elem_value *ucontrol)
2098 {
2099 	alc_update_headset_mode(codec);
2100 }
2101 
2102 void alc_update_headset_jack_cb(struct hda_codec *codec,
2103 				struct hda_jack_callback *jack)
2104 {
2105 	snd_hda_gen_hp_automute(codec, jack);
2106 	alc_update_headset_mode(codec);
2107 }
2108 EXPORT_SYMBOL_NS_GPL(alc_update_headset_jack_cb, "SND_HDA_CODEC_REALTEK");
2109 
2110 static void alc_probe_headset_mode(struct hda_codec *codec)
2111 {
2112 	int i;
2113 	struct alc_spec *spec = codec->spec;
2114 	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
2115 
2116 	/* Find mic pins */
2117 	for (i = 0; i < cfg->num_inputs; i++) {
2118 		if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
2119 			spec->headset_mic_pin = cfg->inputs[i].pin;
2120 		if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
2121 			spec->headphone_mic_pin = cfg->inputs[i].pin;
2122 	}
2123 
2124 	WARN_ON(spec->gen.cap_sync_hook);
2125 	spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
2126 	spec->gen.automute_hook = alc_update_headset_mode;
2127 	spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
2128 }
2129 
2130 void alc_fixup_headset_mode(struct hda_codec *codec,
2131 			    const struct hda_fixup *fix, int action)
2132 {
2133 	struct alc_spec *spec = codec->spec;
2134 
2135 	switch (action) {
2136 	case HDA_FIXUP_ACT_PRE_PROBE:
2137 		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
2138 		break;
2139 	case HDA_FIXUP_ACT_PROBE:
2140 		alc_probe_headset_mode(codec);
2141 		break;
2142 	case HDA_FIXUP_ACT_INIT:
2143 		if (is_s3_resume(codec) || is_s4_resume(codec)) {
2144 			spec->current_headset_mode = ALC_HEADSET_MODE_UNKNOWN;
2145 			spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
2146 		}
2147 		alc_update_headset_mode(codec);
2148 		break;
2149 	}
2150 }
2151 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mode, "SND_HDA_CODEC_REALTEK");
2152 
2153 void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
2154 				      const struct hda_fixup *fix, int action)
2155 {
2156 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2157 		struct alc_spec *spec = codec->spec;
2158 		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
2159 	} else
2160 		alc_fixup_headset_mode(codec, fix, action);
2161 }
2162 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mode_no_hp_mic, "SND_HDA_CODEC_REALTEK");
2163 
2164 void alc_fixup_headset_mic(struct hda_codec *codec,
2165 			   const struct hda_fixup *fix, int action)
2166 {
2167 	struct alc_spec *spec = codec->spec;
2168 
2169 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
2170 		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
2171 }
2172 EXPORT_SYMBOL_NS_GPL(alc_fixup_headset_mic, "SND_HDA_CODEC_REALTEK");
2173 
2174 /* update LED status via GPIO */
2175 void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
2176 			 int polarity, bool enabled)
2177 {
2178 	if (polarity)
2179 		enabled = !enabled;
2180 	alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
2181 }
2182 EXPORT_SYMBOL_NS_GPL(alc_update_gpio_led, "SND_HDA_CODEC_REALTEK");
2183 
2184 /* turn on/off mic-mute LED via GPIO per capture hook */
2185 static int micmute_led_set(struct led_classdev *led_cdev,
2186 			   enum led_brightness brightness)
2187 {
2188 	struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
2189 	struct alc_spec *spec = codec->spec;
2190 
2191 	alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
2192 			    spec->micmute_led_polarity, !brightness);
2193 	return 0;
2194 }
2195 
2196 /* turn on/off mute LED via GPIO per vmaster hook */
2197 static int gpio_mute_led_set(struct led_classdev *led_cdev,
2198 			     enum led_brightness brightness)
2199 {
2200 	struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
2201 	struct alc_spec *spec = codec->spec;
2202 
2203 	alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
2204 			    spec->mute_led_polarity, !brightness);
2205 	return 0;
2206 }
2207 
2208 /* setup mute and mic-mute GPIO bits, add hooks appropriately */
2209 void alc_fixup_hp_gpio_led(struct hda_codec *codec,
2210 			   int action,
2211 			   unsigned int mute_mask,
2212 			   unsigned int micmute_mask)
2213 {
2214 	struct alc_spec *spec = codec->spec;
2215 
2216 	alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
2217 
2218 	if (action != HDA_FIXUP_ACT_PRE_PROBE)
2219 		return;
2220 	if (mute_mask) {
2221 		spec->gpio_mute_led_mask = mute_mask;
2222 		snd_hda_gen_add_mute_led_cdev(codec, gpio_mute_led_set);
2223 	}
2224 	if (micmute_mask) {
2225 		spec->gpio_mic_led_mask = micmute_mask;
2226 		snd_hda_gen_add_micmute_led_cdev(codec, micmute_led_set);
2227 	}
2228 }
2229 EXPORT_SYMBOL_NS_GPL(alc_fixup_hp_gpio_led, "SND_HDA_CODEC_REALTEK");
2230 
2231 /* suppress the jack-detection */
2232 void alc_fixup_no_jack_detect(struct hda_codec *codec,
2233 			      const struct hda_fixup *fix, int action)
2234 {
2235 	if (action == HDA_FIXUP_ACT_PRE_PROBE)
2236 		codec->no_jack_detect = 1;
2237 }
2238 EXPORT_SYMBOL_NS_GPL(alc_fixup_no_jack_detect, "SND_HDA_CODEC_REALTEK");
2239 
2240 void alc_fixup_disable_aamix(struct hda_codec *codec,
2241 			     const struct hda_fixup *fix, int action)
2242 {
2243 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2244 		struct alc_spec *spec = codec->spec;
2245 		/* Disable AA-loopback as it causes white noise */
2246 		spec->gen.mixer_nid = 0;
2247 	}
2248 }
2249 EXPORT_SYMBOL_NS_GPL(alc_fixup_disable_aamix, "SND_HDA_CODEC_REALTEK");
2250 
2251 void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
2252 				 const struct hda_fixup *fix, int action)
2253 {
2254 	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2255 		struct alc_spec *spec = codec->spec;
2256 		spec->gen.auto_mute_via_amp = 1;
2257 	}
2258 }
2259 EXPORT_SYMBOL_NS_GPL(alc_fixup_auto_mute_via_amp, "SND_HDA_CODEC_REALTEK");
2260 
2261 MODULE_IMPORT_NS("SND_HDA_SCODEC_COMPONENT");
2262 MODULE_LICENSE("GPL");
2263 MODULE_DESCRIPTION("Realtek HD-audio codec helper");
2264