From 7a00d45cf017172c74d15bad0f9f14720efd69dd Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Date: Fri, 25 Aug 2006 16:53:09 -0300
Subject: [PATCH] V4L/DVB (6419): V4L2 port of tda7432 from V4L1 api

Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
---
 drivers/media/video/tda7432.c | 232 ++++++++++++++++++----------------
 1 file changed, 121 insertions(+), 111 deletions(-)

diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 43225802a5511..b4d10f7a4e57e 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -8,6 +8,7 @@
  * Muting and tone control by Jonathan Isom <jisom@ematic.com>
  *
  * Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
+ * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
  * This code is placed under the terms of the GNU General Public License
  * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
  * Which was based on tda8425.c by Greg Alexander (c) 1998
@@ -276,7 +277,7 @@ static void do_tda7432_init(struct i2c_client *client)
 	t->volume =  0x3b ;				 /* -27dB Volume            */
 	if (loudness)			 /* Turn loudness on?     */
 		t->volume |= TDA7432_LD_ON;
-	t->muted    = VIDEO_AUDIO_MUTE;
+	t->muted    = 1;
 	t->treble   = TDA7432_TREBLE_0DB; /* 0dB Treble            */
 	t->bass		= TDA7432_BASS_0DB; 	 /* 0dB Bass              */
 	t->lf     = TDA7432_ATTEN_0DB;	 /* 0dB attenuation       */
@@ -332,151 +333,160 @@ static int tda7432_detach(struct i2c_client *client)
 	return 0;
 }
 
