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