kern/84728: [sound] [patch] ac97 broken mixing capabilities
checking
Ariff Abdullah
skywizard at MyBSD.org.my
Thu Aug 11 09:30:22 GMT 2005
The following reply was made to PR kern/84728; it has been noted by GNATS.
From: Ariff Abdullah <skywizard at MyBSD.org.my>
To: Michael Seyfert <michaels at sdf.lonestar.org>
Cc: bug-followup at FreeBSD.org
Subject: Re: kern/84728: [sound] [patch] ac97 broken mixing capabilities
checking
Date: Thu, 11 Aug 2005 17:21:11 +0800
On Wed, 10 Aug 2005 23:24:13 +0000
Michael Seyfert <michaels at sdf.lonestar.org> wrote:
> No good.. please try this one:
>
> --- sys/dev/sound/pcm/ac97.c.orig Wed Aug 10 16:25:42 2005
> +++ sys/dev/sound/pcm/ac97.c Wed Aug 10 16:25:53 2005
> @@ -618,25 +618,12 @@
> }
> if ((j & 0x8000)) {
> j = ((1 << 6) - 1) << codec->mix[i].ofs;
> - if (codec->mix[i].mute)
> - j |= 0x8000;
> ac97_wrcd(codec, codec->mix[i].reg, j);
> j = ac97_rdcd(codec, codec->mix[i].reg) & j;
> j >>= codec->mix[i].ofs;
> - if (codec->mix[i].reg == AC97_MIX_TONE &&
> - ((j & 0x0001) == 0x0000))
> - j >>= 1;
> - for (k = 0; j != 0; k++)
> - j >>= 1;
> - for (j = 0; k != 0; j++)
> - k >>= 1;
> - if (j != 0) {
> - codec->mix[i].enable = 1;
> -#if 0
> - codec->mix[i].bits = j;
> -#endif
> - } else
> - codec->mix[i].enable = 0;
> + codec->mix[i].enable = (j != 0 && j != old)? 1 : 0;
> + for (k = 1; j & (1 << k); k++);
> + codec->mix[i].bits = j? k : 0;
> } else
> codec->mix[i].enable = 0;
> ac97_wrcd(codec, codec->mix[i].reg, old);
>
No good for various STAC* / ALC (the reason for why this new detection mechanism).
Ok.. I think this will do the job for both of us and others too:
(Sorry, my previous post didn't make it into audit trail.)
--- sys/dev/sound/pcm/ac97.c.orig Thu Aug 11 08:46:32 2005
+++ sys/dev/sound/pcm/ac97.c Thu Aug 11 11:41:05 2005
@@ -74,9 +74,9 @@
static const struct ac97mixtable_entry ac97mixtable_default[32] = {
/* [offset] reg bits of st mu re mk en */
- [SOUND_MIXER_VOLUME] = { AC97_MIX_MASTER, 5, 0, 1, 1, 6, 0, 1 },
- [SOUND_MIXER_OGAIN] = { AC97_MIX_AUXOUT, 5, 0, 1, 1, 0, 0, 0 },
- [SOUND_MIXER_PHONEOUT] = { AC97_MIX_MONO, 5, 0, 0, 1, 7, 0, 0 },
+ [SOUND_MIXER_VOLUME] = { AC97_MIX_MASTER, 6, 0, 1, 1, 6, 0, 1 },
+ [SOUND_MIXER_OGAIN] = { AC97_MIX_AUXOUT, 6, 0, 1, 1, 0, 0, 0 },
+ [SOUND_MIXER_PHONEOUT] = { AC97_MIX_MONO, 6, 0, 0, 1, 7, 0, 0 },
[SOUND_MIXER_BASS] = { AC97_MIX_TONE, 4, 8, 0, 0, 0, 1, 0 },
[SOUND_MIXER_TREBLE] = { AC97_MIX_TONE, 4, 0, 0, 0, 0, 1, 0 },
[SOUND_MIXER_PCM] = { AC97_MIX_PCM, 5, 0, 1, 1, 0, 0, 1 },
@@ -283,7 +283,19 @@
u_int16_t
ac97_rdcd(struct ac97_info *codec, int reg)
{
- return AC97_READ(codec->methods, codec->devinfo, reg);
+ u_int16_t v[2], i = 0;
+
+ v[0] = AC97_READ(codec->methods, codec->devinfo, reg);
+ v[1] = AC97_READ(codec->methods, codec->devinfo, reg);
+ while (v[0] != v[1] && i < 100)
+ v[i++ & 1] = AC97_READ(codec->methods, codec->devinfo, reg);
+#if 0
+ if (i > 0) {
+ device_printf(codec->dev, "%s(): Inconsistent register value at"
+ " 0x%08x (retry: %d)\n", __func__, reg, i);
+ }
+#endif
+ return v[1];
}
void
@@ -617,24 +629,25 @@
j = ac97_rdcd(codec, codec->mix[i].reg);
}
if ((j & 0x8000)) {
- j = ((1 << 6) - 1) << codec->mix[i].ofs;
+ j = ((1 << codec->mix[i].bits) - 1) << codec->mix[i].ofs;
if (codec->mix[i].mute)
j |= 0x8000;
ac97_wrcd(codec, codec->mix[i].reg, j);
- j = ac97_rdcd(codec, codec->mix[i].reg) & j;
- j >>= codec->mix[i].ofs;
+ k = ac97_rdcd(codec, codec->mix[i].reg) & (j & ~0x8000);
+ k >>= codec->mix[i].ofs;
if (codec->mix[i].reg == AC97_MIX_TONE &&
- ((j & 0x0001) == 0x0000))
- j >>= 1;
- for (k = 0; j != 0; k++)
- j >>= 1;
- for (j = 0; k != 0; j++)
+ ((k & 0x0001) == 0x0000))
k >>= 1;
+ j = 0;
+ while (k >> j)
+ j++;
if (j != 0) {
- codec->mix[i].enable = 1;
#if 0
- codec->mix[i].bits = j;
+ device_printf(codec->dev, "%d: (%d) %d -> %d\n",
+ i, k, codec->mix[i].bits, j);
#endif
+ codec->mix[i].enable = 1;
+ codec->mix[i].bits = j;
} else
codec->mix[i].enable = 0;
} else
--
Ariff Abdullah
MyBSD
http://www.MyBSD.org.my (IPv6/IPv4)
http://staff.MyBSD.org.my (IPv6/IPv4)
http://tomoyo.MyBSD.org.my (IPv6/IPv4)
More information about the freebsd-bugs
mailing list