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