Fix support for IBM/Lenovo Thinkcentre M52 series. Its vendorid / 0x1014
accidentally match with HP vendorid / 0x103c. Reported by: Robert Noland <rnoland@2hip.net>
This commit is contained in:
parent
413d6375d7
commit
0b414ccace
@ -113,6 +113,12 @@ SND_DECLARE_FILE("$FreeBSD$");
|
||||
#define hdac_lockowned(sc) mtx_owned((sc)->lock)
|
||||
|
||||
#define HDA_FLAG_MATCH(fl, v) (((fl) & (v)) == (v))
|
||||
#define HDA_DEV_MATCH(fl, v) ((fl) == (v) || \
|
||||
(fl) == 0xffffffff || \
|
||||
(((fl) & 0xffff0000) == 0xffff0000 && \
|
||||
((fl) & 0x0000ffff) == ((v) & 0x0000ffff)) || \
|
||||
(((fl) & 0x0000ffff) == 0x0000ffff && \
|
||||
((fl) & 0xffff0000) == ((v) & 0xffff0000)))
|
||||
#define HDA_MATCH_ALL 0xffffffff
|
||||
#define HDAC_INVALID 0xffffffff
|
||||
|
||||
@ -184,6 +190,11 @@ SND_DECLARE_FILE("$FreeBSD$");
|
||||
#define ASUS_M5200_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1993)
|
||||
#define ASUS_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0xffff)
|
||||
|
||||
/* IBM / Lenovo */
|
||||
#define IBM_VENDORID 0x1014
|
||||
#define IBM_M52_SUBVENDOR HDA_MODEL_CONSTRUCT(IBM, 0x02f6)
|
||||
#define IBM_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(IBM, 0xffff)
|
||||
|
||||
|
||||
/* Misc constants.. */
|
||||
#define HDA_AMP_MUTE_DEFAULT (0xffffffff)
|
||||
@ -514,7 +525,7 @@ hdac_codec_name(struct hdac_devinfo *devinfo)
|
||||
id = hdac_codec_id(devinfo);
|
||||
|
||||
for (i = 0; i < HDAC_CODECS_LEN; i++) {
|
||||
if (HDA_FLAG_MATCH(hdac_codecs[i].id, id))
|
||||
if (HDA_DEV_MATCH(hdac_codecs[i].id, id))
|
||||
return (hdac_codecs[i].name);
|
||||
}
|
||||
|
||||
@ -617,7 +628,7 @@ hdac_hp_switch_handler(struct hdac_devinfo *devinfo)
|
||||
cad = devinfo->codec->cad;
|
||||
id = hdac_codec_id(devinfo);
|
||||
for (i = 0; i < HDAC_HP_SWITCH_LEN; i++) {
|
||||
if (HDA_FLAG_MATCH(hdac_hp_switch[i].model,
|
||||
if (HDA_DEV_MATCH(hdac_hp_switch[i].model,
|
||||
sc->pci_subvendor) &&
|
||||
hdac_hp_switch[i].id == id)
|
||||
break;
|
||||
@ -2231,7 +2242,8 @@ static int
|
||||
hdac_probe(device_t dev)
|
||||
{
|
||||
int i, result;
|
||||
uint32_t model, class, subclass;
|
||||
uint32_t model;
|
||||
uint16_t class, subclass;
|
||||
char desc[64];
|
||||
|
||||
model = (uint32_t)pci_get_device(dev) << 16;
|
||||
@ -2247,7 +2259,7 @@ hdac_probe(device_t dev)
|
||||
result = BUS_PROBE_DEFAULT;
|
||||
break;
|
||||
}
|
||||
if (HDA_FLAG_MATCH(hdac_devices[i].model, model) &&
|
||||
if (HDA_DEV_MATCH(hdac_devices[i].model, model) &&
|
||||
class == PCIC_MULTIMEDIA &&
|
||||
subclass == PCIS_MULTIMEDIA_HDA) {
|
||||
strlcpy(desc, hdac_devices[i].desc, sizeof(desc));
|
||||
@ -2525,7 +2537,7 @@ hdac_audio_ctl_ossmixer_init(struct snd_mixer *m)
|
||||
id = hdac_codec_id(devinfo);
|
||||
cad = devinfo->codec->cad;
|
||||
for (i = 0; i < HDAC_HP_SWITCH_LEN; i++) {
|
||||
if (!(HDA_FLAG_MATCH(hdac_hp_switch[i].model,
|
||||
if (!(HDA_DEV_MATCH(hdac_hp_switch[i].model,
|
||||
sc->pci_subvendor) &&
|
||||
hdac_hp_switch[i].id == id))
|
||||
continue;
|
||||
@ -2554,7 +2566,7 @@ hdac_audio_ctl_ossmixer_init(struct snd_mixer *m)
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < HDAC_EAPD_SWITCH_LEN; i++) {
|
||||
if (!(HDA_FLAG_MATCH(hdac_eapd_switch[i].model,
|
||||
if (!(HDA_DEV_MATCH(hdac_eapd_switch[i].model,
|
||||
sc->pci_subvendor) &&
|
||||
hdac_eapd_switch[i].id == id))
|
||||
continue;
|
||||
@ -2673,13 +2685,14 @@ hdac_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev,
|
||||
|
||||
hdac_lock(sc);
|
||||
if (dev == SOUND_MIXER_OGAIN) {
|
||||
uint32_t orig;
|
||||
/*if (left != right || !(left == 0 || left == 1)) {
|
||||
hdac_unlock(sc);
|
||||
return (-1);
|
||||
}*/
|
||||
id = hdac_codec_id(devinfo);
|
||||
for (i = 0; i < HDAC_EAPD_SWITCH_LEN; i++) {
|
||||
if (HDA_FLAG_MATCH(hdac_eapd_switch[i].model,
|
||||
if (HDA_DEV_MATCH(hdac_eapd_switch[i].model,
|
||||
sc->pci_subvendor) &&
|
||||
hdac_eapd_switch[i].id == id)
|
||||
break;
|
||||
@ -2695,15 +2708,18 @@ hdac_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev,
|
||||
hdac_unlock(sc);
|
||||
return (-1);
|
||||
}
|
||||
orig = w->param.eapdbtl;
|
||||
if (left == 0)
|
||||
w->param.eapdbtl &= ~HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
|
||||
else
|
||||
w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD;
|
||||
if (orig != w->param.eapdbtl) {
|
||||
if (hdac_eapd_switch[i].hp_switch != 0)
|
||||
hdac_hp_switch_handler(devinfo);
|
||||
hdac_command(sc,
|
||||
HDA_CMD_SET_EAPD_BTL_ENABLE(devinfo->codec->cad, w->nid,
|
||||
w->param.eapdbtl), devinfo->codec->cad);
|
||||
HDA_CMD_SET_EAPD_BTL_ENABLE(devinfo->codec->cad,
|
||||
w->nid, w->param.eapdbtl), devinfo->codec->cad);
|
||||
}
|
||||
hdac_unlock(sc);
|
||||
return (left | (left << 8));
|
||||
}
|
||||
@ -2844,8 +2860,8 @@ hdac_attach(device_t dev)
|
||||
}
|
||||
|
||||
sc->dev = dev;
|
||||
sc->pci_subvendor = pci_get_subdevice(sc->dev) << 16;
|
||||
sc->pci_subvendor |= pci_get_subvendor(sc->dev);
|
||||
sc->pci_subvendor = (uint32_t)pci_get_subdevice(sc->dev) << 16;
|
||||
sc->pci_subvendor |= (uint32_t)pci_get_subvendor(sc->dev) & 0x0000ffff;
|
||||
|
||||
sc->chan_size = pcm_getbuffersize(dev,
|
||||
HDA_BUFSZ_MIN, HDA_BUFSZ_DEFAULT, HDA_BUFSZ_DEFAULT);
|
||||
@ -3236,8 +3252,8 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo)
|
||||
* Quirks
|
||||
*/
|
||||
for (i = 0; i < HDAC_QUIRKS_LEN; i++) {
|
||||
if (!(HDA_FLAG_MATCH(hdac_quirks[i].model, subvendor) &&
|
||||
HDA_FLAG_MATCH(hdac_quirks[i].id, id)))
|
||||
if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subvendor) &&
|
||||
HDA_DEV_MATCH(hdac_quirks[i].id, id)))
|
||||
continue;
|
||||
if (hdac_quirks[i].set != 0)
|
||||
devinfo->function.audio.quirks |=
|
||||
@ -3283,6 +3299,18 @@ hdac_vendor_patch_parse(struct hdac_devinfo *devinfo)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HDA_CODEC_AD1981HD:
|
||||
w = hdac_widget_get(devinfo, 11);
|
||||
if (w != NULL && w->enable != 0 && w->nconns > 3)
|
||||
w->selconn = 3;
|
||||
if (subvendor == IBM_M52_SUBVENDOR) {
|
||||
struct hdac_audio_ctl *ctl;
|
||||
|
||||
ctl = hdac_audio_ctl_amp_get(devinfo, 7, 0, 1);
|
||||
if (ctl != NULL)
|
||||
ctl->ossmask = SOUND_MASK_SPEAKER;
|
||||
}
|
||||
break;
|
||||
case HDA_CODEC_AD1986A:
|
||||
for (i = devinfo->startnode; i < devinfo->endnode; i++) {
|
||||
w = hdac_widget_get(devinfo, i);
|
||||
|
Loading…
Reference in New Issue
Block a user