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