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>
This commit is contained in:
parent
a813d01f82
commit
2840d2497b
2 changed files with 28 additions and 0 deletions
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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 {
|
||||||
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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue