From 62cb4f9764b16dfba0b314a8f3d688fc36cc86f9 Mon Sep 17 00:00:00 2001 From: Peter Gielda Date: Thu, 25 Jul 2013 14:57:04 +0200 Subject: media: max9526: input selection support --- drivers/media/video/max9526.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/max9526.c b/drivers/media/video/max9526.c index 3fdfd7846e2d..22ecd00a8358 100644 --- a/drivers/media/video/max9526.c +++ b/drivers/media/video/max9526.c @@ -32,6 +32,7 @@ #include #include #include +#include /*MODULE NAME*/ #define MAX9526_MODULE_NAME "max9526" @@ -138,6 +139,8 @@ static const struct max9526_reg max9526_reg_list_default[] = { {TOK_TERM, 0, 0}, }; +#define REG_VIDEO_INPUT_SELECT_IN1 0x20 +#define REG_VIDEO_INPUT_SELECT_IN2 0x40 //static struct max9526_reg max9526_reg_list_default[0x11]; @@ -169,6 +172,8 @@ struct max9526_decoder { int ver; int streaming; + int active_input; + struct v4l2_pix_format pix; int num_fmts; const struct v4l2_fmtdesc *fmt_list; @@ -856,6 +861,25 @@ static int max9526_s_stream(struct v4l2_subdev *sd, int enable) return err; } +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct max9526_decoder *decoder = to_decoder(sd); + if (i < 2) { + decoder->active_input = i; + decoder->max9526_regs[REG_VIDEO_INPUT_SELECT_AND_CLAMP].val = (decoder->active_input == 0) ? REG_VIDEO_INPUT_SELECT_IN1 : REG_VIDEO_INPUT_SELECT_IN2; + return 0; + } + return -EINVAL; +} + +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { + struct soc_camera_device *icd = file->private_data; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct max9526_decoder *decoder = to_decoder(sd); + *i = decoder->active_input; + return 0; +} static const struct v4l2_subdev_core_ops max9526_core_ops = { .queryctrl = max9526_queryctrl, @@ -944,6 +968,7 @@ static struct max9526_decoder max9526_dev = { .std_list = max9526_std_list, .num_stds = ARRAY_SIZE(max9526_std_list), + .active_input = 1, // IN2 }; /** @@ -959,7 +984,8 @@ static int max9526_probe(struct i2c_client *client, const struct i2c_device_id * { struct max9526_decoder *decoder; struct v4l2_subdev *sd; -struct soc_camera_device *icd = client->dev.platform_data; + struct soc_camera_device *icd = client->dev.platform_data; + struct v4l2_ioctl_ops *ops; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -980,6 +1006,8 @@ struct soc_camera_device *icd = client->dev.platform_data; memcpy(decoder->max9526_regs, max9526_reg_list_default, sizeof(max9526_reg_list_default)); + decoder->max9526_regs[REG_VIDEO_INPUT_SELECT_AND_CLAMP].val = (decoder->active_input == 0) ? REG_VIDEO_INPUT_SELECT_IN1 : REG_VIDEO_INPUT_SELECT_IN2; + /* Copy board specific information here */ decoder->pdata = client->dev.platform_data; @@ -990,6 +1018,15 @@ struct soc_camera_device *icd = client->dev.platform_data; icd->ops = &max9526_soc_camera_ops; + /* + * this is the only way to support more than one input as soc_camera + * assumes in its own vidioc_s(g)_input implementation that only one input + * is present we have to override that with our own handlers. + */ + ops = (struct v4l2_ioctl_ops*)icd->vdev->ioctl_ops; + ops->vidioc_s_input = &vidioc_s_input; + ops->vidioc_g_input = &vidioc_g_input; + v4l2_info(sd, "%s decoder driver registered !!\n", sd->name); return 0; -- cgit v1.2.3