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