1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca>
5 * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org>
6 * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31/*
32 * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
33 */
34
35#ifdef HAVE_KERNEL_OPTION_HEADERS
36#include "opt_snd.h"
37#endif
38
39#include <dev/sound/pcm/sound.h>
40
41#include <sys/ctype.h>
42
43#include <dev/sound/pci/hda/hdac.h>
44#include <dev/sound/pci/hda/hdaa.h>
45#include <dev/sound/pci/hda/hda_reg.h>
46
47SND_DECLARE_FILE("$FreeBSD$");
48
49static const struct {
50	uint32_t model;
51	uint32_t id;
52	uint32_t subsystemid;
53	uint32_t set, unset;
54	uint32_t gpio;
55} hdac_quirks[] = {
56	/*
57	 * XXX Force stereo quirk. Monoural recording / playback
58	 *     on few codecs (especially ALC880) seems broken or
59	 *     perhaps unsupported.
60	 */
61	{ HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL,
62	    HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0,
63	    0 },
64	{ ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL,
65	    0, 0,
66	    HDAA_GPIO_SET(0) },
67	{ ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL,
68	    0, 0,
69	    HDAA_GPIO_SET(0) },
70	{ ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
71	    0, 0,
72	    HDAA_GPIO_SET(0) },
73	{ ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
74	    0, 0,
75	    HDAA_GPIO_SET(0) },
76	{ ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
77	    0, 0,
78	    HDAA_GPIO_SET(0) },
79	{ ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
80	    0, 0,
81	    HDAA_GPIO_SET(0) },
82	{ ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
83	    HDAA_QUIRK_EAPDINV, 0,
84	    0 },
85	{ ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
86	    HDAA_QUIRK_EAPDINV, 0,
87	    0 },
88	{ ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
89	    HDAA_QUIRK_OVREF, 0,
90	    0 },
91	{ UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
92	    HDAA_QUIRK_OVREF, 0,
93	    0 },
94	/*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, HDA_MATCH_ALL,
95	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
96	    0 },*/
97	{ MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
98	    0, 0,
99	    HDAA_GPIO_SET(1) },
100	{ LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
101	    HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0,
102	    0 },
103	{ SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
104	    HDAA_QUIRK_EAPDINV, 0,
105	    0 },
106	{ APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL,
107	    HDAA_QUIRK_OVREF50, 0,
108	    HDAA_GPIO_SET(0) },
109	{ APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL,
110	    0, 0,
111	    HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) },
112	{ APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL,
113	    0, 0,
114	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
115	{ APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL,
116	    0, 0,
117	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
118	{ APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL,
119	    0, 0,
120	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
121	{ HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL,
122	    0, 0,
123	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
124	{ DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
125	    0, 0,
126	    HDAA_GPIO_SET(0) },
127	{ DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL,
128	    0, 0,
129	    HDAA_GPIO_SET(2) },
130	{ DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
131	    0, 0,
132	    HDAA_GPIO_SET(0) },
133	{ HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL,
134	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
135	    0 },
136	{ HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL,
137	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
138	    0 },
139	{ HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL,
140	    0, HDAA_QUIRK_FORCESTEREO,
141	    0 },
142	/* Mac Pro 1,1 requires ovref for proper volume level. */
143	{ 0x00000000, HDA_CODEC_ALC885, 0x106b0c00,
144	    0, HDAA_QUIRK_OVREF,
145	    0 }
146};
147
148static void
149hdac_pin_patch(struct hdaa_widget *w)
150{
151	const char *patch = NULL;
152	uint32_t config, orig, id, subid;
153	nid_t nid = w->nid;
154
155	config = orig = w->wclass.pin.config;
156	id = hdaa_codec_id(w->devinfo);
157	subid = hdaa_card_id(w->devinfo);
158
159	/* XXX: Old patches require complete review.
160	 * Now they may create more problem then solve due to
161	 * incorrect associations.
162	 */
163	if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) {
164		switch (nid) {
165		case 26:
166			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
167			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
168			break;
169		case 27:
170			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
171			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
172			break;
173		default:
174			break;
175		}
176	} else if (id == HDA_CODEC_ALC880 &&
177	    (subid == CLEVO_D900T_SUBVENDOR ||
178	    subid == ASUS_M5200_SUBVENDOR)) {
179		/*
180		 * Super broken BIOS
181		 */
182		switch (nid) {
183		case 24:	/* MIC1 */
184			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
185			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
186			break;
187		case 25:	/* XXX MIC2 */
188			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
189			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
190			break;
191		case 26:	/* LINE1 */
192			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
193			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
194			break;
195		case 27:	/* XXX LINE2 */
196			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
197			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
198			break;
199		case 28:	/* CD */
200			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
201			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
202			break;
203		}
204	} else if (id == HDA_CODEC_ALC883 &&
205	    (subid == MSI_MS034A_SUBVENDOR ||
206	    HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) {
207		switch (nid) {
208		case 25:
209			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
210			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
211			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
212			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
213			break;
214		case 28:
215			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
216			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
217			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
218			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
219			break;
220		}
221	} else if (id == HDA_CODEC_CX20549 && subid ==
222	    HP_V3000_SUBVENDOR) {
223		switch (nid) {
224		case 18:
225			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
226			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
227			break;
228		case 20:
229			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
230			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
231			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
232			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
233			break;
234		case 21:
235			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
236			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
237			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
238			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
239			break;
240		}
241	} else if (id == HDA_CODEC_CX20551 && subid ==
242	    HP_DV5000_SUBVENDOR) {
243		switch (nid) {
244		case 20:
245		case 21:
246			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
247			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
248			break;
249		}
250	} else if (id == HDA_CODEC_ALC861 && subid ==
251	    ASUS_W6F_SUBVENDOR) {
252		switch (nid) {
253		case 11:
254			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
255			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
256			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
257			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
258			break;
259		case 12:
260		case 14:
261		case 16:
262		case 31:
263		case 32:
264			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
265			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
266			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
267			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
268			break;
269		case 15:
270			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
271			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
272			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
273			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
274			break;
275		}
276	} else if (id == HDA_CODEC_ALC861 && subid ==
277	    UNIWILL_9075_SUBVENDOR) {
278		switch (nid) {
279		case 15:
280			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
281			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
282			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
283			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
284			break;
285		}
286	}
287
288	/* New patches */
289	if (id == HDA_CODEC_AD1984A &&
290	    subid == LENOVO_X300_SUBVENDOR) {
291		switch (nid) {
292		case 17: /* Headphones with redirection */
293			patch = "as=1 seq=15";
294			break;
295		case 20: /* Two mics together */
296			patch = "as=2 seq=15";
297			break;
298		}
299	} else if (id == HDA_CODEC_AD1986A &&
300	    (subid == ASUS_M2NPVMX_SUBVENDOR ||
301	    subid == ASUS_A8NVMCSM_SUBVENDOR ||
302	    subid == ASUS_P5PL2_SUBVENDOR)) {
303		switch (nid) {
304		case 26: /* Headphones with redirection */
305			patch = "as=1 seq=15";
306			break;
307		case 28: /* 5.1 out => 2.0 out + 1 input */
308			patch = "device=Line-in as=8 seq=1";
309			break;
310		case 29: /* Can't use this as input, as the only available mic
311			  * preamplifier is busy by front panel mic (nid 31).
312			  * If you want to use this rear connector as mic input,
313			  * you have to disable the front panel one. */
314			patch = "as=0";
315			break;
316		case 31: /* Lot of inputs configured with as=15 and unusable */
317			patch = "as=8 seq=3";
318			break;
319		case 32:
320			patch = "as=8 seq=4";
321			break;
322		case 34:
323			patch = "as=8 seq=5";
324			break;
325		case 36:
326			patch = "as=8 seq=6";
327			break;
328		}
329	} else if (id == HDA_CODEC_ALC260 &&
330	    HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) {
331		switch (nid) {
332		case 16:
333			patch = "seq=15 device=Headphones";
334			break;
335		}
336	} else if (id == HDA_CODEC_ALC268) {
337	    if (subid == ACER_T5320_SUBVENDOR) {
338		switch (nid) {
339		case 20: /* Headphones Jack */
340			patch = "as=1 seq=15";
341			break;
342		}
343	    }
344	} else if (id == HDA_CODEC_CX20561 &&
345	    subid == LENOVO_B450_SUBVENDOR) {
346		switch (nid) {
347		case 22:
348			patch = "as=1 seq=15";
349			break;
350		}
351	} else if (id == HDA_CODEC_CX20561 &&
352	    subid == LENOVO_T400_SUBVENDOR) {
353		switch (nid) {
354		case 22:
355			patch = "as=1 seq=15";
356			break;
357		case 26:
358			patch = "as=1 seq=0";
359			break;
360		}
361	} else if (id == HDA_CODEC_CX20590 &&
362	    (subid == LENOVO_X1_SUBVENDOR ||
363	    subid == LENOVO_X220_SUBVENDOR ||
364	    subid == LENOVO_T420_SUBVENDOR ||
365	    subid == LENOVO_T520_SUBVENDOR ||
366	    subid == LENOVO_G580_SUBVENDOR)) {
367		switch (nid) {
368		case 25:
369			patch = "as=1 seq=15";
370			break;
371		/*
372		 * Group onboard mic and headphone mic
373		 * together.  Fixes onboard mic.
374		 */
375		case 27:
376			patch = "as=2 seq=15";
377			break;
378		case 35:
379			patch = "as=2";
380			break;
381		}
382	} else if (id == HDA_CODEC_ALC269 &&
383	    (subid == LENOVO_X1CRBN_SUBVENDOR ||
384	    subid == LENOVO_T430_SUBVENDOR ||
385	    subid == LENOVO_T430S_SUBVENDOR ||
386	    subid == LENOVO_T530_SUBVENDOR)) {
387		switch (nid) {
388		case 21:
389			patch = "as=1 seq=15";
390			break;
391		}
392	} else if (id == HDA_CODEC_ALC285 &&
393	    (subid == LENOVO_X120KH_SUBVENDOR ||
394	    subid == LENOVO_X120QD_SUBVENDOR)) {
395		switch (nid) {
396		case 33:
397			patch = "as=1 seq=15";
398			break;
399		}
400	} else if (id == HDA_CODEC_ALC269 &&
401	    subid == ASUS_UX31A_SUBVENDOR) {
402		switch (nid) {
403		case 33:
404			patch = "as=1 seq=15";
405			break;
406		}
407	} else if (id == HDA_CODEC_ALC892 &&
408	    subid == INTEL_DH87RL_SUBVENDOR) {
409		switch (nid) {
410		case 27:
411			patch = "as=1 seq=15";
412			break;
413		}
414	} else if (id == HDA_CODEC_ALC292 &&
415	    subid == LENOVO_X120BS_SUBVENDOR) {
416		switch (nid) {
417		case 21:
418			patch = "as=1 seq=15";
419			break;
420		}
421	} else if (id == HDA_CODEC_ALC295 && subid == HP_AF006UR_SUBVENDOR) {
422		switch (nid) {
423		case 18:
424			patch = "as=2";
425			break;
426		case 25:
427			patch = "as=2 seq=15";
428			break;
429		case 33:
430			patch = "as=1 seq=15";
431			break;
432		}
433	} else if (id == HDA_CODEC_ALC298 && HDA_DEV_MATCH(LENOVO_ALL_SUBVENDOR, subid)) {
434		switch (nid) {
435		case 23:
436			config = 0x03a1103f;
437			break;
438		case 33:
439			config = 0x2121101f;
440			break;
441		}
442	} else if (id == HDA_CODEC_ALC298 && subid == DELL_XPS9560_SUBVENDOR) {
443		switch (nid) {
444		case 24:
445			config = 0x01a1913c;
446			break;
447		case 26:
448			config = 0x01a1913d;
449			break;
450		}
451	} else if (id == HDA_CODEC_ALC256 && (subid == DELL_I7577_SUBVENDOR ||
452	    subid == DELL_L7480_SUBVENDOR)) {
453		switch (nid) {
454		case 20:
455			patch = "as=1 seq=0";
456			break;
457		case 33:
458			patch = "as=1 seq=15";
459			break;
460		}
461	}
462
463	if (patch != NULL)
464		config = hdaa_widget_pin_patch(config, patch);
465	HDA_BOOTVERBOSE(
466		if (config != orig)
467			device_printf(w->devinfo->dev,
468			    "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
469			    nid, orig, config);
470	);
471	w->wclass.pin.config = config;
472}
473
474static void
475hdaa_widget_patch(struct hdaa_widget *w)
476{
477	struct hdaa_devinfo *devinfo = w->devinfo;
478	uint32_t orig;
479	nid_t beeper = -1;
480
481	orig = w->param.widget_cap;
482	/* On some codecs beeper is an input pin, but it is not recordable
483	   alone. Also most of BIOSes does not declare beeper pin.
484	   Change beeper pin node type to beeper to help parser. */
485	switch (hdaa_codec_id(devinfo)) {
486	case HDA_CODEC_AD1882:
487	case HDA_CODEC_AD1883:
488	case HDA_CODEC_AD1984:
489	case HDA_CODEC_AD1984A:
490	case HDA_CODEC_AD1984B:
491	case HDA_CODEC_AD1987:
492	case HDA_CODEC_AD1988:
493	case HDA_CODEC_AD1988B:
494	case HDA_CODEC_AD1989B:
495		beeper = 26;
496		break;
497	case HDA_CODEC_ALC260:
498		beeper = 23;
499		break;
500	}
501	if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
502	    hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
503		beeper = 29;
504	if (w->nid == beeper) {
505		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
506		w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
507		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
508		w->waspin = 1;
509	}
510	/*
511	 * Clear "digital" flag from digital mic input, as its signal then goes
512	 * to "analog" mixer and this separation just limits functionaity.
513	 */
514	if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A &&
515	    w->nid == 23)
516		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK;
517	HDA_BOOTVERBOSE(
518		if (w->param.widget_cap != orig) {
519			device_printf(w->devinfo->dev,
520			    "Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
521			    w->nid, orig, w->param.widget_cap);
522		}
523	);
524
525	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
526		hdac_pin_patch(w);
527}
528
529void
530hdaa_patch(struct hdaa_devinfo *devinfo)
531{
532	struct hdaa_widget *w;
533	uint32_t id, subid, subsystemid;
534	int i;
535
536	id = hdaa_codec_id(devinfo);
537	subid = hdaa_card_id(devinfo);
538	subsystemid = hda_get_subsystem_id(devinfo->dev);
539
540	/*
541	 * Quirks
542	 */
543	for (i = 0; i < nitems(hdac_quirks); i++) {
544		if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
545		    HDA_DEV_MATCH(hdac_quirks[i].id, id) &&
546		    HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid)))
547			continue;
548		devinfo->quirks |= hdac_quirks[i].set;
549		devinfo->quirks &= ~(hdac_quirks[i].unset);
550		devinfo->gpio = hdac_quirks[i].gpio;
551	}
552
553	/* Apply per-widget patch. */
554	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
555		w = hdaa_widget_get(devinfo, i);
556		if (w == NULL)
557			continue;
558		hdaa_widget_patch(w);
559	}
560
561	switch (id) {
562	case HDA_CODEC_AD1983:
563		/*
564		 * This CODEC has several possible usages, but none
565		 * fit the parser best. Help parser to choose better.
566		 */
567		/* Disable direct unmixed playback to get pcm volume. */
568		w = hdaa_widget_get(devinfo, 5);
569		if (w != NULL)
570			w->connsenable[0] = 0;
571		w = hdaa_widget_get(devinfo, 6);
572		if (w != NULL)
573			w->connsenable[0] = 0;
574		w = hdaa_widget_get(devinfo, 11);
575		if (w != NULL)
576			w->connsenable[0] = 0;
577		/* Disable mic and line selectors. */
578		w = hdaa_widget_get(devinfo, 12);
579		if (w != NULL)
580			w->connsenable[1] = 0;
581		w = hdaa_widget_get(devinfo, 13);
582		if (w != NULL)
583			w->connsenable[1] = 0;
584		/* Disable recording from mono playback mix. */
585		w = hdaa_widget_get(devinfo, 20);
586		if (w != NULL)
587			w->connsenable[3] = 0;
588		break;
589	case HDA_CODEC_AD1986A:
590		/*
591		 * This CODEC has overcomplicated input mixing.
592		 * Make some cleaning there.
593		 */
594		/* Disable input mono mixer. Not needed and not supported. */
595		w = hdaa_widget_get(devinfo, 43);
596		if (w != NULL)
597			w->enable = 0;
598		/* Disable any with any input mixing mesh. Use separately. */
599		w = hdaa_widget_get(devinfo, 39);
600		if (w != NULL)
601			w->enable = 0;
602		w = hdaa_widget_get(devinfo, 40);
603		if (w != NULL)
604			w->enable = 0;
605		w = hdaa_widget_get(devinfo, 41);
606		if (w != NULL)
607			w->enable = 0;
608		w = hdaa_widget_get(devinfo, 42);
609		if (w != NULL)
610			w->enable = 0;
611		/* Disable duplicate mixer node connector. */
612		w = hdaa_widget_get(devinfo, 15);
613		if (w != NULL)
614			w->connsenable[3] = 0;
615		/* There is only one mic preamplifier, use it effectively. */
616		w = hdaa_widget_get(devinfo, 31);
617		if (w != NULL) {
618			if ((w->wclass.pin.config &
619			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
620			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
621				w = hdaa_widget_get(devinfo, 16);
622				if (w != NULL)
623				    w->connsenable[2] = 0;
624			} else {
625				w = hdaa_widget_get(devinfo, 15);
626				if (w != NULL)
627				    w->connsenable[0] = 0;
628			}
629		}
630		w = hdaa_widget_get(devinfo, 32);
631		if (w != NULL) {
632			if ((w->wclass.pin.config &
633			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
634			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
635				w = hdaa_widget_get(devinfo, 16);
636				if (w != NULL)
637				    w->connsenable[0] = 0;
638			} else {
639				w = hdaa_widget_get(devinfo, 15);
640				if (w != NULL)
641				    w->connsenable[1] = 0;
642			}
643		}
644
645		if (subid == ASUS_A8X_SUBVENDOR) {
646			/*
647			 * This is just plain ridiculous.. There
648			 * are several A8 series that share the same
649			 * pci id but works differently (EAPD).
650			 */
651			w = hdaa_widget_get(devinfo, 26);
652			if (w != NULL && w->type ==
653			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
654			    (w->wclass.pin.config &
655			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
656			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
657				devinfo->quirks &=
658				    ~HDAA_QUIRK_EAPDINV;
659		}
660		break;
661	case HDA_CODEC_AD1981HD:
662		/*
663		 * This CODEC has very unusual design with several
664		 * points inappropriate for the present parser.
665		 */
666		/* Disable recording from mono playback mix. */
667		w = hdaa_widget_get(devinfo, 21);
668		if (w != NULL)
669			w->connsenable[3] = 0;
670		/* Disable rear to front mic mixer, use separately. */
671		w = hdaa_widget_get(devinfo, 31);
672		if (w != NULL)
673			w->enable = 0;
674		/* Disable direct playback, use mixer. */
675		w = hdaa_widget_get(devinfo, 5);
676		if (w != NULL)
677			w->connsenable[0] = 0;
678		w = hdaa_widget_get(devinfo, 6);
679		if (w != NULL)
680			w->connsenable[0] = 0;
681		w = hdaa_widget_get(devinfo, 9);
682		if (w != NULL)
683			w->connsenable[0] = 0;
684		w = hdaa_widget_get(devinfo, 24);
685		if (w != NULL)
686			w->connsenable[0] = 0;
687		break;
688	case HDA_CODEC_ALC269:
689		/*
690		 * ASUS EeePC 1001px has strange variant of ALC269 CODEC,
691		 * that mutes speaker if unused mixer at NID 15 is muted.
692		 * Probably CODEC incorrectly reports internal connections.
693		 * Hide that muter from the driver.  There are several CODECs
694		 * sharing this ID and I have not enough information about
695		 * them to implement more universal solution.
696		 */
697		if (subid == 0x84371043) {
698			w = hdaa_widget_get(devinfo, 15);
699			if (w != NULL)
700				w->param.inamp_cap = 0;
701		}
702		break;
703	case HDA_CODEC_CX20582:
704	case HDA_CODEC_CX20583:
705	case HDA_CODEC_CX20584:
706	case HDA_CODEC_CX20585:
707	case HDA_CODEC_CX20590:
708		/*
709		 * These codecs have extra connectivity on record side
710		 * too reach for the present parser.
711		 */
712		w = hdaa_widget_get(devinfo, 20);
713		if (w != NULL)
714			w->connsenable[1] = 0;
715		w = hdaa_widget_get(devinfo, 21);
716		if (w != NULL)
717			w->connsenable[1] = 0;
718		w = hdaa_widget_get(devinfo, 22);
719		if (w != NULL)
720			w->connsenable[0] = 0;
721		break;
722	case HDA_CODEC_VT1708S_0:
723	case HDA_CODEC_VT1708S_1:
724	case HDA_CODEC_VT1708S_2:
725	case HDA_CODEC_VT1708S_3:
726	case HDA_CODEC_VT1708S_4:
727	case HDA_CODEC_VT1708S_5:
728	case HDA_CODEC_VT1708S_6:
729	case HDA_CODEC_VT1708S_7:
730		/*
731		 * These codecs have hidden mic boost controls.
732		 */
733		w = hdaa_widget_get(devinfo, 26);
734		if (w != NULL)
735			w->param.inamp_cap =
736			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
737			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
738			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
739		w = hdaa_widget_get(devinfo, 30);
740		if (w != NULL)
741			w->param.inamp_cap =
742			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
743			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
744			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
745		break;
746	}
747}
748
749static uint32_t
750hdaa_read_coef(device_t dev, nid_t nid, uint16_t idx)
751{
752
753	hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
754	return (hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid)));
755}
756
757static uint32_t
758hdaa_write_coef(device_t dev, nid_t nid, uint16_t idx, uint16_t val)
759{
760
761	hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
762	return (hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, val)));
763}
764
765void
766hdaa_patch_direct(struct hdaa_devinfo *devinfo)
767{
768	device_t dev = devinfo->dev;
769	uint32_t id, subid, val;
770
771	id = hdaa_codec_id(devinfo);
772	subid = hdaa_card_id(devinfo);
773
774	switch (id) {
775	case HDA_CODEC_VT1708S_0:
776	case HDA_CODEC_VT1708S_1:
777	case HDA_CODEC_VT1708S_2:
778	case HDA_CODEC_VT1708S_3:
779	case HDA_CODEC_VT1708S_4:
780	case HDA_CODEC_VT1708S_5:
781	case HDA_CODEC_VT1708S_6:
782	case HDA_CODEC_VT1708S_7:
783		/* Enable Mic Boost Volume controls. */
784		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
785		    0xf98, 0x01));
786		/* Fall though */
787	case HDA_CODEC_VT1818S:
788		/* Don't bypass mixer. */
789		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
790		    0xf88, 0xc0));
791		break;
792	case HDA_CODEC_ALC1150:
793		if (subid == 0xd9781462) {
794			/* Too low volume on MSI H170 GAMING M3. */
795			hdaa_write_coef(dev, 0x20, 0x07, 0x7cb);
796		}
797		break;
798	}
799	if (id == HDA_CODEC_ALC255 || id == HDA_CODEC_ALC256) {
800		val = hdaa_read_coef(dev, 0x20, 0x46);
801		hdaa_write_coef(dev, 0x20, 0x46, val|0x3000);
802	}
803	if (subid == APPLE_INTEL_MAC)
804		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
805		    0x7e7, 0));
806	if (id == HDA_CODEC_ALC269) {
807		if (subid == 0x16e31043 || subid == 0x831a1043 ||
808		    subid == 0x834a1043 || subid == 0x83981043 ||
809		    subid == 0x83ce1043) {
810			/*
811			 * The digital mics on some Asus laptops produce
812			 * differential signals instead of expected stereo.
813			 * That results in silence if downmixing to mono.
814			 * To workaround, make codec handle the signal as mono.
815			 */
816			val = hdaa_read_coef(dev, 0x20, 0x07);
817			hdaa_write_coef(dev, 0x20, 0x07, val|0x80);
818		}
819		if (subid == 0x15171043) {
820			/* Increase output amp on ASUS UX31A by +5dB. */
821			hdaa_write_coef(dev, 0x20, 0x12, 0x2800);
822		}
823	}
824}
825