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