2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
32 * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
35 #ifdef HAVE_KERNEL_OPTION_HEADERS
39 #include <dev/sound/pcm/sound.h>
41 #include <sys/ctype.h>
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>
47 SND_DECLARE_FILE("$FreeBSD$");
57 * XXX Force stereo quirk. Monoural recording / playback
58 * on few codecs (especially ALC880) seems broken or
59 * perhaps unsupported.
61 { HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL,
62 HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0,
64 { ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL,
67 { ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL,
70 { ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
73 { ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
76 { ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
79 { ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
82 { ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
83 HDAA_QUIRK_EAPDINV, 0,
85 { ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
86 HDAA_QUIRK_EAPDINV, 0,
88 { ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
91 { UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
94 /*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, HDA_MATCH_ALL,
95 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
97 { MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
100 { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
101 HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0,
103 { SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
104 HDAA_QUIRK_EAPDINV, 0,
106 { APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL,
107 HDAA_QUIRK_OVREF50, 0,
109 { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL,
111 HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) },
112 { APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL,
114 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
115 { APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL,
117 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
118 { APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL,
120 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
121 { HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL,
123 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
124 { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
127 { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL,
130 { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
133 { HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL,
134 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
136 { HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL,
137 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
139 { HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL,
140 0, HDAA_QUIRK_FORCESTEREO,
142 /* Mac Pro 1,1 requires ovref for proper volume level. */
143 { 0x00000000, HDA_CODEC_ALC885, 0x106b0c00,
149 hdac_pin_patch(struct hdaa_widget *w)
151 const char *patch = NULL;
152 uint32_t config, orig, id, subid;
155 config = orig = w->wclass.pin.config;
156 id = hdaa_codec_id(w->devinfo);
157 subid = hdaa_card_id(w->devinfo);
159 /* XXX: Old patches require complete review.
160 * Now they may create more problem then solve due to
161 * incorrect associations.
163 if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) {
166 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
167 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
170 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
171 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
176 } else if (id == HDA_CODEC_ALC880 &&
177 (subid == CLEVO_D900T_SUBVENDOR ||
178 subid == ASUS_M5200_SUBVENDOR)) {
184 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
185 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
187 case 25: /* XXX MIC2 */
188 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
189 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
192 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
193 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
195 case 27: /* XXX LINE2 */
196 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
197 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
200 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
201 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
204 } else if (id == HDA_CODEC_ALC883 &&
205 (subid == MSI_MS034A_SUBVENDOR ||
206 HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) {
209 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
210 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
211 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
212 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
215 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
216 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
217 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
218 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
221 } else if (id == HDA_CODEC_CX20549 && subid ==
222 HP_V3000_SUBVENDOR) {
225 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
226 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
229 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
230 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
231 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
232 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
235 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
236 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
237 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
238 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
241 } else if (id == HDA_CODEC_CX20551 && subid ==
242 HP_DV5000_SUBVENDOR) {
246 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
247 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
250 } else if (id == HDA_CODEC_ALC861 && subid ==
251 ASUS_W6F_SUBVENDOR) {
254 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
255 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
256 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
257 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
264 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
265 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
266 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
267 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
270 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
271 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
272 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
273 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
276 } else if (id == HDA_CODEC_ALC861 && subid ==
277 UNIWILL_9075_SUBVENDOR) {
280 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
281 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
282 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
283 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
289 if (id == HDA_CODEC_AD1984A &&
290 subid == LENOVO_X300_SUBVENDOR) {
292 case 17: /* Headphones with redirection */
293 patch = "as=1 seq=15";
295 case 20: /* Two mics together */
296 patch = "as=2 seq=15";
299 } else if (id == HDA_CODEC_AD1986A &&
300 (subid == ASUS_M2NPVMX_SUBVENDOR ||
301 subid == ASUS_A8NVMCSM_SUBVENDOR ||
302 subid == ASUS_P5PL2_SUBVENDOR)) {
304 case 26: /* Headphones with redirection */
305 patch = "as=1 seq=15";
307 case 28: /* 5.1 out => 2.0 out + 1 input */
308 patch = "device=Line-in as=8 seq=1";
310 case 29: /* Can't use this as input, as the only available mic
311 * preamplifier is busy by front panel mic (nid 31).
312 * If you want to use this rear connector as mic input,
313 * you have to disable the front panel one. */
316 case 31: /* Lot of inputs configured with as=15 and unusable */
317 patch = "as=8 seq=3";
320 patch = "as=8 seq=4";
323 patch = "as=8 seq=5";
326 patch = "as=8 seq=6";
329 } else if (id == HDA_CODEC_ALC260 &&
330 HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) {
333 patch = "seq=15 device=Headphones";
336 } else if (id == HDA_CODEC_ALC268) {
337 if (subid == ACER_T5320_SUBVENDOR) {
339 case 20: /* Headphones Jack */
340 patch = "as=1 seq=15";
344 } else if (id == HDA_CODEC_CX20561 &&
345 subid == LENOVO_B450_SUBVENDOR) {
348 patch = "as=1 seq=15";
351 } else if (id == HDA_CODEC_CX20561 &&
352 subid == LENOVO_T400_SUBVENDOR) {
355 patch = "as=1 seq=15";
358 patch = "as=1 seq=0";
361 } else if (id == HDA_CODEC_CX20590 &&
362 (subid == LENOVO_X1_SUBVENDOR ||
363 subid == LENOVO_X220_SUBVENDOR ||
364 subid == LENOVO_T420_SUBVENDOR ||
365 subid == LENOVO_T520_SUBVENDOR ||
366 subid == LENOVO_G580_SUBVENDOR)) {
369 patch = "as=1 seq=15";
372 * Group onboard mic and headphone mic
373 * together. Fixes onboard mic.
376 patch = "as=2 seq=15";
382 } else if (id == HDA_CODEC_ALC269 &&
383 (subid == LENOVO_X1CRBN_SUBVENDOR ||
384 subid == LENOVO_T430_SUBVENDOR ||
385 subid == LENOVO_T430S_SUBVENDOR ||
386 subid == LENOVO_T530_SUBVENDOR)) {
389 patch = "as=1 seq=15";
392 } else if (id == HDA_CODEC_ALC269 &&
393 subid == ASUS_UX31A_SUBVENDOR) {
396 patch = "as=1 seq=15";
399 } else if (id == HDA_CODEC_ALC892 &&
400 subid == INTEL_DH87RL_SUBVENDOR) {
403 patch = "as=1 seq=15";
406 } else if (id == HDA_CODEC_ALC292 &&
407 subid == LENOVO_X120BS_SUBVENDOR) {
410 patch = "as=1 seq=15";
413 } else if (id == HDA_CODEC_ALC295 && subid == HP_AF006UR_SUBVENDOR) {
419 patch = "as=2 seq=15";
422 patch = "as=1 seq=15";
425 } else if (id == HDA_CODEC_ALC298 && subid == DELL_XPS9560_SUBVENDOR) {
437 config = hdaa_widget_pin_patch(config, patch);
440 device_printf(w->devinfo->dev,
441 "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
444 w->wclass.pin.config = config;
448 hdaa_widget_patch(struct hdaa_widget *w)
450 struct hdaa_devinfo *devinfo = w->devinfo;
454 orig = w->param.widget_cap;
455 /* On some codecs beeper is an input pin, but it is not recordable
456 alone. Also most of BIOSes does not declare beeper pin.
457 Change beeper pin node type to beeper to help parser. */
458 switch (hdaa_codec_id(devinfo)) {
459 case HDA_CODEC_AD1882:
460 case HDA_CODEC_AD1883:
461 case HDA_CODEC_AD1984:
462 case HDA_CODEC_AD1984A:
463 case HDA_CODEC_AD1984B:
464 case HDA_CODEC_AD1987:
465 case HDA_CODEC_AD1988:
466 case HDA_CODEC_AD1988B:
467 case HDA_CODEC_AD1989B:
470 case HDA_CODEC_ALC260:
474 if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
475 hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
477 if (w->nid == beeper) {
478 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
479 w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
480 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
484 * Clear "digital" flag from digital mic input, as its signal then goes
485 * to "analog" mixer and this separation just limits functionaity.
487 if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A &&
489 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK;
491 if (w->param.widget_cap != orig) {
492 device_printf(w->devinfo->dev,
493 "Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
494 w->nid, orig, w->param.widget_cap);
498 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
503 hdaa_patch(struct hdaa_devinfo *devinfo)
505 struct hdaa_widget *w;
506 uint32_t id, subid, subsystemid;
509 id = hdaa_codec_id(devinfo);
510 subid = hdaa_card_id(devinfo);
511 subsystemid = hda_get_subsystem_id(devinfo->dev);
516 for (i = 0; i < nitems(hdac_quirks); i++) {
517 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
518 HDA_DEV_MATCH(hdac_quirks[i].id, id) &&
519 HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid)))
521 devinfo->quirks |= hdac_quirks[i].set;
522 devinfo->quirks &= ~(hdac_quirks[i].unset);
523 devinfo->gpio = hdac_quirks[i].gpio;
526 /* Apply per-widget patch. */
527 for (i = devinfo->startnode; i < devinfo->endnode; i++) {
528 w = hdaa_widget_get(devinfo, i);
531 hdaa_widget_patch(w);
535 case HDA_CODEC_AD1983:
537 * This CODEC has several possible usages, but none
538 * fit the parser best. Help parser to choose better.
540 /* Disable direct unmixed playback to get pcm volume. */
541 w = hdaa_widget_get(devinfo, 5);
543 w->connsenable[0] = 0;
544 w = hdaa_widget_get(devinfo, 6);
546 w->connsenable[0] = 0;
547 w = hdaa_widget_get(devinfo, 11);
549 w->connsenable[0] = 0;
550 /* Disable mic and line selectors. */
551 w = hdaa_widget_get(devinfo, 12);
553 w->connsenable[1] = 0;
554 w = hdaa_widget_get(devinfo, 13);
556 w->connsenable[1] = 0;
557 /* Disable recording from mono playback mix. */
558 w = hdaa_widget_get(devinfo, 20);
560 w->connsenable[3] = 0;
562 case HDA_CODEC_AD1986A:
564 * This CODEC has overcomplicated input mixing.
565 * Make some cleaning there.
567 /* Disable input mono mixer. Not needed and not supported. */
568 w = hdaa_widget_get(devinfo, 43);
571 /* Disable any with any input mixing mesh. Use separately. */
572 w = hdaa_widget_get(devinfo, 39);
575 w = hdaa_widget_get(devinfo, 40);
578 w = hdaa_widget_get(devinfo, 41);
581 w = hdaa_widget_get(devinfo, 42);
584 /* Disable duplicate mixer node connector. */
585 w = hdaa_widget_get(devinfo, 15);
587 w->connsenable[3] = 0;
588 /* There is only one mic preamplifier, use it effectively. */
589 w = hdaa_widget_get(devinfo, 31);
591 if ((w->wclass.pin.config &
592 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
593 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
594 w = hdaa_widget_get(devinfo, 16);
596 w->connsenable[2] = 0;
598 w = hdaa_widget_get(devinfo, 15);
600 w->connsenable[0] = 0;
603 w = hdaa_widget_get(devinfo, 32);
605 if ((w->wclass.pin.config &
606 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
607 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
608 w = hdaa_widget_get(devinfo, 16);
610 w->connsenable[0] = 0;
612 w = hdaa_widget_get(devinfo, 15);
614 w->connsenable[1] = 0;
618 if (subid == ASUS_A8X_SUBVENDOR) {
620 * This is just plain ridiculous.. There
621 * are several A8 series that share the same
622 * pci id but works differently (EAPD).
624 w = hdaa_widget_get(devinfo, 26);
625 if (w != NULL && w->type ==
626 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
627 (w->wclass.pin.config &
628 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
629 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
634 case HDA_CODEC_AD1981HD:
636 * This CODEC has very unusual design with several
637 * points inappropriate for the present parser.
639 /* Disable recording from mono playback mix. */
640 w = hdaa_widget_get(devinfo, 21);
642 w->connsenable[3] = 0;
643 /* Disable rear to front mic mixer, use separately. */
644 w = hdaa_widget_get(devinfo, 31);
647 /* Disable direct playback, use mixer. */
648 w = hdaa_widget_get(devinfo, 5);
650 w->connsenable[0] = 0;
651 w = hdaa_widget_get(devinfo, 6);
653 w->connsenable[0] = 0;
654 w = hdaa_widget_get(devinfo, 9);
656 w->connsenable[0] = 0;
657 w = hdaa_widget_get(devinfo, 24);
659 w->connsenable[0] = 0;
661 case HDA_CODEC_ALC269:
663 * ASUS EeePC 1001px has strange variant of ALC269 CODEC,
664 * that mutes speaker if unused mixer at NID 15 is muted.
665 * Probably CODEC incorrectly reports internal connections.
666 * Hide that muter from the driver. There are several CODECs
667 * sharing this ID and I have not enough information about
668 * them to implement more universal solution.
670 if (subid == 0x84371043) {
671 w = hdaa_widget_get(devinfo, 15);
673 w->param.inamp_cap = 0;
676 case HDA_CODEC_CX20582:
677 case HDA_CODEC_CX20583:
678 case HDA_CODEC_CX20584:
679 case HDA_CODEC_CX20585:
680 case HDA_CODEC_CX20590:
682 * These codecs have extra connectivity on record side
683 * too reach for the present parser.
685 w = hdaa_widget_get(devinfo, 20);
687 w->connsenable[1] = 0;
688 w = hdaa_widget_get(devinfo, 21);
690 w->connsenable[1] = 0;
691 w = hdaa_widget_get(devinfo, 22);
693 w->connsenable[0] = 0;
695 case HDA_CODEC_VT1708S_0:
696 case HDA_CODEC_VT1708S_1:
697 case HDA_CODEC_VT1708S_2:
698 case HDA_CODEC_VT1708S_3:
699 case HDA_CODEC_VT1708S_4:
700 case HDA_CODEC_VT1708S_5:
701 case HDA_CODEC_VT1708S_6:
702 case HDA_CODEC_VT1708S_7:
704 * These codecs have hidden mic boost controls.
706 w = hdaa_widget_get(devinfo, 26);
709 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
710 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
711 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
712 w = hdaa_widget_get(devinfo, 30);
715 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
716 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
717 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
723 hdaa_read_coef(device_t dev, nid_t nid, uint16_t idx)
726 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
727 return (hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid)));
731 hdaa_write_coef(device_t dev, nid_t nid, uint16_t idx, uint16_t val)
734 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, idx));
735 return (hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, val)));
739 hdaa_patch_direct(struct hdaa_devinfo *devinfo)
741 device_t dev = devinfo->dev;
742 uint32_t id, subid, val;
744 id = hdaa_codec_id(devinfo);
745 subid = hdaa_card_id(devinfo);
748 case HDA_CODEC_VT1708S_0:
749 case HDA_CODEC_VT1708S_1:
750 case HDA_CODEC_VT1708S_2:
751 case HDA_CODEC_VT1708S_3:
752 case HDA_CODEC_VT1708S_4:
753 case HDA_CODEC_VT1708S_5:
754 case HDA_CODEC_VT1708S_6:
755 case HDA_CODEC_VT1708S_7:
756 /* Enable Mic Boost Volume controls. */
757 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
760 case HDA_CODEC_VT1818S:
761 /* Don't bypass mixer. */
762 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
765 case HDA_CODEC_ALC1150:
766 if (subid == 0xd9781462) {
767 /* Too low volume on MSI H170 GAMING M3. */
768 hdaa_write_coef(dev, 0x20, 0x07, 0x7cb);
772 if (subid == APPLE_INTEL_MAC)
773 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
775 if (id == HDA_CODEC_ALC269) {
776 if (subid == 0x16e31043 || subid == 0x831a1043 ||
777 subid == 0x834a1043 || subid == 0x83981043 ||
778 subid == 0x83ce1043) {
780 * The ditital mics on some Asus laptops produce
781 * differential signals instead of expected stereo.
782 * That results in silence if downmix it to mono.
783 * To workaround, make codec to handle signal as mono.
785 val = hdaa_read_coef(dev, 0x20, 0x07);
786 hdaa_write_coef(dev, 0x20, 0x07, val|0x80);
788 if (subid == 0x15171043) {
789 /* Increase output amp on ASUS UX31A by +5dB. */
790 hdaa_write_coef(dev, 0x20, 0x12, 0x2800);