xref: /freebsd-11-stable/sys/dev/sound/pci/hda/hdaa_patches.c (revision e3390a91597677644dbd07059e7fb71cb61f6b03)
1 /*-
2  * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca>
3  * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org>
4  * Copyright (c) 2008-2012 Alexander Motin <mav@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
31  */
32 
33 #ifdef HAVE_KERNEL_OPTION_HEADERS
34 #include "opt_snd.h"
35 #endif
36 
37 #include <dev/sound/pcm/sound.h>
38 
39 #include <sys/ctype.h>
40 
41 #include <dev/sound/pci/hda/hdac.h>
42 #include <dev/sound/pci/hda/hdaa.h>
43 #include <dev/sound/pci/hda/hda_reg.h>
44 
45 SND_DECLARE_FILE("$FreeBSD$");
46 
47 static const struct {
48 	uint32_t model;
49 	uint32_t id;
50 	uint32_t subsystemid;
51 	uint32_t set, unset;
52 	uint32_t gpio;
53 } hdac_quirks[] = {
54 	/*
55 	 * XXX Force stereo quirk. Monoural recording / playback
56 	 *     on few codecs (especially ALC880) seems broken or
57 	 *     perhaps unsupported.
58 	 */
59 	{ HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL,
60 	    HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0,
61 	    0 },
62 	{ ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL,
63 	    0, 0,
64 	    HDAA_GPIO_SET(0) },
65 	{ ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL,
66 	    0, 0,
67 	    HDAA_GPIO_SET(0) },
68 	{ ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
69 	    0, 0,
70 	    HDAA_GPIO_SET(0) },
71 	{ ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
72 	    0, 0,
73 	    HDAA_GPIO_SET(0) },
74 	{ ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
75 	    0, 0,
76 	    HDAA_GPIO_SET(0) },
77 	{ ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
78 	    0, 0,
79 	    HDAA_GPIO_SET(0) },
80 	{ ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
81 	    HDAA_QUIRK_EAPDINV, 0,
82 	    0 },
83 	{ ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
84 	    HDAA_QUIRK_EAPDINV, 0,
85 	    0 },
86 	{ ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
87 	    HDAA_QUIRK_OVREF, 0,
88 	    0 },
89 	{ UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
90 	    HDAA_QUIRK_OVREF, 0,
91 	    0 },
92 	/*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, HDA_MATCH_ALL,
93 	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
94 	    0 },*/
95 	{ MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
96 	    0, 0,
97 	    HDAA_GPIO_SET(1) },
98 	{ LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
99 	    HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0,
100 	    0 },
101 	{ SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
102 	    HDAA_QUIRK_EAPDINV, 0,
103 	    0 },
104 	{ APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL,
105 	    HDAA_QUIRK_OVREF50, 0,
106 	    HDAA_GPIO_SET(0) },
107 	{ APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL,
108 	    0, 0,
109 	    HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) },
110 	{ APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL,
111 	    0, 0,
112 	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
113 	{ APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL,
114 	    0, 0,
115 	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
116 	{ APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL,
117 	    0, 0,
118 	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
119 	{ HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL,
120 	    0, 0,
121 	    HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
122 	{ DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
123 	    0, 0,
124 	    HDAA_GPIO_SET(0) },
125 	{ DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL,
126 	    0, 0,
127 	    HDAA_GPIO_SET(2) },
128 	{ DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
129 	    0, 0,
130 	    HDAA_GPIO_SET(0) },
131 	{ HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL,
132 	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
133 	    0 },
134 	{ HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL,
135 	    HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
136 	    0 },
137 	{ HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL,
138 	    0, HDAA_QUIRK_FORCESTEREO,
139 	    0 },
140 	/* Mac Pro 1,1 requires ovref for proper volume level. */
141 	{ 0x00000000, HDA_CODEC_ALC885, 0x106b0c00,
142 	    0, HDAA_QUIRK_OVREF,
143 	    0 }
144 };
145 
146 static void
hdac_pin_patch(struct hdaa_widget * w)147 hdac_pin_patch(struct hdaa_widget *w)
148 {
149 	const char *patch = NULL;
150 	uint32_t config, orig, id, subid;
151 	nid_t nid = w->nid;
152 
153 	config = orig = w->wclass.pin.config;
154 	id = hdaa_codec_id(w->devinfo);
155 	subid = hdaa_card_id(w->devinfo);
156 
157 	/* XXX: Old patches require complete review.
158 	 * Now they may create more problem then solve due to
159 	 * incorrect associations.
160 	 */
161 	if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) {
162 		switch (nid) {
163 		case 26:
164 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
165 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
166 			break;
167 		case 27:
168 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
169 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
170 			break;
171 		default:
172 			break;
173 		}
174 	} else if (id == HDA_CODEC_ALC880 &&
175 	    (subid == CLEVO_D900T_SUBVENDOR ||
176 	    subid == ASUS_M5200_SUBVENDOR)) {
177 		/*
178 		 * Super broken BIOS
179 		 */
180 		switch (nid) {
181 		case 24:	/* MIC1 */
182 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
183 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
184 			break;
185 		case 25:	/* XXX MIC2 */
186 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
187 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
188 			break;
189 		case 26:	/* LINE1 */
190 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
191 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
192 			break;
193 		case 27:	/* XXX LINE2 */
194 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
195 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
196 			break;
197 		case 28:	/* CD */
198 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
199 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
200 			break;
201 		}
202 	} else if (id == HDA_CODEC_ALC883 &&
203 	    (subid == MSI_MS034A_SUBVENDOR ||
204 	    HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) {
205 		switch (nid) {
206 		case 25:
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 28:
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_CX20549 && subid ==
220 	    HP_V3000_SUBVENDOR) {
221 		switch (nid) {
222 		case 18:
223 			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
224 			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
225 			break;
226 		case 20:
227 			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
228 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
229 			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
230 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
231 			break;
232 		case 21:
233 			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
234 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
235 			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
236 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
237 			break;
238 		}
239 	} else if (id == HDA_CODEC_CX20551 && subid ==
240 	    HP_DV5000_SUBVENDOR) {
241 		switch (nid) {
242 		case 20:
243 		case 21:
244 			config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
245 			config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
246 			break;
247 		}
248 	} else if (id == HDA_CODEC_ALC861 && subid ==
249 	    ASUS_W6F_SUBVENDOR) {
250 		switch (nid) {
251 		case 11:
252 			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
253 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
254 			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
255 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
256 			break;
257 		case 12:
258 		case 14:
259 		case 16:
260 		case 31:
261 		case 32:
262 			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
263 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
264 			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
265 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
266 			break;
267 		case 15:
268 			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
269 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
270 			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
271 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
272 			break;
273 		}
274 	} else if (id == HDA_CODEC_ALC861 && subid ==
275 	    UNIWILL_9075_SUBVENDOR) {
276 		switch (nid) {
277 		case 15:
278 			config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
279 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
280 			config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
281 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
282 			break;
283 		}
284 	}
285 
286 	/* New patches */
287 	if (id == HDA_CODEC_AD1984A &&
288 	    subid == LENOVO_X300_SUBVENDOR) {
289 		switch (nid) {
290 		case 17: /* Headphones with redirection */
291 			patch = "as=1 seq=15";
292 			break;
293 		case 20: /* Two mics together */
294 			patch = "as=2 seq=15";
295 			break;
296 		}
297 	} else if (id == HDA_CODEC_AD1986A &&
298 	    (subid == ASUS_M2NPVMX_SUBVENDOR ||
299 	    subid == ASUS_A8NVMCSM_SUBVENDOR ||
300 	    subid == ASUS_P5PL2_SUBVENDOR)) {
301 		switch (nid) {
302 		case 26: /* Headphones with redirection */
303 			patch = "as=1 seq=15";
304 			break;
305 		case 28: /* 5.1 out => 2.0 out + 1 input */
306 			patch = "device=Line-in as=8 seq=1";
307 			break;
308 		case 29: /* Can't use this as input, as the only available mic
309 			  * preamplifier is busy by front panel mic (nid 31).
310 			  * If you want to use this rear connector as mic input,
311 			  * you have to disable the front panel one. */
312 			patch = "as=0";
313 			break;
314 		case 31: /* Lot of inputs configured with as=15 and unusable */
315 			patch = "as=8 seq=3";
316 			break;
317 		case 32:
318 			patch = "as=8 seq=4";
319 			break;
320 		case 34:
321 			patch = "as=8 seq=5";
322 			break;
323 		case 36:
324 			patch = "as=8 seq=6";
325 			break;
326 		}
327 	} else if (id == HDA_CODEC_ALC260 &&
328 	    HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) {
329 		switch (nid) {
330 		case 16:
331 			patch = "seq=15 device=Headphones";
332 			break;
333 		}
334 	} else if (id == HDA_CODEC_ALC268) {
335 	    if (subid == ACER_T5320_SUBVENDOR) {
336 		switch (nid) {
337 		case 20: /* Headphones Jack */
338 			patch = "as=1 seq=15";
339 			break;
340 		}
341 	    }
342 	} else if (id == HDA_CODEC_CX20561 &&
343 	    subid == LENOVO_B450_SUBVENDOR) {
344 		switch (nid) {
345 		case 22:
346 			patch = "as=1 seq=15";
347 			break;
348 		}
349 	} else if (id == HDA_CODEC_CX20561 &&
350 	    subid == LENOVO_T400_SUBVENDOR) {
351 		switch (nid) {
352 		case 22:
353 			patch = "as=1 seq=15";
354 			break;
355 		case 26:
356 			patch = "as=1 seq=0";
357 			break;
358 		}
359 	} else if (id == HDA_CODEC_CX20590 &&
360 	    (subid == LENOVO_X1_SUBVENDOR ||
361 	    subid == LENOVO_X220_SUBVENDOR ||
362 	    subid == LENOVO_T420_SUBVENDOR ||
363 	    subid == LENOVO_T520_SUBVENDOR ||
364 	    subid == LENOVO_G580_SUBVENDOR)) {
365 		switch (nid) {
366 		case 25:
367 			patch = "as=1 seq=15";
368 			break;
369 		/*
370 		 * Group onboard mic and headphone mic
371 		 * together.  Fixes onboard mic.
372 		 */
373 		case 27:
374 			patch = "as=2 seq=15";
375 			break;
376 		case 35:
377 			patch = "as=2";
378 			break;
379 		}
380 	} else if (id == HDA_CODEC_ALC269 &&
381 	    (subid == LENOVO_X1CRBN_SUBVENDOR ||
382 	    subid == LENOVO_T430_SUBVENDOR ||
383 	    subid == LENOVO_T430S_SUBVENDOR ||
384 	    subid == LENOVO_T530_SUBVENDOR)) {
385 		switch (nid) {
386 		case 21:
387 			patch = "as=1 seq=15";
388 			break;
389 		}
390 	} else if (id == HDA_CODEC_ALC285 &&
391 	    subid == LENOVO_X120KH_SUBVENDOR) {
392 		switch (nid) {
393 		case 33:
394 			patch = "as=1 seq=15";
395 			break;
396 		}
397 	} else if (id == HDA_CODEC_ALC269 &&
398 	    subid == ASUS_UX31A_SUBVENDOR) {
399 		switch (nid) {
400 		case 33:
401 			patch = "as=1 seq=15";
402 			break;
403 		}
404 	} else if (id == HDA_CODEC_ALC892 &&
405 	    subid == INTEL_DH87RL_SUBVENDOR) {
406 		switch (nid) {
407 		case 27:
408 			patch = "as=1 seq=15";
409 			break;
410 		}
411 	} else if (id == HDA_CODEC_ALC292 &&
412 	    subid == LENOVO_X120BS_SUBVENDOR) {
413 		switch (nid) {
414 		case 21:
415 			patch = "as=1 seq=15";
416 			break;
417 		}
418 	}
419 
420 	if (patch != NULL)
421 		config = hdaa_widget_pin_patch(config, patch);
422 	HDA_BOOTVERBOSE(
423 		if (config != orig)
424 			device_printf(w->devinfo->dev,
425 			    "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
426 			    nid, orig, config);
427 	);
428 	w->wclass.pin.config = config;
429 }
430 
431 static void
hdaa_widget_patch(struct hdaa_widget * w)432 hdaa_widget_patch(struct hdaa_widget *w)
433 {
434 	struct hdaa_devinfo *devinfo = w->devinfo;
435 	uint32_t orig;
436 	nid_t beeper = -1;
437 
438 	orig = w->param.widget_cap;
439 	/* On some codecs beeper is an input pin, but it is not recordable
440 	   alone. Also most of BIOSes does not declare beeper pin.
441 	   Change beeper pin node type to beeper to help parser. */
442 	switch (hdaa_codec_id(devinfo)) {
443 	case HDA_CODEC_AD1882:
444 	case HDA_CODEC_AD1883:
445 	case HDA_CODEC_AD1984:
446 	case HDA_CODEC_AD1984A:
447 	case HDA_CODEC_AD1984B:
448 	case HDA_CODEC_AD1987:
449 	case HDA_CODEC_AD1988:
450 	case HDA_CODEC_AD1988B:
451 	case HDA_CODEC_AD1989B:
452 		beeper = 26;
453 		break;
454 	case HDA_CODEC_ALC260:
455 		beeper = 23;
456 		break;
457 	}
458 	if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
459 	    hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
460 		beeper = 29;
461 	if (w->nid == beeper) {
462 		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
463 		w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
464 		    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
465 		w->waspin = 1;
466 	}
467 	/*
468 	 * Clear "digital" flag from digital mic input, as its signal then goes
469 	 * to "analog" mixer and this separation just limits functionaity.
470 	 */
471 	if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A &&
472 	    w->nid == 23)
473 		w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK;
474 	HDA_BOOTVERBOSE(
475 		if (w->param.widget_cap != orig) {
476 			device_printf(w->devinfo->dev,
477 			    "Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
478 			    w->nid, orig, w->param.widget_cap);
479 		}
480 	);
481 
482 	if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
483 		hdac_pin_patch(w);
484 }
485 
486 void
hdaa_patch(struct hdaa_devinfo * devinfo)487 hdaa_patch(struct hdaa_devinfo *devinfo)
488 {
489 	struct hdaa_widget *w;
490 	uint32_t id, subid, subsystemid;
491 	int i;
492 
493 	id = hdaa_codec_id(devinfo);
494 	subid = hdaa_card_id(devinfo);
495 	subsystemid = hda_get_subsystem_id(devinfo->dev);
496 
497 	/*
498 	 * Quirks
499 	 */
500 	for (i = 0; i < nitems(hdac_quirks); i++) {
501 		if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
502 		    HDA_DEV_MATCH(hdac_quirks[i].id, id) &&
503 		    HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid)))
504 			continue;
505 		devinfo->quirks |= hdac_quirks[i].set;
506 		devinfo->quirks &= ~(hdac_quirks[i].unset);
507 		devinfo->gpio = hdac_quirks[i].gpio;
508 	}
509 
510 	/* Apply per-widget patch. */
511 	for (i = devinfo->startnode; i < devinfo->endnode; i++) {
512 		w = hdaa_widget_get(devinfo, i);
513 		if (w == NULL)
514 			continue;
515 		hdaa_widget_patch(w);
516 	}
517 
518 	switch (id) {
519 	case HDA_CODEC_AD1983:
520 		/*
521 		 * This CODEC has several possible usages, but none
522 		 * fit the parser best. Help parser to choose better.
523 		 */
524 		/* Disable direct unmixed playback to get pcm volume. */
525 		w = hdaa_widget_get(devinfo, 5);
526 		if (w != NULL)
527 			w->connsenable[0] = 0;
528 		w = hdaa_widget_get(devinfo, 6);
529 		if (w != NULL)
530 			w->connsenable[0] = 0;
531 		w = hdaa_widget_get(devinfo, 11);
532 		if (w != NULL)
533 			w->connsenable[0] = 0;
534 		/* Disable mic and line selectors. */
535 		w = hdaa_widget_get(devinfo, 12);
536 		if (w != NULL)
537 			w->connsenable[1] = 0;
538 		w = hdaa_widget_get(devinfo, 13);
539 		if (w != NULL)
540 			w->connsenable[1] = 0;
541 		/* Disable recording from mono playback mix. */
542 		w = hdaa_widget_get(devinfo, 20);
543 		if (w != NULL)
544 			w->connsenable[3] = 0;
545 		break;
546 	case HDA_CODEC_AD1986A:
547 		/*
548 		 * This CODEC has overcomplicated input mixing.
549 		 * Make some cleaning there.
550 		 */
551 		/* Disable input mono mixer. Not needed and not supported. */
552 		w = hdaa_widget_get(devinfo, 43);
553 		if (w != NULL)
554 			w->enable = 0;
555 		/* Disable any with any input mixing mesh. Use separately. */
556 		w = hdaa_widget_get(devinfo, 39);
557 		if (w != NULL)
558 			w->enable = 0;
559 		w = hdaa_widget_get(devinfo, 40);
560 		if (w != NULL)
561 			w->enable = 0;
562 		w = hdaa_widget_get(devinfo, 41);
563 		if (w != NULL)
564 			w->enable = 0;
565 		w = hdaa_widget_get(devinfo, 42);
566 		if (w != NULL)
567 			w->enable = 0;
568 		/* Disable duplicate mixer node connector. */
569 		w = hdaa_widget_get(devinfo, 15);
570 		if (w != NULL)
571 			w->connsenable[3] = 0;
572 		/* There is only one mic preamplifier, use it effectively. */
573 		w = hdaa_widget_get(devinfo, 31);
574 		if (w != NULL) {
575 			if ((w->wclass.pin.config &
576 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
577 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
578 				w = hdaa_widget_get(devinfo, 16);
579 				if (w != NULL)
580 				    w->connsenable[2] = 0;
581 			} else {
582 				w = hdaa_widget_get(devinfo, 15);
583 				if (w != NULL)
584 				    w->connsenable[0] = 0;
585 			}
586 		}
587 		w = hdaa_widget_get(devinfo, 32);
588 		if (w != NULL) {
589 			if ((w->wclass.pin.config &
590 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
591 			    HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
592 				w = hdaa_widget_get(devinfo, 16);
593 				if (w != NULL)
594 				    w->connsenable[0] = 0;
595 			} else {
596 				w = hdaa_widget_get(devinfo, 15);
597 				if (w != NULL)
598 				    w->connsenable[1] = 0;
599 			}
600 		}
601 
602 		if (subid == ASUS_A8X_SUBVENDOR) {
603 			/*
604 			 * This is just plain ridiculous.. There
605 			 * are several A8 series that share the same
606 			 * pci id but works differently (EAPD).
607 			 */
608 			w = hdaa_widget_get(devinfo, 26);
609 			if (w != NULL && w->type ==
610 			    HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
611 			    (w->wclass.pin.config &
612 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
613 			    HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
614 				devinfo->quirks &=
615 				    ~HDAA_QUIRK_EAPDINV;
616 		}
617 		break;
618 	case HDA_CODEC_AD1981HD:
619 		/*
620 		 * This CODEC has very unusual design with several
621 		 * points inappropriate for the present parser.
622 		 */
623 		/* Disable recording from mono playback mix. */
624 		w = hdaa_widget_get(devinfo, 21);
625 		if (w != NULL)
626 			w->connsenable[3] = 0;
627 		/* Disable rear to front mic mixer, use separately. */
628 		w = hdaa_widget_get(devinfo, 31);
629 		if (w != NULL)
630 			w->enable = 0;
631 		/* Disable direct playback, use mixer. */
632 		w = hdaa_widget_get(devinfo, 5);
633 		if (w != NULL)
634 			w->connsenable[0] = 0;
635 		w = hdaa_widget_get(devinfo, 6);
636 		if (w != NULL)
637 			w->connsenable[0] = 0;
638 		w = hdaa_widget_get(devinfo, 9);
639 		if (w != NULL)
640 			w->connsenable[0] = 0;
641 		w = hdaa_widget_get(devinfo, 24);
642 		if (w != NULL)
643 			w->connsenable[0] = 0;
644 		break;
645 	case HDA_CODEC_ALC269:
646 		/*
647 		 * ASUS EeePC 1001px has strange variant of ALC269 CODEC,
648 		 * that mutes speaker if unused mixer at NID 15 is muted.
649 		 * Probably CODEC incorrectly reports internal connections.
650 		 * Hide that muter from the driver.  There are several CODECs
651 		 * sharing this ID and I have not enough information about
652 		 * them to implement more universal solution.
653 		 */
654 		if (subid == 0x84371043) {
655 			w = hdaa_widget_get(devinfo, 15);
656 			if (w != NULL)
657 				w->param.inamp_cap = 0;
658 		}
659 		break;
660 	case HDA_CODEC_CX20582:
661 	case HDA_CODEC_CX20583:
662 	case HDA_CODEC_CX20584:
663 	case HDA_CODEC_CX20585:
664 	case HDA_CODEC_CX20590:
665 		/*
666 		 * These codecs have extra connectivity on record side
667 		 * too reach for the present parser.
668 		 */
669 		w = hdaa_widget_get(devinfo, 20);
670 		if (w != NULL)
671 			w->connsenable[1] = 0;
672 		w = hdaa_widget_get(devinfo, 21);
673 		if (w != NULL)
674 			w->connsenable[1] = 0;
675 		w = hdaa_widget_get(devinfo, 22);
676 		if (w != NULL)
677 			w->connsenable[0] = 0;
678 		break;
679 	case HDA_CODEC_VT1708S_0:
680 	case HDA_CODEC_VT1708S_1:
681 	case HDA_CODEC_VT1708S_2:
682 	case HDA_CODEC_VT1708S_3:
683 	case HDA_CODEC_VT1708S_4:
684 	case HDA_CODEC_VT1708S_5:
685 	case HDA_CODEC_VT1708S_6:
686 	case HDA_CODEC_VT1708S_7:
687 		/*
688 		 * These codecs have hidden mic boost controls.
689 		 */
690 		w = hdaa_widget_get(devinfo, 26);
691 		if (w != NULL)
692 			w->param.inamp_cap =
693 			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
694 			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
695 			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
696 		w = hdaa_widget_get(devinfo, 30);
697 		if (w != NULL)
698 			w->param.inamp_cap =
699 			    (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
700 			    (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
701 			    (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
702 		break;
703 	}
704 }
705 
706 static uint32_t
hdaa_read_coef(device_t dev,nid_t nid,uint16_t idx)707 hdaa_read_coef(device_t dev, nid_t nid, uint16_t idx)
708 {
709 
710 	hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
711 	return (hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid)));
712 }
713 
714 static uint32_t
hdaa_write_coef(device_t dev,nid_t nid,uint16_t idx,uint16_t val)715 hdaa_write_coef(device_t dev, nid_t nid, uint16_t idx, uint16_t val)
716 {
717 
718 	hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
719 	return (hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, val)));
720 }
721 
722 void
hdaa_patch_direct(struct hdaa_devinfo * devinfo)723 hdaa_patch_direct(struct hdaa_devinfo *devinfo)
724 {
725 	device_t dev = devinfo->dev;
726 	uint32_t id, subid, val;
727 
728 	id = hdaa_codec_id(devinfo);
729 	subid = hdaa_card_id(devinfo);
730 
731 	switch (id) {
732 	case HDA_CODEC_VT1708S_0:
733 	case HDA_CODEC_VT1708S_1:
734 	case HDA_CODEC_VT1708S_2:
735 	case HDA_CODEC_VT1708S_3:
736 	case HDA_CODEC_VT1708S_4:
737 	case HDA_CODEC_VT1708S_5:
738 	case HDA_CODEC_VT1708S_6:
739 	case HDA_CODEC_VT1708S_7:
740 		/* Enable Mic Boost Volume controls. */
741 		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
742 		    0xf98, 0x01));
743 		/* Fall though */
744 	case HDA_CODEC_VT1818S:
745 		/* Don't bypass mixer. */
746 		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
747 		    0xf88, 0xc0));
748 		break;
749 	case HDA_CODEC_ALC1150:
750 		if (subid == 0xd9781462) {
751 			/* Too low volume on MSI H170 GAMING M3. */
752 			hdaa_write_coef(dev, 0x20, 0x07, 0x7cb);
753 		}
754 		break;
755 	}
756 	if (subid == APPLE_INTEL_MAC)
757 		hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
758 		    0x7e7, 0));
759 	if (id == HDA_CODEC_ALC269) {
760 		if (subid == 0x16e31043 || subid == 0x831a1043 ||
761 		    subid == 0x834a1043 || subid == 0x83981043 ||
762 		    subid == 0x83ce1043) {
763 			/*
764 			 * The ditital mics on some Asus laptops produce
765 			 * differential signals instead of expected stereo.
766 			 * That results in silence if downmix it to mono.
767 			 * To workaround, make codec to handle signal as mono.
768 			 */
769 			val = hdaa_read_coef(dev, 0x20, 0x07);
770 			hdaa_write_coef(dev, 0x20, 0x07, val|0x80);
771 		}
772 		if (subid == 0x15171043) {
773 			/* Increase output amp on ASUS UX31A by +5dB. */
774 			hdaa_write_coef(dev, 0x20, 0x12, 0x2800);
775 		}
776 	}
777 }
778