@@ -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)
@@ -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 = {
@@ -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;
};