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