From owner-freebsd-bugs@FreeBSD.ORG Thu Aug 11 09:30:22 2005 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4EDB416A420 for ; Thu, 11 Aug 2005 09:30:22 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id E8DBE43D48 for ; Thu, 11 Aug 2005 09:30:21 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.3/8.13.3) with ESMTP id j7B9ULZg088045 for ; Thu, 11 Aug 2005 09:30:21 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.3/8.13.1/Submit) id j7B9ULba088044; Thu, 11 Aug 2005 09:30:21 GMT (envelope-from gnats) Date: Thu, 11 Aug 2005 09:30:21 GMT Message-Id: <200508110930.j7B9ULba088044@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Ariff Abdullah Cc: Subject: Re: kern/84728: [sound] [patch] ac97 broken mixing capabilities checking X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Ariff Abdullah List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Aug 2005 09:30:22 -0000 The following reply was made to PR kern/84728; it has been noted by GNATS. From: Ariff Abdullah To: Michael Seyfert Cc: bug-followup@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 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)