#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_snd.h"
#endif
#include <dev/sound/pcm/sound.h>
#include <sys/ctype.h>
#include <dev/sound/pci/hda/hdac.h>
#include <dev/sound/pci/hda/hdaa.h>
#include <dev/sound/pci/hda/hda_reg.h>
#include <dev/sound/pci/hda/hdaa_patches.h>
SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdaa_patches.c 269158 2014-07-27 20:14:22Z adrian $");
static const struct {
uint32_t model;
uint32_t id;
uint32_t subsystemid;
uint32_t set, unset;
uint32_t gpio;
} hdac_quirks[] = {
{ HDA_MATCH_ALL, HDA_MATCH_ALL, HDA_MATCH_ALL,
HDAA_QUIRK_FORCESTEREO | HDAA_QUIRK_IVREF, 0,
0 },
{ ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
HDAA_QUIRK_EAPDINV, 0,
0 },
{ ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
HDAA_QUIRK_EAPDINV, 0,
0 },
{ ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
HDAA_QUIRK_OVREF, 0,
0 },
{ UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, HDA_MATCH_ALL,
HDAA_QUIRK_OVREF, 0,
0 },
{ MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(1) },
{ LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
HDAA_QUIRK_EAPDINV | HDAA_QUIRK_SENSEINV, 0,
0 },
{ SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, HDA_MATCH_ALL,
HDAA_QUIRK_EAPDINV, 0,
0 },
{ APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDA_MATCH_ALL,
HDAA_QUIRK_OVREF50, 0,
HDAA_GPIO_SET(0) },
{ APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) | HDAA_GPIO_SET(1) },
{ APPLE_MACBOOKAIR31, HDA_CODEC_CS4206, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
{ APPLE_MACBOOKPRO55, HDA_CODEC_CS4206, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
{ APPLE_MACBOOKPRO71, HDA_CODEC_CS4206, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
{ HDA_INTEL_MACBOOKPRO92, HDA_CODEC_CS4206, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(1) | HDAA_GPIO_SET(3) },
{ DELL_D630_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ DELL_V1400_SUBVENDOR, HDA_CODEC_STAC9228X, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(2) },
{ DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205X, HDA_MATCH_ALL,
0, 0,
HDAA_GPIO_SET(0) },
{ HDA_MATCH_ALL, HDA_CODEC_AD1988, HDA_MATCH_ALL,
HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
0 },
{ HDA_MATCH_ALL, HDA_CODEC_AD1988B, HDA_MATCH_ALL,
HDAA_QUIRK_IVREF80, HDAA_QUIRK_IVREF50 | HDAA_QUIRK_IVREF100,
0 },
{ HDA_MATCH_ALL, HDA_CODEC_CX20549, HDA_MATCH_ALL,
0, HDAA_QUIRK_FORCESTEREO,
0 },
{ 0x00000000, HDA_CODEC_ALC885, 0x106b0c00,
0, HDAA_QUIRK_OVREF,
0 }
};
static void
hdac_pin_patch(struct hdaa_widget *w)
{
const char *patch = NULL;
uint32_t config, orig, id, subid;
nid_t nid = w->nid;
config = orig = w->wclass.pin.config;
id = hdaa_codec_id(w->devinfo);
subid = hdaa_card_id(w->devinfo);
if (id == HDA_CODEC_ALC880 && subid == LG_LW20_SUBVENDOR) {
switch (nid) {
case 26:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
break;
case 27:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT;
break;
default:
break;
}
} else if (id == HDA_CODEC_ALC880 &&
(subid == CLEVO_D900T_SUBVENDOR ||
subid == ASUS_M5200_SUBVENDOR)) {
switch (nid) {
case 24:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
break;
case 25:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
break;
case 26:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
break;
case 27:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
break;
case 28:
config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD;
break;
}
} else if (id == HDA_CODEC_ALC883 &&
(subid == MSI_MS034A_SUBVENDOR ||
HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subid))) {
switch (nid) {
case 25:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
break;
case 28:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
break;
}
} else if (id == HDA_CODEC_CX20549 && subid ==
HP_V3000_SUBVENDOR) {
switch (nid) {
case 18:
config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
break;
case 20:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
break;
case 21:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
break;
}
} else if (id == HDA_CODEC_CX20551 && subid ==
HP_DV5000_SUBVENDOR) {
switch (nid) {
case 20:
case 21:
config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK;
config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE;
break;
}
} else if (id == HDA_CODEC_ALC861 && subid ==
ASUS_W6F_SUBVENDOR) {
switch (nid) {
case 11:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
break;
case 12:
case 14:
case 16:
case 31:
case 32:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED);
break;
case 15:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
break;
}
} else if (id == HDA_CODEC_ALC861 && subid ==
UNIWILL_9075_SUBVENDOR) {
switch (nid) {
case 15:
config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK);
config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT |
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK);
break;
}
}
if (id == HDA_CODEC_ALC283 && (subid == ACER_C720_SUBVENDOR ||
subid == ACER_C720_SUBVENDOR2)) {
switch (nid) {
case 20:
patch = "as=2 seq=0";
break;
case 25:
patch = "as=1 seq=0";
break;
case 27:
break;
case 33:
break;
}
} else
if (id == HDA_CODEC_AD1984A &&
subid == LENOVO_X300_SUBVENDOR) {
switch (nid) {
case 17:
patch = "as=1 seq=15";
break;
case 20:
patch = "as=2 seq=15";
break;
}
} else if (id == HDA_CODEC_AD1986A &&
(subid == ASUS_M2NPVMX_SUBVENDOR ||
subid == ASUS_A8NVMCSM_SUBVENDOR ||
subid == ASUS_P5PL2_SUBVENDOR)) {
switch (nid) {
case 26:
patch = "as=1 seq=15";
break;
case 28:
patch = "device=Line-in as=8 seq=1";
break;
case 29:
patch = "as=0";
break;
case 31:
patch = "as=8 seq=3";
break;
case 32:
patch = "as=8 seq=4";
break;
case 34:
patch = "as=8 seq=5";
break;
case 36:
patch = "as=8 seq=6";
break;
}
} else if (id == HDA_CODEC_ALC260 &&
HDA_DEV_MATCH(SONY_S5_SUBVENDOR, subid)) {
switch (nid) {
case 16:
patch = "seq=15 device=Headphones";
break;
}
} else if (id == HDA_CODEC_ALC268) {
if (subid == ACER_T5320_SUBVENDOR) {
switch (nid) {
case 20:
patch = "as=1 seq=15";
break;
}
}
} else if (id == HDA_CODEC_CX20561 &&
subid == LENOVO_B450_SUBVENDOR) {
switch (nid) {
case 22:
patch = "as=1 seq=15";
break;
}
} else if (id == HDA_CODEC_CX20561 &&
subid == LENOVO_T400_SUBVENDOR) {
switch (nid) {
case 22:
patch = "as=1 seq=15";
break;
case 26:
patch = "as=1 seq=0";
break;
}
} else if (id == HDA_CODEC_CX20590 &&
(subid == LENOVO_X1_SUBVENDOR ||
subid == LENOVO_X220_SUBVENDOR ||
subid == LENOVO_T420_SUBVENDOR ||
subid == LENOVO_T520_SUBVENDOR ||
subid == LENOVO_G580_SUBVENDOR)) {
switch (nid) {
case 25:
patch = "as=1 seq=15";
break;
case 27:
patch = "as=2 seq=15";
break;
case 35:
patch = "as=2";
break;
}
} else if (id == HDA_CODEC_ALC269 &&
(subid == LENOVO_X1CRBN_SUBVENDOR ||
subid == LENOVO_T430_SUBVENDOR ||
subid == LENOVO_T430S_SUBVENDOR ||
subid == LENOVO_T530_SUBVENDOR)) {
switch (nid) {
case 21:
patch = "as=1 seq=15";
break;
}
} else if (id == HDA_CODEC_ALC269 &&
subid == ASUS_UX31A_SUBVENDOR) {
switch (nid) {
case 33:
patch = "as=1 seq=15";
break;
}
} else if (id == HDA_CODEC_ALC892 &&
subid == INTEL_DH87RL_SUBVENDOR) {
switch (nid) {
case 27:
patch = "as=1 seq=15";
break;
}
}
if (patch != NULL)
config = hdaa_widget_pin_patch(config, patch);
HDA_BOOTVERBOSE(
if (config != orig)
device_printf(w->devinfo->dev,
"Patching pin config nid=%u 0x%08x -> 0x%08x\n",
nid, orig, config);
);
w->wclass.pin.config = config;
}
static void
hdaa_widget_patch(struct hdaa_widget *w)
{
struct hdaa_devinfo *devinfo = w->devinfo;
uint32_t orig;
nid_t beeper = -1;
uint32_t id, subid;
id = hdaa_codec_id(devinfo);
subid = hdaa_card_id(devinfo);
orig = w->param.widget_cap;
switch (hdaa_codec_id(devinfo)) {
case HDA_CODEC_AD1882:
case HDA_CODEC_AD1883:
case HDA_CODEC_AD1984:
case HDA_CODEC_AD1984A:
case HDA_CODEC_AD1984B:
case HDA_CODEC_AD1987:
case HDA_CODEC_AD1988:
case HDA_CODEC_AD1988B:
case HDA_CODEC_AD1989B:
beeper = 26;
break;
case HDA_CODEC_ALC260:
beeper = 23;
break;
}
if (hda_get_vendor_id(devinfo->dev) == REALTEK_VENDORID &&
hdaa_codec_id(devinfo) != HDA_CODEC_ALC260)
beeper = 29;
if (w->nid == beeper) {
w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK;
w->param.widget_cap |= HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET <<
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT;
w->waspin = 1;
}
if (hdaa_codec_id(devinfo) == HDA_CODEC_AD1984A &&
w->nid == 23)
w->param.widget_cap &= ~HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK;
HDA_BOOTVERBOSE(
if (w->param.widget_cap != orig) {
device_printf(w->devinfo->dev,
"Patching widget caps nid=%u 0x%08x -> 0x%08x\n",
w->nid, orig, w->param.widget_cap);
}
);
#if 1
if (id == HDA_CODEC_ALC283 && (subid == ACER_C720_SUBVENDOR ||
subid == ACER_C720_SUBVENDOR2)) {
if (w->nid == 33)
w->senseredir = 12;
if (w->nid == 11)
w->enable = 0;
}
#endif
if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
hdac_pin_patch(w);
}
void
hdaa_patch(struct hdaa_devinfo *devinfo)
{
struct hdaa_widget *w;
uint32_t id, subid, subsystemid;
uint32_t val;
int i;
id = hdaa_codec_id(devinfo);
subid = hdaa_card_id(devinfo);
subsystemid = hda_get_subsystem_id(devinfo->dev);
for (i = 0; i < nitems(hdac_quirks); i++) {
if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subid) &&
HDA_DEV_MATCH(hdac_quirks[i].id, id) &&
HDA_DEV_MATCH(hdac_quirks[i].subsystemid, subsystemid)))
continue;
devinfo->quirks |= hdac_quirks[i].set;
devinfo->quirks &= ~(hdac_quirks[i].unset);
devinfo->gpio = hdac_quirks[i].gpio;
}
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
w = hdaa_widget_get(devinfo, i);
if (w == NULL)
continue;
hdaa_widget_patch(w);
}
switch (id) {
case HDA_CODEC_AD1983:
w = hdaa_widget_get(devinfo, 5);
if (w != NULL)
w->connsenable[0] = 0;
w = hdaa_widget_get(devinfo, 6);
if (w != NULL)
w->connsenable[0] = 0;
w = hdaa_widget_get(devinfo, 11);
if (w != NULL)
w->connsenable[0] = 0;
w = hdaa_widget_get(devinfo, 12);
if (w != NULL)
w->connsenable[1] = 0;
w = hdaa_widget_get(devinfo, 13);
if (w != NULL)
w->connsenable[1] = 0;
w = hdaa_widget_get(devinfo, 20);
if (w != NULL)
w->connsenable[3] = 0;
break;
case HDA_CODEC_AD1986A:
w = hdaa_widget_get(devinfo, 43);
if (w != NULL)
w->enable = 0;
w = hdaa_widget_get(devinfo, 39);
if (w != NULL)
w->enable = 0;
w = hdaa_widget_get(devinfo, 40);
if (w != NULL)
w->enable = 0;
w = hdaa_widget_get(devinfo, 41);
if (w != NULL)
w->enable = 0;
w = hdaa_widget_get(devinfo, 42);
if (w != NULL)
w->enable = 0;
w = hdaa_widget_get(devinfo, 15);
if (w != NULL)
w->connsenable[3] = 0;
w = hdaa_widget_get(devinfo, 31);
if (w != NULL) {
if ((w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
w = hdaa_widget_get(devinfo, 16);
if (w != NULL)
w->connsenable[2] = 0;
} else {
w = hdaa_widget_get(devinfo, 15);
if (w != NULL)
w->connsenable[0] = 0;
}
}
w = hdaa_widget_get(devinfo, 32);
if (w != NULL) {
if ((w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) ==
HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN) {
w = hdaa_widget_get(devinfo, 16);
if (w != NULL)
w->connsenable[0] = 0;
} else {
w = hdaa_widget_get(devinfo, 15);
if (w != NULL)
w->connsenable[1] = 0;
}
}
if (subid == ASUS_A8X_SUBVENDOR) {
w = hdaa_widget_get(devinfo, 26);
if (w != NULL && w->type ==
HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX &&
(w->wclass.pin.config &
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) !=
HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE)
devinfo->quirks &=
~HDAA_QUIRK_EAPDINV;
}
break;
case HDA_CODEC_AD1981HD:
w = hdaa_widget_get(devinfo, 21);
if (w != NULL)
w->connsenable[3] = 0;
w = hdaa_widget_get(devinfo, 31);
if (w != NULL)
w->enable = 0;
w = hdaa_widget_get(devinfo, 5);
if (w != NULL)
w->connsenable[0] = 0;
w = hdaa_widget_get(devinfo, 6);
if (w != NULL)
w->connsenable[0] = 0;
w = hdaa_widget_get(devinfo, 9);
if (w != NULL)
w->connsenable[0] = 0;
w = hdaa_widget_get(devinfo, 24);
if (w != NULL)
w->connsenable[0] = 0;
break;
case HDA_CODEC_ALC256:
val = hda_read_coef_idx(devinfo->dev, 0x20, 0x46);
hda_write_coef_idx(devinfo->dev, 0x20, 0x46, val|0x3000);
break;
case HDA_CODEC_ALC269:
if (subid == 0x84371043) {
w = hdaa_widget_get(devinfo, 15);
if (w != NULL)
w->param.inamp_cap = 0;
}
break;
case HDA_CODEC_CX20582:
case HDA_CODEC_CX20583:
case HDA_CODEC_CX20584:
case HDA_CODEC_CX20585:
case HDA_CODEC_CX20590:
w = hdaa_widget_get(devinfo, 20);
if (w != NULL)
w->connsenable[1] = 0;
w = hdaa_widget_get(devinfo, 21);
if (w != NULL)
w->connsenable[1] = 0;
w = hdaa_widget_get(devinfo, 22);
if (w != NULL)
w->connsenable[0] = 0;
break;
case HDA_CODEC_VT1708S_0:
case HDA_CODEC_VT1708S_1:
case HDA_CODEC_VT1708S_2:
case HDA_CODEC_VT1708S_3:
case HDA_CODEC_VT1708S_4:
case HDA_CODEC_VT1708S_5:
case HDA_CODEC_VT1708S_6:
case HDA_CODEC_VT1708S_7:
w = hdaa_widget_get(devinfo, 26);
if (w != NULL)
w->param.inamp_cap =
(40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
(3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
(0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
w = hdaa_widget_get(devinfo, 30);
if (w != NULL)
w->param.inamp_cap =
(40 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) |
(3 << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) |
(0 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT);
break;
}
}
void
hdaa_patch_direct(struct hdaa_devinfo *devinfo)
{
device_t dev = devinfo->dev;
uint32_t id, subid, val;
id = hdaa_codec_id(devinfo);
subid = hdaa_card_id(devinfo);
switch (id) {
case HDA_CODEC_VT1708S_0:
case HDA_CODEC_VT1708S_1:
case HDA_CODEC_VT1708S_2:
case HDA_CODEC_VT1708S_3:
case HDA_CODEC_VT1708S_4:
case HDA_CODEC_VT1708S_5:
case HDA_CODEC_VT1708S_6:
case HDA_CODEC_VT1708S_7:
hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
0xf98, 0x01));
case HDA_CODEC_VT1818S:
hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
0xf88, 0xc0));
break;
}
if (subid == APPLE_INTEL_MAC)
hda_command(dev, HDA_CMD_12BIT(0, devinfo->nid,
0x7e7, 0));
if (id == HDA_CODEC_ALC269) {
if (subid == 0x16e31043 || subid == 0x831a1043 ||
subid == 0x834a1043 || subid == 0x83981043 ||
subid == 0x83ce1043) {
hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07));
val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, 0x20));
hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, 0x20, 0x07));
hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, 0x20, val|0x80));
}
}
if (id == HDA_CODEC_ALC283) {
if (subid == ACER_C720_SUBVENDOR ||
subid == ACER_C720_SUBVENDOR2)
hdaa_patch_direct_acer_c720(devinfo);
}
}
uint32_t
hda_read_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx)
{
uint32_t val;
hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx));
val = hda_command(dev, HDA_CMD_GET_PROCESSING_COEFF(0, nid));
return val;
}
void
hda_write_coef_idx(device_t dev, nid_t nid, unsigned int coef_idx,
unsigned coef_val)
{
hda_command(dev, HDA_CMD_SET_COEFF_INDEX(0, nid, coef_idx));
hda_command(dev, HDA_CMD_SET_PROCESSING_COEFF(0, nid, coef_val));
}