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>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
30 * Intel High Definition Audio (Audio function quirks) driver for FreeBSD.
33 #ifdef HAVE_KERNEL_OPTION_HEADERS
37 #include <dev/sound/pcm/sound.h>
39 #include <sys/ctype.h>
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>
46 SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdaa_patches.c 269158 2014-07-27 20:14:22Z adrian $");
56 * XXX Force stereo quirk. Monoural recording / playback
57 * on few codecs (especially ALC880) seems broken or
58 * perhaps unsupported.
60 { HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL,
61 HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0,
63 { ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL,
66 { ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL,
69 { ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
72 { ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
75 { ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
78 { ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
81 { ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
82 HDAA_QUIRK_EAPDINV, 0,
84 { ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
85 HDAA_QUIRK_EAPDINV, 0,
87 { ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
90 { UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
93 /*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, HDA_MATCH_ALL,
94 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
96 { MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
99 { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
100 HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0,
102 { SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
103 HDAA_QUIRK_EAPDINV, 0,
105 { APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL,
106 HDAA_QUIRK_OVREF50, 0,
108 { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL,
110 HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) },
111 { APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL,
113 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
114 { APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL,
116 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
117 { APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL,
119 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
120 { HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL,
122 HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
123 { DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
126 { DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL,
129 { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
132 { HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL,
133 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
135 { HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL,
136 HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
138 { HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL,
139 0, HDAA_QUIRK_FORCESTEREO,
141 /* Mac Pro 1,1 requires ovref for proper volume level. */
142 { 0x00000000, HDA_CODEC_ALC885, 0x106b0c00,
148 hdac_pin_patch(struct hdaa_widget *w)
150 const char *patch = NULL;
151 uint32_t config, orig, id, subid;
154 config = orig = w->wclass.pin.config;
155 id = hdaa_codec_id(w->devinfo);
156 subid = hdaa_card_id(w->devinfo);
158 /* XXX: Old patches require complete review.
159 * Now they may create more problem then solve due to
160 * incorrect associations.
162 if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) {
165 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
166 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
169 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
170 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
175 } else if (id == HDA_CODEC_ALC880 &&
176 (subid == CLEVO_D900T_SUBVENDOR ||
177 subid == ASUS_M5200_SUBVENDOR)) {
183 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
184 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
186 case 25: /* XXX MIC2 */
187 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
188 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
191 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
192 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
194 case 27: /* XXX LINE2 */
195 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
196 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
199 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
200 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
203 } else if (id == HDA_CODEC_ALC883 &&
204 (subid == MSI_MS034A_SUBVENDOR ||
205 HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) {
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);
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);
220 } else if (id == HDA_CODEC_CX20549 && subid ==
221 HP_V3000_SUBVENDOR) {
224 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
225 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
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);
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);
240 } else if (id == HDA_CODEC_CX20551 && subid ==
241 HP_DV5000_SUBVENDOR) {
245 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
246 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
249 } else if (id == HDA_CODEC_ALC861 && subid ==
250 ASUS_W6F_SUBVENDOR) {
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);
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);
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);
275 } else if (id == HDA_CODEC_ALC861 && subid ==
276 UNIWILL_9075_SUBVENDOR) {
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);
288 if (id == HDA_CODEC_ALC283 && (subid == ACER_C720_SUBVENDOR ||
289 subid == ACER_C720_SUBVENDOR2)) {
292 patch = "as=2 seq=0";
295 patch = "as=1 seq=0";
299 patch = "device=Headphones conn=Fixed as=2 seq=15";
307 if (id == HDA_CODEC_AD1984A &&
308 subid == LENOVO_X300_SUBVENDOR) {
310 case 17: /* Headphones with redirection */
311 patch = "as=1 seq=15";
313 case 20: /* Two mics together */
314 patch = "as=2 seq=15";
317 } else if (id == HDA_CODEC_AD1986A &&
318 (subid == ASUS_M2NPVMX_SUBVENDOR ||
319 subid == ASUS_A8NVMCSM_SUBVENDOR ||
320 subid == ASUS_P5PL2_SUBVENDOR)) {
322 case 26: /* Headphones with redirection */
323 patch = "as=1 seq=15";
325 case 28: /* 5.1 out => 2.0 out + 1 input */
326 patch = "device=Line-in as=8 seq=1";
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. */
334 case 31: /* Lot of inputs configured with as=15 and unusable */
335 patch = "as=8 seq=3";
338 patch = "as=8 seq=4";
341 patch = "as=8 seq=5";
344 patch = "as=8 seq=6";
347 } else if (id == HDA_CODEC_ALC260 &&
348 HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) {
351 patch = "seq=15 device=Headphones";
354 } else if (id == HDA_CODEC_ALC268) {
355 if (subid == ACER_T5320_SUBVENDOR) {
357 case 20: /* Headphones Jack */
358 patch = "as=1 seq=15";
362 } else if (id == HDA_CODEC_CX20561 &&
363 subid == LENOVO_B450_SUBVENDOR) {
366 patch = "as=1 seq=15";
369 } else if (id == HDA_CODEC_CX20561 &&
370 subid == LENOVO_T400_SUBVENDOR) {
373 patch = "as=1 seq=15";
376 patch = "as=1 seq=0";
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)) {
387 patch = "as=1 seq=15";
390 * Group onboard mic and headphone mic
391 * together. Fixes onboard mic.
394 patch = "as=2 seq=15";
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)) {
407 patch = "as=1 seq=15";
410 } else if (id == HDA_CODEC_ALC269 &&
411 subid == ASUS_UX31A_SUBVENDOR) {
414 patch = "as=1 seq=15";
417 } else if (id == HDA_CODEC_ALC892 &&
418 subid == INTEL_DH87RL_SUBVENDOR) {
421 patch = "as=1 seq=15";
427 config = hdaa_widget_pin_patch(config, patch);
430 device_printf(w->devinfo->dev,
431 "Patching pin config nid=%u 0x%08x -> 0x%08x\n",
434 w->wclass.pin.config = config;
438 hdaa_widget_patch(struct hdaa_widget *w)
440 struct hdaa_devinfo *devinfo = w->devinfo;
445 id = hdaa_codec_id(devinfo);
446 subid = hdaa_card_id(devinfo);
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:
464 case HDA_CODEC_ALC260:
468 if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
469 hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
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;
478 * Clear "digital" flag from digital mic input, as its signal then goes
479 * to "analog" mixer and this separation just limits functionaity.
481 if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A &&
483 w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK;
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);
494 * Redirect the headphone plug sense (NID 33 -> redir to 12).
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.
501 if (id == HDA_CODEC_ALC283 && (subid == ACER_C720_SUBVENDOR ||
502 subid == ACER_C720_SUBVENDOR2)) {
510 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
515 hdaa_patch(struct hdaa_devinfo *devinfo)
517 struct hdaa_widget *w;
518 uint32_t id, subid, subsystemid;
522 id = hdaa_codec_id(devinfo);
523 subid = hdaa_card_id(devinfo);
524 subsystemid = hda_get_subsystem_id(devinfo->dev);
529 for (i = 0; i < nitems(hdac_quirks); i++) {
530 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
531 HDA_DEV_MATCH(hdac_quirks[i].id, id) &&
532 HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid)))
534 devinfo->quirks |= hdac_quirks[i].set;
535 devinfo->quirks &= ~(hdac_quirks[i].unset);
536 devinfo->gpio = hdac_quirks[i].gpio;
539 /* Apply per-widget patch. */
540 for (i = devinfo->startnode; i < devinfo->endnode; i++) {
541 w = hdaa_widget_get(devinfo, i);
544 hdaa_widget_patch(w);
548 case HDA_CODEC_AD1983:
550 * This CODEC has several possible usages, but none
551 * fit the parser best. Help parser to choose better.
553 /* Disable direct unmixed playback to get pcm volume. */
554 w = hdaa_widget_get(devinfo, 5);
556 w->connsenable[0] = 0;
557 w = hdaa_widget_get(devinfo, 6);
559 w->connsenable[0] = 0;
560 w = hdaa_widget_get(devinfo, 11);
562 w->connsenable[0] = 0;
563 /* Disable mic and line selectors. */
564 w = hdaa_widget_get(devinfo, 12);
566 w->connsenable[1] = 0;
567 w = hdaa_widget_get(devinfo, 13);
569 w->connsenable[1] = 0;
570 /* Disable recording from mono playback mix. */
571 w = hdaa_widget_get(devinfo, 20);
573 w->connsenable[3] = 0;
575 case HDA_CODEC_AD1986A:
577 * This CODEC has overcomplicated input mixing.
578 * Make some cleaning there.
580 /* Disable input mono mixer. Not needed and not supported. */
581 w = hdaa_widget_get(devinfo, 43);
584 /* Disable any with any input mixing mesh. Use separately. */
585 w = hdaa_widget_get(devinfo, 39);
588 w = hdaa_widget_get(devinfo, 40);
591 w = hdaa_widget_get(devinfo, 41);
594 w = hdaa_widget_get(devinfo, 42);
597 /* Disable duplicate mixer node connector. */
598 w = hdaa_widget_get(devinfo, 15);
600 w->connsenable[3] = 0;
601 /* There is only one mic preamplifier, use it effectively. */
602 w = hdaa_widget_get(devinfo, 31);
604 if ((w->wclass.pin.config &
605 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
606 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
607 w = hdaa_widget_get(devinfo, 16);
609 w->connsenable[2] = 0;
611 w = hdaa_widget_get(devinfo, 15);
613 w->connsenable[0] = 0;
616 w = hdaa_widget_get(devinfo, 32);
618 if ((w->wclass.pin.config &
619 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
620 HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
621 w = hdaa_widget_get(devinfo, 16);
623 w->connsenable[0] = 0;
625 w = hdaa_widget_get(devinfo, 15);
627 w->connsenable[1] = 0;
631 if (subid == ASUS_A8X_SUBVENDOR) {
633 * This is just plain ridiculous.. There
634 * are several A8 series that share the same
635 * pci id but works differently (EAPD).
637 w = hdaa_widget_get(devinfo, 26);
638 if (w != NULL && w->type ==
639 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
640 (w->wclass.pin.config &
641 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
642 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
647 case HDA_CODEC_AD1981HD:
649 * This CODEC has very unusual design with several
650 * points inappropriate for the present parser.
652 /* Disable recording from mono playback mix. */
653 w = hdaa_widget_get(devinfo, 21);
655 w->connsenable[3] = 0;
656 /* Disable rear to front mic mixer, use separately. */
657 w = hdaa_widget_get(devinfo, 31);
660 /* Disable direct playback, use mixer. */
661 w = hdaa_widget_get(devinfo, 5);
663 w->connsenable[0] = 0;
664 w = hdaa_widget_get(devinfo, 6);
666 w->connsenable[0] = 0;
667 w = hdaa_widget_get(devinfo, 9);
669 w->connsenable[0] = 0;
670 w = hdaa_widget_get(devinfo, 24);
672 w->connsenable[0] = 0;
674 case HDA_CODEC_ALC256:
675 val = hda_read_coef_idx(devinfo->dev, 0x20, 0x46);
676 hda_write_coef_idx(devinfo->dev, 0x20, 0x46, val|0x3000);
678 case HDA_CODEC_ALC269:
680 * ASUS EeePC 1001px has strange variant of ALC269 CODEC,
681 * that mutes speaker if unused mixer at NID 15 is muted.
682 * Probably CODEC incorrectly reports internal connections.
683 * Hide that muter from the driver. There are several CODECs
684 * sharing this ID and I have not enough information about
685 * them to implement more universal solution.
687 if (subid == 0x84371043) {
688 w = hdaa_widget_get(devinfo, 15);
690 w->param.inamp_cap = 0;
693 case HDA_CODEC_CX20582:
694 case HDA_CODEC_CX20583:
695 case HDA_CODEC_CX20584:
696 case HDA_CODEC_CX20585:
697 case HDA_CODEC_CX20590:
699 * These codecs have extra connectivity on record side
700 * too reach for the present parser.
702 w = hdaa_widget_get(devinfo, 20);
704 w->connsenable[1] = 0;
705 w = hdaa_widget_get(devinfo, 21);
707 w->connsenable[1] = 0;
708 w = hdaa_widget_get(devinfo, 22);
710 w->connsenable[0] = 0;
712 case HDA_CODEC_VT1708S_0:
713 case HDA_CODEC_VT1708S_1:
714 case HDA_CODEC_VT1708S_2:
715 case HDA_CODEC_VT1708S_3:
716 case HDA_CODEC_VT1708S_4:
717 case HDA_CODEC_VT1708S_5:
718 case HDA_CODEC_VT1708S_6:
719 case HDA_CODEC_VT1708S_7:
721 * These codecs have hidden mic boost controls.
723 w = hdaa_widget_get(devinfo, 26);
726 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
727 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
728 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
729 w = hdaa_widget_get(devinfo, 30);
732 (40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
733 (3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
734 (0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
740 hdaa_patch_direct(struct hdaa_devinfo *devinfo)
742 device_t dev = devinfo->dev;
743 uint32_t id, subid, val;
745 id = hdaa_codec_id(devinfo);
746 subid = hdaa_card_id(devinfo);
749 case HDA_CODEC_VT1708S_0:
750 case HDA_CODEC_VT1708S_1:
751 case HDA_CODEC_VT1708S_2:
752 case HDA_CODEC_VT1708S_3:
753 case HDA_CODEC_VT1708S_4:
754 case HDA_CODEC_VT1708S_5:
755 case HDA_CODEC_VT1708S_6:
756 case HDA_CODEC_VT1708S_7:
757 /* Enable Mic Boost Volume controls. */
758 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
761 case HDA_CODEC_VT1818S:
762 /* Don't bypass mixer. */
763 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
767 if (subid == APPLE_INTEL_MAC)
768 hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
770 if (id == HDA_CODEC_ALC269) {
771 if (subid == 0x16e31043 || subid == 0x831a1043 ||
772 subid == 0x834a1043 || subid == 0x83981043 ||
773 subid == 0x83ce1043) {
775 * The ditital mics on some Asus laptops produce
776 * differential signals instead of expected stereo.
777 * That results in silence if downmix it to mono.
778 * To workaround, make codec to handle signal as mono.
780 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07));
781 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20));
782 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07));
783 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80));
786 if (id == HDA_CODEC_ALC283) {
787 if (subid == ACER_C720_SUBVENDOR ||
788 subid == ACER_C720_SUBVENDOR2)
789 hdaa_patch_direct_acer_c720(devinfo);
793 /* XXX move me to a better place */
795 hda_read_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx)
799 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx));
800 val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid));
805 hda_write_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx,
808 hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx));
809 hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, coef_val));