summaryrefslogtreecommitdiff
path: root/drivers/media/video/soc_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 18:44:15 +0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-19 07:18:39 +0400
commit2840d2497b912f25d2957477faa1c922ddd733e0 (patch)
tree0cb0fe8ced5e55236c448ab001c4c50faeaa3411 /drivers/media/video/soc_camera.c
parenta813d01f823259d1b27668c2149785515843a7eb (diff)
downloadlinux-2840d2497b912f25d2957477faa1c922ddd733e0.tar.xz
V4L/DVB (12513): soc-camera: add support for camera-host controls
Until now soc-camera only supported client (sensor) controls. This patch enables camera-host drivers to implement their own controls too. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/soc_camera.c')
-rw-r--r--drivers/media/video/soc_camera.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 0a1cb40bfbf6..b3fb8f290ad5 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -633,6 +633,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
{
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
int i;
WARN_ON(priv != file->private_data);
@@ -640,6 +641,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
if (!qc->id)
return -EINVAL;
+ /* First check host controls */
+ for (i = 0; i < ici->ops->num_controls; i++)
+ if (qc->id == ici->ops->controls[i].id) {
+ memcpy(qc, &(ici->ops->controls[i]),
+ sizeof(*qc));
+ return 0;
+ }
+
+ /* Then device controls */
for (i = 0; i < icd->ops->num_controls; i++)
if (qc->id == icd->ops->controls[i].id) {
memcpy(qc, &(icd->ops->controls[i]),
@@ -656,6 +666,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ int ret;
WARN_ON(priv != file->private_data);
@@ -672,6 +683,12 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
return 0;
}
+ if (ici->ops->get_ctrl) {
+ ret = ici->ops->get_ctrl(icd, ctrl);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+ }
+
return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl);
}
@@ -681,9 +698,16 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ int ret;
WARN_ON(priv != file->private_data);
+ if (ici->ops->set_ctrl) {
+ ret = ici->ops->set_ctrl(icd, ctrl);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+ }
+
return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl);
}