Commit 2840d249 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

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: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent a813d01f
...@@ -633,6 +633,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv, ...@@ -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_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd; struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
int i; int i;
WARN_ON(priv != file->private_data); WARN_ON(priv != file->private_data);
...@@ -640,6 +641,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv, ...@@ -640,6 +641,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
if (!qc->id) if (!qc->id)
return -EINVAL; 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++) for (i = 0; i < icd->ops->num_controls; i++)
if (qc->id == icd->ops->controls[i].id) { if (qc->id == icd->ops->controls[i].id) {
memcpy(qc, &(icd->ops->controls[i]), memcpy(qc, &(icd->ops->controls[i]),
...@@ -656,6 +666,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv, ...@@ -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_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd; struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
int ret;
WARN_ON(priv != file->private_data); WARN_ON(priv != file->private_data);
...@@ -672,6 +683,12 @@ static int soc_camera_g_ctrl(struct file *file, void *priv, ...@@ -672,6 +683,12 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
return 0; 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); 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, ...@@ -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_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd; struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
int ret;
WARN_ON(priv != file->private_data); 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); return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl);
} }
......
...@@ -83,7 +83,11 @@ struct soc_camera_host_ops { ...@@ -83,7 +83,11 @@ struct soc_camera_host_ops {
int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *);
int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
int (*set_bus_param)(struct soc_camera_device *, __u32); 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 *); unsigned int (*poll)(struct file *, poll_table *);
const struct v4l2_queryctrl *controls;
int num_controls;
}; };
#define SOCAM_SENSOR_INVERT_PCLK (1 << 0) #define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment