diff mbox

Adding multiple input support to soc-camera and tw9910

Message ID 20091103163323.46300@gmx.net (mailing list archive)
State Accepted
Headers show

Commit Message

p.wiesner@gmx.net Nov. 3, 2009, 4:33 p.m. UTC
None
diff mbox

Patch

diff -r 43878f8dbfb0 -r a5254e7d306a linux/drivers/media/video/soc_camera.c
--- a/linux/drivers/media/video/soc_camera.c	Sun Nov 01 07:17:46 2009 -0200
+++ b/linux/drivers/media/video/soc_camera.c	Tue Nov 03 17:17:49 2009 +0100
@@ -119,11 +119,10 @@ 
 	struct soc_camera_device *icd = icf->icd;
 	int ret = 0;
 
-	if (inp->index != 0)
-		return -EINVAL;
-
 	if (icd->ops->enum_input)
 		ret = icd->ops->enum_input(icd, inp);
+	else if (inp->index != 0)
+		return -EINVAL;
 	else {
 		/* default is camera */
 		inp->type = V4L2_INPUT_TYPE_CAMERA;
@@ -136,17 +135,30 @@ 
 
 static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i)
 {
-	*i = 0;
+	struct soc_camera_file *icf = file->private_data;
+	struct soc_camera_device *icd = icf->icd;
+	int ret = 0;
 
-	return 0;
+	if (icd->ops->g_input)
+		ret = icd->ops->g_input(icd, i);
+	else
+		*i = 0;
+
+	return ret;
 }
 
 static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
 {
-	if (i > 0)
+	struct soc_camera_file *icf = file->private_data;
+	struct soc_camera_device *icd = icf->icd;
+	int ret = 0;
+
+	if (icd->ops->s_input)
+		ret = icd->ops->s_input(icd, i);
+	else if (i > 0)
 		return -EINVAL;
 
-	return 0;
+	return ret;
 }
 
 static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
diff -r 43878f8dbfb0 -r a5254e7d306a linux/drivers/media/video/tw9910.c
--- a/linux/drivers/media/video/tw9910.c	Sun Nov 01 07:17:46 2009 -0200
+++ b/linux/drivers/media/video/tw9910.c	Tue Nov 03 17:17:49 2009 +0100
@@ -566,9 +566,47 @@ 
 static int tw9910_enum_input(struct soc_camera_device *icd,
 			     struct v4l2_input *inp)
 {
-	inp->type = V4L2_INPUT_TYPE_TUNER;
-	inp->std  = V4L2_STD_UNKNOWN;
-	strcpy(inp->name, "Video");
+	switch (inp->index) {
+	case 0:
+		strcpy(inp->name, "Video Input 1");
+		break;
+	case 1:
+		strcpy(inp->name, "Video Input 2");
+		break;
+	case 2:
+		strcpy(inp->name, "Video Input 3");
+		break;
+	case 3:
+		strcpy(inp->name, "Video Input 4");
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+	inp->std  = V4L2_STD_625_50 | V4L2_STD_525_60;
+
+	return 0;
+}
+
+static int tw9910_g_input(struct soc_camera_device *icd, unsigned int *i)
+{
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+	*i = (i2c_smbus_read_byte_data(client, INFORM) & 0x0C) >> 2;
+
+	if (*i < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int tw9910_s_input(struct soc_camera_device *icd, unsigned int i)
+{
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+
+	if (tw9910_mask_set(client, INFORM, 0x0C, i << 2))
+		return -EINVAL;
 
 	return 0;
 }
@@ -906,6 +944,8 @@ 
 	.set_bus_param		= tw9910_set_bus_param,
 	.query_bus_param	= tw9910_query_bus_param,
 	.enum_input		= tw9910_enum_input,
+	.g_input		= tw9910_g_input,
+	.s_input		= tw9910_s_input,
 };
 
 static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
diff -r 43878f8dbfb0 -r a5254e7d306a linux/include/media/soc_camera.h
--- a/linux/include/media/soc_camera.h	Sun Nov 01 07:17:46 2009 -0200
+++ b/linux/include/media/soc_camera.h	Tue Nov 03 17:17:49 2009 +0100
@@ -197,6 +197,8 @@ 
 	unsigned long (*query_bus_param)(struct soc_camera_device *);
 	int (*set_bus_param)(struct soc_camera_device *, unsigned long);
 	int (*enum_input)(struct soc_camera_device *, struct v4l2_input *);
+	int (*g_input)(struct soc_camera_device *, unsigned int *);
+	int (*s_input)(struct soc_camera_device *, unsigned int);
 	const struct v4l2_queryctrl *controls;
 	int num_controls;
 };