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