-static int tda7432_command(struct i2c_client *client,
-			   unsigned int cmd, void *arg)
+static int tda7432_get_ctrl(struct i2c_client *client,
+			    struct v4l2_control *ctrl)
 {
 	struct tda7432 *t = i2c_get_clientdata(client);
-	v4l_dbg(2, debug,client,"In tda7432_command\n");
-	if (debug>1)
-		v4l_i2c_print_ioctl(client,cmd);
 
-	switch (cmd) {
-	/* --- v4l ioctls --- */
-	/* take care: bttv does userspace copying, we'll get a
-	   kernel pointer here... */
-
-	/* Query card - scale from TDA7432 settings to V4L settings */
-	case VIDIOCGAUDIO:
-	{
-		struct video_audio *va = arg;
-
-		va->flags |= VIDEO_AUDIO_VOLUME |
-			VIDEO_AUDIO_BASS |
-			VIDEO_AUDIO_TREBLE |
-			VIDEO_AUDIO_MUTABLE;
-		if (t->muted)
-			va->flags |= VIDEO_AUDIO_MUTE;
-		va->mode |= VIDEO_SOUND_STEREO;
-		/* Master volume control
-		 * V4L volume is min 0, max 65535
-		 * TDA7432 Volume:
-		 * Min (-79dB) is 0x6f
-		 * Max (+20dB) is 0x07 (630)
-		 * Max (0dB) is 0x20 (829)
-		 * (Mask out bit 7 of vol - it's for the loudness setting)
-		 */
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value=t->muted;
+		return 0;
+	case V4L2_CID_AUDIO_VOLUME:
 		if (!maxvol){  /* max +20db */
-			va->volume = ( 0x6f - (t->volume & 0x7F) ) * 630;
+			ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 630;
 		} else {       /* max 0db   */
-			va->volume = ( 0x6f - (t->volume & 0x7F) ) * 829;
+			ctrl->value = ( 0x6f - (t->volume & 0x7F) ) * 829;
 		}
-
-		/* Balance depends on L,R attenuation
-		 * V4L balance is 0 to 65535, middle is 32768
-		 * TDA7432 attenuation: min (0dB) is 0, max (-37.5dB) is 0x1f
-		 * to scale up to V4L numbers, mult by 1057
-		 * attenuation exists for lf, lr, rf, rr
-		 * we use only lf and rf (front channels)
-		 */
-
+		return 0;
+	case V4L2_CID_AUDIO_BALANCE:
+	{
 		if ( (t->lf) < (t->rf) )
 			/* right is attenuated, balance shifted left */
-			va->balance = (32768 - 1057*(t->rf));
+			ctrl->value = (32768 - 1057*(t->rf));
 		else
 			/* left is attenuated, balance shifted right */
-			va->balance = (32768 + 1057*(t->lf));
-
+			ctrl->value = (32768 + 1057*(t->lf));
+		return 0;
+	}
+	case V4L2_CID_AUDIO_BASS:
+	{
 		/* Bass/treble 4 bits each */
-		va->bass=t->bass;
-		if(va->bass >= 0x8)
-			va->bass = ~(va->bass - 0x8) & 0xf;
-		va->bass = (va->bass << 12)+(va->bass << 8)+(va->bass << 4)+(va->bass);
-		va->treble=t->treble;
-		if(va->treble >= 0x8)
-			va->treble = ~(va->treble - 0x8) & 0xf;
-		va->treble = (va->treble << 12)+(va->treble << 8)+(va->treble << 4)+(va->treble);
-
-		break; /* VIDIOCGAUDIO case */
+		int bass=t->bass;
+		if(bass >= 0x8)
+			bass = ~(bass - 0x8) & 0xf;
+		ctrl->value = (bass << 12)+(bass << 8)+(bass << 4)+(bass);
+		return 0;
 	}
-
-	/* Set card - scale from V4L settings to TDA7432 settings */
-	case VIDIOCSAUDIO:
+	case V4L2_CID_AUDIO_TREBLE:
 	{
-		struct video_audio *va = arg;
+		int treble=t->treble;
+		if(treble >= 0x8)
+			treble = ~(treble - 0x8) & 0xf;
+		ctrl->value = (treble << 12)+(treble << 8)+(treble << 4)+(treble);
+		return 0;
+	}
+	}
+	return -EINVAL;
+}
 
-		if(va->flags & VIDEO_AUDIO_VOLUME){
-			if(!maxvol){ /* max +20db */
-				t->volume = 0x6f - ((va->volume)/630);
-			} else {    /* max 0db   */
-				t->volume = 0x6f - ((va->volume)/829);
-			}
+static int tda7432_set_ctrl(struct i2c_client *client,
+			    struct v4l2_control *ctrl)
+{
+	struct tda7432 *t = i2c_get_clientdata(client);
 
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		t->muted=ctrl->value;
+		break;
+	case V4L2_CID_AUDIO_VOLUME:
+		if(!maxvol){ /* max +20db */
+			t->volume = 0x6f - ((ctrl->value)/630);
+		} else {    /* max 0db   */
+			t->volume = 0x6f - ((ctrl->value)/829);
+		}
 		if (loudness)		/* Turn on the loudness bit */
 			t->volume |= TDA7432_LD_ON;
 
-			tda7432_write(client,TDA7432_VL, t->volume);
-		}
-
-		if(va->flags & VIDEO_AUDIO_BASS)
-		{
-			t->bass = va->bass >> 12;
-			if(t->bass>= 0x8)
-					t->bass = (~t->bass & 0xf) + 0x8 ;
-		}
-		if(va->flags & VIDEO_AUDIO_TREBLE)
-		{
-			t->treble= va->treble >> 12;
-			if(t->treble>= 0x8)
-					t->treble = (~t->treble & 0xf) + 0x8 ;
-		}
-		if(va->flags & (VIDEO_AUDIO_TREBLE| VIDEO_AUDIO_BASS))
-			tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble );
-
-		if(va->flags & VIDEO_AUDIO_BALANCE)	{
-		if (va->balance < 32768)
-		{
+		tda7432_write(client,TDA7432_VL, t->volume);
+		return 0;
+	case V4L2_CID_AUDIO_BALANCE:
+		if (ctrl->value < 32768) {
 			/* shifted to left, attenuate right */
-			t->rr = (32768 - va->balance)/1057;
+			t->rr = (32768 - ctrl->value)/1057;
 			t->rf = t->rr;
 			t->lr = TDA7432_ATTEN_0DB;
 			t->lf = TDA7432_ATTEN_0DB;
-		}
-		else if(va->balance > 32769)
-		{
+		} else if(ctrl->value > 32769) {
 			/* shifted to right, attenuate left */
-			t->lf = (va->balance - 32768)/1057;
+			t->lf = (ctrl->value - 32768)/1057;
 			t->lr = t->lf;
 			t->rr = TDA7432_ATTEN_0DB;
 			t->rf = TDA7432_ATTEN_0DB;
-		}
-		else
-		{
+		} else {
 			/* centered */
 			t->rr = TDA7432_ATTEN_0DB;
 			t->rf = TDA7432_ATTEN_0DB;
 			t->lf = TDA7432_ATTEN_0DB;
 			t->lr = TDA7432_ATTEN_0DB;
 		}
-		}
+		break;
+	case V4L2_CID_AUDIO_BASS:
+		t->bass = ctrl->value >> 12;
+		if(t->bass>= 0x8)
+				t->bass = (~t->bass & 0xf) + 0x8 ;
+
+		tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble );
+		return 0;
+	case V4L2_CID_AUDIO_TREBLE:
+		t->treble= ctrl->value >> 12;
+		if(t->treble>= 0x8)
+				t->treble = (~t->treble & 0xf) + 0x8 ;
+
+		tda7432_write(client,TDA7432_TN, 0x10 | (t->bass << 4) | t->treble );
+		return 0;
+	default:
+		return -EINVAL;
+	}
 
