summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2007-04-19 13:54:22 +0000
committerariff <ariff@FreeBSD.org>2007-04-19 13:54:22 +0000
commitd81e54ad86b2abc3cb63f1688f5462009d0d244b (patch)
treed9fbbaabaab08fe8c778853a63dabbf1299cf8b4 /sys/dev
parentf9d2951cadf7da6eb5345a1c593b6389e5abe53b (diff)
downloadFreeBSD-src-d81e54ad86b2abc3cb63f1688f5462009d0d244b.zip
FreeBSD-src-d81e54ad86b2abc3cb63f1688f5462009d0d244b.tar.gz
- AC97 quirk / patch cleanups. Most quirks doesn't work in general sense
and should only be applied on certain specific card / vendor, hence the addition of ac97_getsubvendor(). - Fix low volume issue on several MSI laptops through ALC655 quirk. Reported/Tested by: Christian Mueller <raptor-freebsd-multimedia@xpls.de> MFC after: 1 week
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sound/pcm/ac97.c29
-rw-r--r--sys/dev/sound/pcm/ac97.h1
-rw-r--r--sys/dev/sound/pcm/ac97_patch.c48
-rw-r--r--sys/dev/sound/pcm/ac97_patch.h1
4 files changed, 59 insertions, 20 deletions
diff --git a/sys/dev/sound/pcm/ac97.c b/sys/dev/sound/pcm/ac97.c
index 0993fd6..e32db64 100644
--- a/sys/dev/sound/pcm/ac97.c
+++ b/sys/dev/sound/pcm/ac97.c
@@ -54,6 +54,7 @@ struct ac97_info {
device_t dev;
void *devinfo;
u_int32_t id;
+ u_int32_t subvendor;
unsigned count, caps, se, extcaps, extid, extstat, noext:1;
u_int32_t flags;
struct ac97mixtable_entry mix[32];
@@ -152,7 +153,7 @@ static struct ac97_codecid ac97codecid[] = {
{ 0x414c4740, 0x0f, 0, "ALC202", 0 },
{ 0x414c4720, 0x0f, 0, "ALC650", 0 },
{ 0x414c4752, 0x0f, 0, "ALC250", 0 },
- { 0x414c4760, 0x0f, 0, "ALC655", 0 },
+ { 0x414c4760, 0x0f, 0, "ALC655", alc655_patch },
{ 0x414c4770, 0x0f, 0, "ALC203", 0 },
{ 0x414c4780, 0x0f, 0, "ALC658", 0 },
{ 0x414c4790, 0x0f, 0, "ALC850", 0 },
@@ -405,6 +406,12 @@ ac97_getcaps(struct ac97_info *codec)
return codec->caps;
}
+u_int32_t
+ac97_getsubvendor(struct ac97_info *codec)
+{
+ return codec->subvendor;
+}
+
static int
ac97_setrecsrc(struct ac97_info *codec, int channel)
{
@@ -627,6 +634,9 @@ ac97_initmixer(struct ac97_info *codec)
}
codec->id = id;
+ codec->subvendor = (u_int32_t)pci_get_subdevice(codec->dev) << 16;
+ codec->subvendor |= (u_int32_t)pci_get_subvendor(codec->dev) &
+ 0x0000ffff;
codec->noext = 0;
codec_patch = NULL;
@@ -913,7 +923,6 @@ ac97mix_init(struct snd_mixer *m)
{
struct ac97_info *codec = mix_getdevinfo(m);
struct snddev_info *d;
- u_int32_t subvendor;
u_int32_t i, mask;
if (codec == NULL)
@@ -924,20 +933,18 @@ ac97mix_init(struct snd_mixer *m)
switch (codec->id) {
case 0x41445374: /* AD1981B */
- subvendor = (u_int32_t)pci_get_subdevice(codec->dev) << 16;
- subvendor |= (u_int32_t)pci_get_subvendor(codec->dev) &
- 0x0000ffff;
- /* IBM Thinkcentre */
- if (subvendor == 0x02d91014) {
- /* Enable headphone jack sensing */
- ac97_wrcd(codec, 0x72, ac97_rdcd(codec, 0x72) |
- 0x0800);
+ if (codec->subvendor == 0x02d91014) {
+ /*
+ * IBM Thinkcentre:
+ * Tie "ogain" and "phone" to "vol" since its
+ * master volume is basically useless and can't
+ * control anything.
+ */
mask = 0;
if (codec->mix[SOUND_MIXER_OGAIN].enable)
mask |= SOUND_MASK_OGAIN;
if (codec->mix[SOUND_MIXER_PHONEOUT].enable)
mask |= SOUND_MASK_PHONEOUT;
- /* Tie ogain/phone to master volume */
if (codec->mix[SOUND_MIXER_VOLUME].enable)
mix_setparentchild(m, SOUND_MIXER_VOLUME,
mask);
diff --git a/sys/dev/sound/pcm/ac97.h b/sys/dev/sound/pcm/ac97.h
index f73dc76..3112cc0 100644
--- a/sys/dev/sound/pcm/ac97.h
+++ b/sys/dev/sound/pcm/ac97.h
@@ -101,6 +101,7 @@ int ac97_setextmode(struct ac97_info *codec, u_int16_t mode);
u_int16_t ac97_getextmode(struct ac97_info *codec);
u_int16_t ac97_getextcaps(struct ac97_info *codec);
u_int16_t ac97_getcaps(struct ac97_info *codec);
+u_int32_t ac97_getsubvendor(struct ac97_info *codec);
u_int16_t ac97_rdcd(struct ac97_info *codec, int reg);
void ac97_wrcd(struct ac97_info *codec, int reg, u_int16_t val);
diff --git a/sys/dev/sound/pcm/ac97_patch.c b/sys/dev/sound/pcm/ac97_patch.c
index 1be0852..1db0a98 100644
--- a/sys/dev/sound/pcm/ac97_patch.c
+++ b/sys/dev/sound/pcm/ac97_patch.c
@@ -49,19 +49,49 @@ void ad198x_patch(struct ac97_info* codec)
void ad1981b_patch(struct ac97_info* codec)
{
-#if 0
- ac97_wrcd(codec, AC97_AD_JACK_SPDIF,
- ac97_rdcd(codec, AC97_AD_JACK_SPDIF) | 0x0800);
-#endif
+ /*
+ * Enable headphone jack sensing.
+ */
+ switch (ac97_getsubvendor(codec)) {
+ case 0x02d91014: /* IBM Thinkcentre */
+ ac97_wrcd(codec, AC97_AD_JACK_SPDIF,
+ ac97_rdcd(codec, AC97_AD_JACK_SPDIF) | 0x0800);
+ break;
+ default:
+ break;
+ }
}
void cmi9739_patch(struct ac97_info* codec)
{
/*
- * Few laptops (notably ASUS W1000N) need extra register
- * initialization to power up the internal speakers.
+ * Few laptops need extra register initialization
+ * to power up the internal speakers.
+ */
+ switch (ac97_getsubvendor(codec)) {
+ case 0x18431043: /* ASUS W1000N */
+ ac97_wrcd(codec, AC97_REG_POWER, 0x000f);
+ ac97_wrcd(codec, AC97_MIXEXT_CLFE, 0x0000);
+ ac97_wrcd(codec, 0x64, 0x7110);
+ break;
+ default:
+ break;
+ }
+}
+
+void alc655_patch(struct ac97_info* codec)
+{
+ /*
+ * MSI (Micro-Star International) specific EAPD quirk.
*/
- ac97_wrcd(codec, AC97_REG_POWER, 0x000f);
- ac97_wrcd(codec, AC97_MIXEXT_CLFE, 0x0000);
- ac97_wrcd(codec, 0x64, 0x7110);
+ switch (ac97_getsubvendor(codec)) {
+ case 0x00611462: /* MSI S250 */
+ case 0x01311462: /* MSI S270 */
+ case 0x01611462: /* LG K1 Express */
+ case 0x03511462: /* MSI L725 */
+ ac97_wrcd(codec, 0x7a, ac97_rdcd(codec, 0x7a) & 0xfffd);
+ break;
+ default:
+ break;
+ }
}
diff --git a/sys/dev/sound/pcm/ac97_patch.h b/sys/dev/sound/pcm/ac97_patch.h
index 7a32975..c8df443 100644
--- a/sys/dev/sound/pcm/ac97_patch.h
+++ b/sys/dev/sound/pcm/ac97_patch.h
@@ -32,3 +32,4 @@ void ad1886_patch(struct ac97_info*);
void ad198x_patch(struct ac97_info*);
void ad1981b_patch(struct ac97_info*);
void cmi9739_patch(struct ac97_info*);
+void alc655_patch(struct ac97_info*);
OpenPOWER on IntegriCloud