Fix volume control for the AK4358 DAC. The attenuation control registers of the AK4358 use only 7bit for the volume, the msb is used to enable attenuation output. Without this patch there are 256 volume levels the lower 128 of which are mute. Signed-off-by: Jochen Voss <voss@xxxxxxxxxx> diff -ur alsa-driver-1.0.12rc3.orig/alsa-kernel/i2c/other/ak4xxx-adda.c alsa-driver-1.0.12rc3/alsa-kernel/i2c/other/ak4xxx-adda.c --- alsa-driver-1.0.12rc3.orig/alsa-kernel/i2c/other/ak4xxx-adda.c 2006-08-14 11:55:24.000000000 +0100 +++ alsa-driver-1.0.12rc3/alsa-kernel/i2c/other/ak4xxx-adda.c 2006-08-22 20:46:42.000000000 +0100 @@ -285,10 +285,12 @@ #define AK_GET_CHIP(val) (((val) >> 8) & 0xff) #define AK_GET_ADDR(val) ((val) & 0xff) #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f) +#define AK_GET_NEEDSMSB(val) (((val) >> 22) & 1) #define AK_GET_INVERT(val) (((val) >> 23) & 1) #define AK_GET_MASK(val) (((val) >> 24) & 0xff) #define AK_COMPOSE(chip,addr,shift,mask) \ (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24)) +#define AK_NEEDSMSB (1<<22) #define AK_INVERT (1<<23) static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol, @@ -309,10 +311,13 @@ struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); int chip = AK_GET_CHIP(kcontrol->private_value); int addr = AK_GET_ADDR(kcontrol->private_value); + int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); unsigned int mask = AK_GET_MASK(kcontrol->private_value); unsigned char val = snd_akm4xxx_get(ak, chip, addr); - + + if (needsmsb) + val &= 0x7f; ucontrol->value.integer.value[0] = invert ? mask - val : val; return 0; } @@ -323,6 +328,7 @@ struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); int chip = AK_GET_CHIP(kcontrol->private_value); int addr = AK_GET_ADDR(kcontrol->private_value); + int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); unsigned int mask = AK_GET_MASK(kcontrol->private_value); unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); @@ -330,6 +336,8 @@ if (invert) nval = mask - nval; + if (needsmsb) + nval |= 0x80; change = snd_akm4xxx_get(ak, chip, addr) != nval; if (change) snd_akm4xxx_write(ak, chip, addr, nval); @@ -354,13 +362,19 @@ struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); int chip = AK_GET_CHIP(kcontrol->private_value); int addr = AK_GET_ADDR(kcontrol->private_value); + int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); unsigned int mask = AK_GET_MASK(kcontrol->private_value); - unsigned char val = snd_akm4xxx_get(ak, chip, addr); - + unsigned char val; + + val = snd_akm4xxx_get(ak, chip, addr); + if (needsmsb) + val &= 0x7f; ucontrol->value.integer.value[0] = invert ? mask - val : val; val = snd_akm4xxx_get(ak, chip, addr+1); + if (needsmsb) + val &= 0x7f; ucontrol->value.integer.value[1] = invert ? mask - val : val; return 0; @@ -372,6 +386,7 @@ struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); int chip = AK_GET_CHIP(kcontrol->private_value); int addr = AK_GET_ADDR(kcontrol->private_value); + int needsmsb = AK_GET_NEEDSMSB(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); unsigned int mask = AK_GET_MASK(kcontrol->private_value); unsigned char nval = ucontrol->value.integer.value[0] % (mask+1); @@ -379,6 +394,8 @@ if (invert) nval = mask - nval; + if (needsmsb) + nval |= 0x80; change0 = snd_akm4xxx_get(ak, chip, addr) != nval; if (change0) snd_akm4xxx_write(ak, chip, addr, nval); @@ -386,6 +403,8 @@ nval = ucontrol->value.integer.value[1] % (mask+1); if (invert) nval = mask - nval; + if (needsmsb) + nval |= 0x80; change1 = snd_akm4xxx_get(ak, chip, addr+1) != nval; if (change1) snd_akm4xxx_write(ak, chip, addr+1, nval); @@ -585,16 +604,13 @@ /* register 4-9, chip #0 only */ ctl->private_value = AK_COMPOSE(0, idx + 4, 0, 255); break; - case SND_AK4358: - if (idx >= 6) - /* register 4-9, chip #0 only */ - ctl->private_value = - AK_COMPOSE(0, idx + 5, 0, 255); - else - /* register 4-9, chip #0 only */ - ctl->private_value = - AK_COMPOSE(0, idx + 4, 0, 255); + case SND_AK4358: { + /* register 4-9 and 11-12, chip #0 only */ + int addr = idx < 6 ? idx + 4 : idx + 5; + ctl->private_value = + AK_COMPOSE(0, addr, 0, 127) | AK_NEEDSMSB; break; + } case SND_AK4381: /* register 3 & 4 */ ctl->private_value =
Attachment:
signature.asc
Description: Digital signature
------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/alsa-devel