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