By Date: <-- -->
By Thread: <-- -->

cx88 volume + balance dependency



This patch controls balance value so that volume+balance is never
below -63dB.
Used shadow register makes this action invisible to applications
(changes are only written to real register, not shadowed one).

        Signed-off-by: Marcin Rudowski <mar_rud (at) poczta.onet.pl>

NOTE:
I assumed, that writing to AUD_BAL_CTL need to be shadowed (as is now),
so I added some additional "fake" entry in shadow table to save the
value before corrections.

Regards,
Marcin
diff -rup v4l-dvb.orig/linux/drivers/media/video/cx88/cx88.h v4l-dvb/linux/drivers/media/video/cx88/cx88.h
--- v4l-dvb.orig/linux/drivers/media/video/cx88/cx88.h	2006-03-09 22:25:58.000000000 +0100
+++ v4l-dvb/linux/drivers/media/video/cx88/cx88.h	2006-03-10 00:21:49.000000000 +0100
 (at)  (at)  -69,7 +69,8  (at)  (at) 
 /* need "shadow" registers for some write-only ones ... */
 #define SHADOW_AUD_VOL_CTL           1
 #define SHADOW_AUD_BAL_CTL           2
-#define SHADOW_MAX                   3
+#define SHADOW_FAKE_AUD_BAL_CTL      3
+#define SHADOW_MAX                   4
 
 /* FM Radio deemphasis type */
 enum cx88_deemph_type {
diff -rup v4l-dvb.orig/linux/drivers/media/video/cx88/cx88-video.c v4l-dvb/linux/drivers/media/video/cx88/cx88-video.c
--- v4l-dvb.orig/linux/drivers/media/video/cx88/cx88-video.c	2006-03-09 22:37:26.000000000 +0100
+++ v4l-dvb/linux/drivers/media/video/cx88/cx88-video.c	2006-03-10 00:21:06.000000000 +0100
 (at)  (at)  -1160,6 +1160,7  (at)  (at)  static int get_control(struct cx88_core 
 	value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg);
 	switch (ctl->id) {
 	case V4L2_CID_AUDIO_BALANCE:
+		value = cx_sread(SHADOW_FAKE_AUD_BAL_CTL);
 		ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40)
 					: (0x7f - (value & 0x7f));
 		break;
 (at)  (at)  -1182,6 +1183,7  (at)  (at)  static int set_control(struct cx88_core 
 	/* struct cx88_core *core = dev->core; */
 	struct cx88_ctrl *c = NULL;
 	u32 value,mask;
+	u32 tmp_vol_value;
 	int i;
 	for (i = 0; i < CX8800_CTLS; i++) {
 		if (cx8800_ctls[i].v.id == ctl->id) {
 (at)  (at)  -1206,10 +1208,28  (at)  (at)  static int set_control(struct cx88_core 
 	mask=c->mask;
 	switch (ctl->id) {
 	case V4L2_CID_AUDIO_BALANCE:
+		/* bits [0:5] represents attenaution (0:-63dB)
+		   attenaution channel selection: ([6]==1) ? right : left */
 		value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40);
+		core->shadow[SHADOW_FAKE_AUD_BAL_CTL] = value & 0x7f;
+
+		/* (balance + volume) shouldn't be more then -63dB */
+		tmp_vol_value = cx_sread(SHADOW_AUD_VOL_CTL) & 0x3f;
+		if ( (value & 0x3f) + tmp_vol_value > 0x3f )
+			value = (value & 0x40) | (0x3f - tmp_vol_value);
+
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
 		value = 0x3f - (ctl->value & 0x3f);
+
+		/* (balance + volume) shouldn't be more then -63dB */
+		tmp_vol_value = cx_sread(SHADOW_FAKE_AUD_BAL_CTL) & 0x7f;
+		if ( (tmp_vol_value & 0x3f) + value > 0x3f ) {
+			tmp_vol_value = (tmp_vol_value & 0x40) | (0x3f - value);
+			dprintk(1,"set_control Balance correction: reg=0x%02x val=0x%02x (mask 0x7f)[shadowed]\n",
+				AUD_BAL_CTL, tmp_vol_value);
+			cx_sandor(SHADOW_AUD_BAL_CTL, AUD_BAL_CTL, 0x7f, tmp_vol_value);
+		}
 		break;
 	case V4L2_CID_SATURATION:
 		/* special v_sat handling */
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request (at) redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list