[PATCH] fix volume control for the AK4358 DAC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux