diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 16:44:15 +0200 |
---|---|---|
committer | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-08-25 16:44:15 +0200 |
commit | ac97b8b24a867c8c2d3dd71d3c3d12b078b8091c (patch) | |
tree | 703c5229ce74cc31678b7d549c87aa837fb2f8d0 | |
parent | 4e4ce6d0b364f6dcab06b9f80942339fbfef9e0a (diff) | |
download | mediapointer-dvb-s2-ac97b8b24a867c8c2d3dd71d3c3d12b078b8091c.tar.gz mediapointer-dvb-s2-ac97b8b24a867c8c2d3dd71d3c3d12b078b8091c.tar.bz2 |
soc-camera: add support for camera-host controls
From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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>
Priority: low
---
drivers/media/video/soc_camera.c | 24 ++++++++++++++++++++++++
include/media/soc_camera.h | 4 ++++
2 files changed, 28 insertions(+), 0 deletions(-)
-rw-r--r-- | linux/drivers/media/video/soc_camera.c | 24 | ||||
-rw-r--r-- | linux/include/media/soc_camera.h | 4 |
2 files changed, 28 insertions, 0 deletions
diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index e759400cc..42e7acd9b 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -634,6 +634,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); @@ -641,6 +642,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]), @@ -657,6 +667,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); @@ -673,6 +684,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); } @@ -682,9 +699,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); } diff --git a/linux/include/media/soc_camera.h b/linux/include/media/soc_camera.h index 3bc5b6b20..2d116bbbc 100644 --- a/linux/include/media/soc_camera.h +++ b/linux/include/media/soc_camera.h @@ -83,7 +83,11 @@ struct soc_camera_host_ops { int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); int (*set_bus_param)(struct soc_camera_device *, __u32); + int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); + int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *); unsigned int (*poll)(struct file *, poll_table *); + const struct v4l2_queryctrl *controls; + int num_controls; }; #define SOCAM_SENSOR_INVERT_PCLK (1 << 0) |