cx88 volume + balance dependency
- From: Marcin Rudowski <mar_rud (at) poczta.onet.pl>
- Date: Fri, 10 Mar 2006 00:33:11 +0100
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