-		t->muted=(va->flags & VIDEO_AUDIO_MUTE);
-		if (t->muted)
-		{
-			/* Mute & update balance*/
-			tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE);
-			tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE);
-			tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE);
-			tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE);
-		} else {
-			tda7432_write(client,TDA7432_LF, t->lf);
-			tda7432_write(client,TDA7432_LR, t->lr);
-			tda7432_write(client,TDA7432_RF, t->rf);
-			tda7432_write(client,TDA7432_RR, t->rr);
-		}
+	/* Used for both mute and balance changes */
+	if (t->muted)
+	{
+		/* Mute & update balance*/
+		tda7432_write(client,TDA7432_LF, t->lf | TDA7432_MUTE);
+		tda7432_write(client,TDA7432_LR, t->lr | TDA7432_MUTE);
+		tda7432_write(client,TDA7432_RF, t->rf | TDA7432_MUTE);
+		tda7432_write(client,TDA7432_RR, t->rr | TDA7432_MUTE);
+	} else {
+		tda7432_write(client,TDA7432_LF, t->lf);
+		tda7432_write(client,TDA7432_LR, t->lr);
+		tda7432_write(client,TDA7432_RF, t->rf);
+		tda7432_write(client,TDA7432_RR, t->rr);
+	}
+	return 0;
+}
 
-		break;
+static int tda7432_command(struct i2c_client *client,
+			   unsigned int cmd, void *arg)
+{
+	v4l_dbg(2, debug,client,"In tda7432_command\n");
+	if (debug>1)
+		v4l_i2c_print_ioctl(client,cmd);
+
+	switch (cmd) {
+	/* --- v4l ioctls --- */
+	/* take care: bttv does userspace copying, we'll get a
+	   kernel pointer here... */
+	case VIDIOC_QUERYCTRL:
+	{
+		struct v4l2_queryctrl *qc = arg;
+
+		switch (qc->id) {
+			case V4L2_CID_AUDIO_MUTE:
+			case V4L2_CID_AUDIO_VOLUME:
+			case V4L2_CID_AUDIO_BALANCE:
+			case V4L2_CID_AUDIO_BASS:
+			case V4L2_CID_AUDIO_TREBLE:
+			default:
+				return -EINVAL;
+		}
+		return v4l2_ctrl_query_fill_std(qc);
+	}
+	case VIDIOC_S_CTRL:
+		return tda7432_set_ctrl(client, arg);
 
-	} /* end of VIDEOCSAUDIO case */
+	case VIDIOC_G_CTRL:
+		return tda7432_get_ctrl(client, arg);
 
 	} /* end of (cmd) switch */
 
-- 
2.30.2