[PATCH] v4l: 683: some v4l2 api calls implemented on msp3400.c

- Some V4L2 API calls implemented on msp3400.c.

Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index e75e794..6e2b077 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -382,6 +382,7 @@
 {
 	int val = 0, bal = 0;
 
+muted=0;
 	if (!muted) {
 		/* 0x7f instead if 0x73 here has sound quality issues,
 		 * probably due to overmodulation + clipping ... */
@@ -989,6 +990,8 @@
 {
 	switch (norm) {
 	case VIDEO_MODE_PAL:
+		dprintk(KERN_DEBUG "msp34xx: video mode selected to PAL\n");
+
 #if 1
 		/* experimental: not sure this works with all chip versions */
 		return 0x7003;
@@ -997,12 +1000,16 @@
 		return 0x1003;
 #endif
 	case VIDEO_MODE_NTSC:  /* BTSC */
+		dprintk(KERN_DEBUG "msp34xx: video mode selected to NTSC\n");
 		return 0x2003;
 	case VIDEO_MODE_SECAM:
+		dprintk(KERN_DEBUG "msp34xx: video mode selected to SECAM\n");
 		return 0x0003;
 	case VIDEO_MODE_RADIO:
+		dprintk(KERN_DEBUG "msp34xx: video mode selected to Radio\n");
 		return 0x0003;
 	case VIDEO_MODE_AUTO:
+		dprintk(KERN_DEBUG "msp34xx: video mode selected to Auto\n");
 		return 0x2003;
 	default:
 		return 0x0003;
@@ -1495,6 +1502,7 @@
 		dprintk("msp34xx: error while reading chip version\n");
 		return -1;
 	}
+	printk(KERN_INFO "msp34xx: rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
 
 	msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance);
 
@@ -1762,6 +1770,7 @@
 			msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
 		break;
 	}
+
 	case VIDIOCSCHAN:
 	{
 		struct video_channel *vc = arg;
@@ -1782,6 +1791,92 @@
 	}
 
 	/* --- v4l2 ioctls --- */
+	case VIDIOC_S_STD:
+	{
+		v4l2_std_id *id = arg;
+
+		/*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
+		if (*id & V4L2_STD_PAL) {
+			msp->norm=VIDEO_MODE_PAL;
+		} else if (*id & V4L2_STD_SECAM) {
+			msp->norm=VIDEO_MODE_SECAM;
+		} else {
+			msp->norm=VIDEO_MODE_NTSC;
+		}
+
+		msp_wake_thread(client);
+		return 0;
+	}
+
+	case VIDIOC_G_AUDIO:
+	{
+		struct v4l2_audio *a = arg;
+
+		memset(a,0,sizeof(*a));
+
+		switch (a->index) {
+		case AUDIO_RADIO:
+			strcpy(a->name,"Radio");
+			break;
+		case AUDIO_EXTERN_1:
+			strcpy(a->name,"Extern 1");
+			break;
+		case AUDIO_EXTERN_2:
+			strcpy(a->name,"Extern 2");
+			break;
+		case AUDIO_TUNER:
+			strcpy(a->name,"Television");
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		msp_any_detect_stereo(client);
+ 		if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
+			a->capability=V4L2_AUDCAP_STEREO;
+		}
+
+		break;
+	}
+	case VIDIOC_S_AUDIO:
+	{
+		struct v4l2_audio *sarg = arg;
+
+		switch (sarg->index) {
+		case AUDIO_RADIO:
+			/* Hauppauge uses IN2 for the radio */
+			msp->mode   = MSP_MODE_FM_RADIO;
+			scart       = SCART_IN2;
+			break;
+		case AUDIO_EXTERN_1:
+			/* IN1 is often used for external input ... */
+			msp->mode   = MSP_MODE_EXTERN;
+			scart       = SCART_IN1;
+			break;
+		case AUDIO_EXTERN_2:
+			/* ... sometimes it is IN2 through ;) */
+			msp->mode   = MSP_MODE_EXTERN;
+			scart       = SCART_IN2;
+			break;
+		case AUDIO_TUNER:
+			msp->mode   = -1;
+			break;
+		}
+		if (scart) {
+			msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			msp->audmode = V4L2_TUNER_MODE_STEREO;
+			msp3400c_set_scart(client,scart,0);
+			msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
+		}
+ 		if (sarg->capability==V4L2_AUDCAP_STEREO) {
+			msp->audmode = V4L2_TUNER_MODE_STEREO;
+		} else {
+			msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
+		}
+		msp_any_set_audmode(client, msp->audmode);
+		msp_wake_thread(client);
+		break;
+	}
 	case VIDIOC_G_TUNER:
 	{
 		struct v4l2_tuner *vt = arg;