xref: /freebsd/sys/dev/sound/pci/hda/hdaa_patches.c (revision 5f624d923db0f2fb33990948cffdc24da44deaa8)
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_ALC256 && (subid == DELL_I7577_SUBVENDOR ||
332 	    subid == DELL_L7480_SUBVENDOR)) {
333 		switch (nid) {
334 		case 20:
335 			patch_str = "as=1 seq=0";
336 			break;
337 		case 33:
338 			patch_str = "as=1 seq=15";
339 			break;
340 		}
341 	} else if (id == HDA_CODEC_ALC257 &&
342 	    (subid == LENOVO_L5AMD_SUBVENDOR ||
343 	    subid == LENOVO_L5INTEL_SUBVENDOR ||
344 	    subid == LENOVO_IDEAPAD3_SUBVENDOR ||
345 	    subid == LENOVO_V15_SUBVENDOR)) {
346 		switch (nid) {
347 		case 20:
348 			patch_str = "as=1 seq=0";
349 			break;
350 		case 33:
351 			patch_str = "as=1 seq=15";
352 			break;
353 		}
354 	} else if (id == HDA_CODEC_IDT92HD95B &&
355 	    (subid == FRAMEWORK_LAPTOP_0001_SUBVENDOR ||
356 	    subid == FRAMEWORK_LAPTOP_0002_SUBVENDOR ||
357 	    subid == FRAMEWORK_LAPTOP_0003_SUBVENDOR)) {
358 		switch (nid) {
359 		case 10:
360 			patch_str = "as=1 seq=15 color=Black loc=Left";
361 			break;
362 		case 11:
363 			patch_str = "as=3 seq=15 color=Black loc=Left";
364 			break;
365 		}
366 	} else if ((id == HDA_CODEC_ALC295 &&
367 	    subid == FRAMEWORK_LAPTOP_0005_SUBVENDOR) ||
368 	    (id == HDA_CODEC_ALC285 &&
369 	    subid == FRAMEWORK_LAPTOP_000D_SUBVENDOR)) {
370 		switch (nid) {
371 		case 20:
372 			/*
373 			 * This pin is a duplicate of pin 23 (both as=1 seq=0),
374 			 * which ends up in the driver disabling the
375 			 * association altogether. Since sound quality from pin
376 			 * 23 seems to be better, configure this one as a back
377 			 * speaker.
378 			 */
379 			patch_str = "as=1 seq=2";
380 			break;
381 		}
382 	} else if (id == HDA_CODEC_ALC295 &&
383 	    subid == FRAMEWORK_LAPTOP_0006_SUBVENDOR) {
384 		switch (nid) {
385 		case 33:
386 			patch_str = "as=1 seq=15 color=Black loc=Left";
387 			break;
388 		}
389 	} else if (id == HDA_CODEC_ALC230 &&
390 	    subid == LENOVO_IDEAPAD330_SUBVENDOR) {
391 		switch (nid) {
392 		case 20:
393 			patch_str = "as=1 seq=0 device=Speaker";
394 			break;
395 		case 33:
396 			patch_str = "as=1 seq=15 device=Headphones";
397 			break;
398 		}
399 	} else if (id == HDA_CODEC_ALC269 &&
400 	    subid == LENOVO_X230_SUBVENDOR) {
401 		switch (nid) {
402 		case 21:
403 			patch_str = "as=1 seq=15";
404 			break;
405 		case 24:
406 			patch_str = "as=4 seq=15";
407 			break;
408 		}
409 	} else if (id == HDA_CODEC_ALC294 &&
410 	    subid == ASUS_UX331_SUBVENDOR) {
411 		switch (nid) {
412 		case 25:
413 			/* XXX You are not expected to understand this. */
414 			config = 0x01a1103c;
415 			break;
416 		case 33:
417 			patch_str = "as=1 seq=15";
418 			break;
419 		}
420 	} else {
421 		/*
422 		 * loop over hdaa_model_pin_patch
423 		 */
424 		struct pin_patch_t *pin_patches = NULL;
425 
426 		pin_patches = match_pin_patches(id, subid);
427 
428 		if (pin_patches != NULL) {
429 			for (struct pin_patch_t *patch = pin_patches; patch->type; patch++) {
430 				if (nid == patch->nid) {
431 					switch (patch->type) {
432 					case PIN_PATCH_TYPE_STRING:
433 						patch_str = patch->patch.string;
434 						break;
435 					case PIN_PATCH_TYPE_MASK:
436 						config &= ~patch->patch.mask[0];
437 						config |= patch->patch.mask[1];
438 						break;
439 					case PIN_PATCH_TYPE_OVERRIDE:
440 						config = patch->patch.override;
441 						break;
442 					default:
443 						/* should panic hard */
444 						break;
445 					}
446 					break;
447 				}
448 			}
449 		}
450 	}
451 
452 	if (patch_str != NULL)
453 		config = hdaa_widget_pin_patch(config, patch_str);
454 	HDA_BOOTVERBOSE(
455 		if (config != orig)
456 			device_printf(w->devinfo->dev,
457 			    "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
458 			    nid, orig, config);
459 	);
460 	w->wclass.pin.config = config;
461 }
462 
463 static void
hdaa_widget_patch(struct hdaa_widget * w)464 hdaa_widget_patch(struct hdaa_widget *w)
465 {
466 	struct hdaa_devinfo *devinfo = w->devinfo;
467 	uint32_t orig;
468 	nid_t beeper = -1;
469 
470 	orig = w->param.widget_cap;
471 	/* On some codecs beeper is an input pin, but it is not recordable
472 	   alone. Also most of BIOSes does not declare beeper pin.
473 	   Change beeper pin node type to beeper to help parser. */
474 	switch (hdaa_codec_id(devinfo)) {
475 	case HDA_CODEC_AD1882:
476 	case HDA_CODEC_AD1883:
477 	case HDA_CODEC_AD1984:
478 	case HDA_CODEC_AD1984A:
479 	case HDA_CODEC_AD1984B:
480 	case HDA_CODEC_AD1987:
481 	case HDA_CODEC_AD1988:
482 	case HDA_CODEC_AD1988B:
483 	case HDA_CODEC_AD1989B:
484 		beeper = 26;
485 		break;
486 	case HDA_CODEC_ALC260:
487 		beeper = 23;
488 		break;
489 	}
490 	if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
491 	    hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
492 		beeper = 29;
493 	if (w->nid == beeper) {
494 		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
495 		w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
496 		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
497 		w->waspin = 1;
498 	}
499 	/*
500 	 * Clear "digital" flag from digital mic input, as its signal then goes
501 	 * to "analog" mixer and this separation just limits functionaity.
502 	 */
503 	if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A &&
504 	    w->nid == 23)
505 		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK;
506 	HDA_BOOTVERBOSE(
507 		if (w->param.widget_cap != orig) {
508 			device_printf(w->devinfo->dev,
509 			    "Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
510 			    w->nid, orig, w->param.widget_cap);
511 		}
512 	);
513 
514 	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
515 		hdac_pin_patch(w);
516 }
517 
518 void
hdaa_patch(struct hdaa_devinfo * devinfo)519 hdaa_patch(struct hdaa_devinfo *devinfo)
520 {
521 	struct hdaa_widget *w;
522 	uint32_t id, subid, subsystemid;
523 	int i;
524 
525 	id = hdaa_codec_id(devinfo);
526 	subid = hdaa_card_id(devinfo);
527 	subsystemid = hda_get_subsystem_id(devinfo->dev);
528 
529 	/*
530 	 * Quirks
531 	 */
532 	for (i = 0; i < nitems(hdac_quirks); i++) {
533 		if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
534 		    HDA_DEV_MATCH(hdac_quirks[i].id, id) &&
535 		    HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid)))
536 			continue;
537 		devinfo->quirks |= hdac_quirks[i].set;
538 		devinfo->quirks &= ~(hdac_quirks[i].unset);
539 		devinfo->gpio = hdac_quirks[i].gpio;
540 	}
541 
542 	/* Apply per-widget patch. */
543 	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
544 		w = hdaa_widget_get(devinfo, i);
545 		if (w == NULL)
546 			continue;
547 		hdaa_widget_patch(w);
548 	}
549 
550 	switch (id) {
551 	case HDA_CODEC_AD1983:
552 		/*
553 		 * This CODEC has several possible usages, but none
554 		 * fit the parser best. Help parser to choose better.
555 		 */
556 		/* Disable direct unmixed playback to get pcm volume. */
557 		w = hdaa_widget_get(devinfo, 5);
558 		if (w != NULL)
559 			w->connsenable[0] = 0;
560 		w = hdaa_widget_get(devinfo, 6);
561 		if (w != NULL)
562 			w->connsenable[0] = 0;
563 		w = hdaa_widget_get(devinfo, 11);
564 		if (w != NULL)
565 			w->connsenable[0] = 0;
566 		/* Disable mic and line selectors. */
567 		w = hdaa_widget_get(devinfo, 12);
568 		if (w != NULL)
569 			w->connsenable[1] = 0;
570 		w = hdaa_widget_get(devinfo, 13);
571 		if (w != NULL)
572 			w->connsenable[1] = 0;
573 		/* Disable recording from mono playback mix. */
574 		w = hdaa_widget_get(devinfo, 20);
575 		if (w != NULL)
576 			w->connsenable[3] = 0;
577 		break;
578 	case HDA_CODEC_AD1986A:
579 		/*
580 		 * This CODEC has overcomplicated input mixing.
581 		 * Make some cleaning there.
582 		 */
583 		/* Disable input mono mixer. Not needed and not supported. */
584 		w = hdaa_widget_get(devinfo, 43);
585 		if (w != NULL)
586 			w->enable = 0;
587 		/* Disable any with any input mixing mesh. Use separately. */
588 		w = hdaa_widget_get(devinfo, 39);
589 		if (w != NULL)
590 			w->enable = 0;
591 		w = hdaa_widget_get(devinfo, 40);
592 		if (w != NULL)
593 			w->enable = 0;
594 		w = hdaa_widget_get(devinfo, 41);
595 		if (w != NULL)
596 			w->enable = 0;
597 		w = hdaa_widget_get(devinfo, 42);
598 		if (w != NULL)
599 			w->enable = 0;
600 		/* Disable duplicate mixer node connector. */
601 		w = hdaa_widget_get(devinfo, 15);
602 		if (w != NULL)
603 			w->connsenable[3] = 0;
604 		/* There is only one mic preamplifier, use it effectively. */
605 		w = hdaa_widget_get(devinfo, 31);
606 		if (w != NULL) {
607 			if ((w->wclass.pin.config &
608 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
609 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
610 				w = hdaa_widget_get(devinfo, 16);
611 				if (w != NULL)
612 				    w->connsenable[2] = 0;
613 			} else {
614 				w = hdaa_widget_get(devinfo, 15);
615 				if (w != NULL)
616 				    w->connsenable[0] = 0;
617 			}
618 		}
619 		w = hdaa_widget_get(devinfo, 32);
620 		if (w != NULL) {
621 			if ((w->wclass.pin.config &
622 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
623 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
624 				w = hdaa_widget_get(devinfo, 16);
625 				if (w != NULL)
626 				    w->connsenable[0] = 0;
627 			} else {
628 				w = hdaa_widget_get(devinfo, 15);
629 				if (w != NULL)
630 				    w->connsenable[1] = 0;
631 			}
632 		}
633 
634 		if (subid == ASUS_A8X_SUBVENDOR) {
635 			/*
636 			 * This is just plain ridiculous.. There
637 			 * are several A8 series that share the same
638 			 * pci id but works differently (EAPD).
639 			 */
640 			w = hdaa_widget_get(devinfo, 26);
641 			if (w != NULL && w->type ==
642 			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
643 			    (w->wclass.pin.config &
644 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
645 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
646 				devinfo->quirks &=
647 				    ~HDAA_QUIRK_EAPDINV;
648 		}
649 		break;
650 	case HDA_CODEC_AD1981HD:
651 		/*
652 		 * This CODEC has very unusual design with several
653 		 * points inappropriate for the present parser.
654 		 */
655 		/* Disable recording from mono playback mix. */
656 		w = hdaa_widget_get(devinfo, 21);
657 		if (w != NULL)
658 			w->connsenable[3] = 0;
659 		/* Disable rear to front mic mixer, use separately. */
660 		w = hdaa_widget_get(devinfo, 31);
661 		if (w != NULL)
662 			w->enable = 0;
663 		/* Disable direct playback, use mixer. */
664 		w = hdaa_widget_get(devinfo, 5);
665 		if (w != NULL)
666 			w->connsenable[0] = 0;
667 		w = hdaa_widget_get(devinfo, 6);
668 		if (w != NULL)
669 			w->connsenable[0] = 0;
670 		w = hdaa_widget_get(devinfo, 9);
671 		if (w != NULL)
672 			w->connsenable[0] = 0;
673 		w = hdaa_widget_get(devinfo, 24);
674 		if (w != NULL)
675 			w->connsenable[0] = 0;
676 		break;
677 	case HDA_CODEC_ALC269:
678 		/*
679 		 * ASUS EeePC 1001px has strange variant of ALC269 CODEC,
680 		 * that mutes speaker if unused mixer at NID 15 is muted.
681 		 * Probably CODEC incorrectly reports internal connections.
682 		 * Hide that muter from the driver.  There are several CODECs
683 		 * sharing this ID and I have not enough information about
684 		 * them to implement more universal solution.
685 		 */
686 		if (subid == 0x84371043) {
687 			w = hdaa_widget_get(devinfo, 15);
688 			if (w != NULL)
689 				w->param.inamp_cap = 0;
690 		}
691 		break;
692 	case HDA_CODEC_CX20582:
693 	case HDA_CODEC_CX20583:
694 	case HDA_CODEC_CX20584:
695 	case HDA_CODEC_CX20585:
696 	case HDA_CODEC_CX20590:
697 		/*
698 		 * These codecs have extra connectivity on record side
699 		 * too reach for the present parser.
700 		 */
701 		w = hdaa_widget_get(devinfo, 20);
702 		if (w != NULL)
703 			w->connsenable[1] = 0;
704 		w = hdaa_widget_get(devinfo, 21);
705 		if (w != NULL)
706 			w->connsenable[1] = 0;
707 		w = hdaa_widget_get(devinfo, 22);
708 		if (w != NULL)
709 			w->connsenable[0] = 0;
710 		break;
711 	case HDA_CODEC_VT1708S_0:
712 	case HDA_CODEC_VT1708S_1:
713 	case HDA_CODEC_VT1708S_2:
714 	case HDA_CODEC_VT1708S_3:
715 	case HDA_CODEC_VT1708S_4:
716 	case HDA_CODEC_VT1708S_5:
717 	case HDA_CODEC_VT1708S_6:
718 	case HDA_CODEC_VT1708S_7:
719 		/*
720 		 * These codecs have hidden mic boost controls.
721 		 */
722 		w = hdaa_widget_get(devinfo, 26);
723 		if (w != NULL)
724 			w->param.inamp_cap =
725 			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
726 			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
727 			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
728 		w = hdaa_widget_get(devinfo, 30);
729 		if (w != NULL)
730 			w->param.inamp_cap =
731 			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
732 			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
733 			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
734 		break;
735 	}
736 }
737 
738 static uint32_t
hdaa_read_coef(device_t dev,nid_t nid,uint16_t idx)739 hdaa_read_coef(device_t dev, nid_t nid, uint16_t idx)
740 {
741 
742 	hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
743 	return (hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid)));
744 }
745 
746 static uint32_t
hdaa_write_coef(device_t dev,nid_t nid,uint16_t idx,uint16_t val)747 hdaa_write_coef(device_t dev, nid_t nid, uint16_t idx, uint16_t val)
748 {
749 
750 	hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
751 	return (hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, val)));
752 }
753 
754 void
hdaa_patch_direct(struct hdaa_devinfo * devinfo)755 hdaa_patch_direct(struct hdaa_devinfo *devinfo)
756 {
757 	device_t dev = devinfo->dev;
758 	uint32_t id, subid, val;
759 
760 	id = hdaa_codec_id(devinfo);
761 	subid = hdaa_card_id(devinfo);
762 
763 	switch (id) {
764 	case HDA_CODEC_VT1708S_0:
765 	case HDA_CODEC_VT1708S_1:
766 	case HDA_CODEC_VT1708S_2:
767 	case HDA_CODEC_VT1708S_3:
768 	case HDA_CODEC_VT1708S_4:
769 	case HDA_CODEC_VT1708S_5:
770 	case HDA_CODEC_VT1708S_6:
771 	case HDA_CODEC_VT1708S_7:
772 		/* Enable Mic Boost Volume controls. */
773 		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
774 		    0xf98, 0x01));
775 		/* Fall though */
776 	case HDA_CODEC_VT1818S:
777 		/* Don't bypass mixer. */
778 		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
779 		    0xf88, 0xc0));
780 		break;
781 	case HDA_CODEC_ALC1150:
782 		if (subid == 0xd9781462) {
783 			/* Too low volume on MSI H170 GAMING M3. */
784 			hdaa_write_coef(dev, 0x20, 0x07, 0x7cb);
785 		}
786 		break;
787 	}
788 	if (id == HDA_CODEC_ALC255 || id == HDA_CODEC_ALC256) {
789 		val = hdaa_read_coef(dev, 0x20, 0x46);
790 		hdaa_write_coef(dev, 0x20, 0x46, val|0x3000);
791 	}
792 	if (subid == APPLE_INTEL_MAC)
793 		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
794 		    0x7e7, 0));
795 	if (id == HDA_CODEC_ALC269) {
796 		if (subid == 0x16e31043 || subid == 0x831a1043 ||
797 		    subid == 0x834a1043 || subid == 0x83981043 ||
798 		    subid == 0x83ce1043) {
799 			/*
800 			 * The digital mics on some Asus laptops produce
801 			 * differential signals instead of expected stereo.
802 			 * That results in silence if downmixing to mono.
803 			 * To workaround, make codec handle the signal as mono.
804 			 */
805 			val = hdaa_read_coef(dev, 0x20, 0x07);
806 			hdaa_write_coef(dev, 0x20, 0x07, val|0x80);
807 		}
808 		if (subid == 0x15171043) {
809 			/* Increase output amp on ASUS UX31A by +5dB. */
810 			hdaa_write_coef(dev, 0x20, 0x12, 0x2800);
811 		}
812 	}
813 }
814