|
|
|
@ -92,8 +92,7 @@ EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
|
|
|
|
|
static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_format *f)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
@ -105,8 +104,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_enum_input(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_input *inp)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (inp->index != 0)
|
|
|
|
@ -141,8 +139,7 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
|
|
|
|
|
|
|
|
|
|
static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
|
|
|
|
|
return v4l2_subdev_call(sd, core, s_std, *a);
|
|
|
|
@ -152,47 +149,59 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_requestbuffers *p)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
|
|
|
|
|
|
ret = videobuf_reqbufs(&icf->vb_vidq, p);
|
|
|
|
|
if (icd->streamer && icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
ret = videobuf_reqbufs(&icd->vb_vidq, p);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
return ici->ops->reqbufs(icf, p);
|
|
|
|
|
ret = ici->ops->reqbufs(icd, p);
|
|
|
|
|
if (!ret && !icd->streamer)
|
|
|
|
|
icd->streamer = file;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int soc_camera_querybuf(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_buffer *p)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
|
|
|
|
|
|
return videobuf_querybuf(&icf->vb_vidq, p);
|
|
|
|
|
return videobuf_querybuf(&icd->vb_vidq, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int soc_camera_qbuf(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_buffer *p)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
|
|
|
|
|
|
return videobuf_qbuf(&icf->vb_vidq, p);
|
|
|
|
|
if (icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
return videobuf_qbuf(&icd->vb_vidq, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int soc_camera_dqbuf(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_buffer *p)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
|
|
|
|
|
|
return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
|
|
|
|
|
if (icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Always entered with .video_lock held */
|
|
|
|
@ -280,10 +289,9 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
|
|
|
|
|
((x) >> 24) & 0xff
|
|
|
|
|
|
|
|
|
|
/* Called with .vb_lock held, or from the first open(2), see comment there */
|
|
|
|
|
static int soc_camera_set_fmt(struct soc_camera_file *icf,
|
|
|
|
|
static int soc_camera_set_fmt(struct soc_camera_device *icd,
|
|
|
|
|
struct v4l2_format *f)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
struct v4l2_pix_format *pix = &f->fmt.pix;
|
|
|
|
|
int ret;
|
|
|
|
@ -309,7 +317,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
|
|
|
|
|
icd->user_width = pix->width;
|
|
|
|
|
icd->user_height = pix->height;
|
|
|
|
|
icd->colorspace = pix->colorspace;
|
|
|
|
|
icf->vb_vidq.field =
|
|
|
|
|
icd->vb_vidq.field =
|
|
|
|
|
icd->field = pix->field;
|
|
|
|
|
|
|
|
|
|
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
@ -331,7 +339,6 @@ static int soc_camera_open(struct file *file)
|
|
|
|
|
dev);
|
|
|
|
|
struct soc_camera_link *icl = to_soc_camera_link(icd);
|
|
|
|
|
struct soc_camera_host *ici;
|
|
|
|
|
struct soc_camera_file *icf;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!icd->ops)
|
|
|
|
@ -340,14 +347,9 @@ static int soc_camera_open(struct file *file)
|
|
|
|
|
|
|
|
|
|
ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
icf = vmalloc(sizeof(*icf));
|
|
|
|
|
if (!icf)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
if (!try_module_get(ici->ops->owner)) {
|
|
|
|
|
dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto emgi;
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -356,7 +358,6 @@ static int soc_camera_open(struct file *file)
|
|
|
|
|
*/
|
|
|
|
|
mutex_lock(&icd->video_lock);
|
|
|
|
|
|
|
|
|
|
icf->icd = icd;
|
|
|
|
|
icd->use_count++;
|
|
|
|
|
|
|
|
|
|
/* Now we really have to activate the camera */
|
|
|
|
@ -401,15 +402,15 @@ static int soc_camera_open(struct file *file)
|
|
|
|
|
* apart from someone else calling open() simultaneously, but
|
|
|
|
|
* .video_lock is protecting us against it.
|
|
|
|
|
*/
|
|
|
|
|
ret = soc_camera_set_fmt(icf, &f);
|
|
|
|
|
ret = soc_camera_set_fmt(icd, &f);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
goto esfmt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file->private_data = icf;
|
|
|
|
|
file->private_data = icd;
|
|
|
|
|
dev_dbg(&icd->dev, "camera device open\n");
|
|
|
|
|
|
|
|
|
|
ici->ops->init_videobuf(&icf->vb_vidq, icd);
|
|
|
|
|
ici->ops->init_videobuf(&icd->vb_vidq, icd);
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&icd->video_lock);
|
|
|
|
|
|
|
|
|
@ -430,15 +431,13 @@ epower:
|
|
|
|
|
icd->use_count--;
|
|
|
|
|
mutex_unlock(&icd->video_lock);
|
|
|
|
|
module_put(ici->ops->owner);
|
|
|
|
|
emgi:
|
|
|
|
|
vfree(icf);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int soc_camera_close(struct file *file)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
mutex_lock(&icd->video_lock);
|
|
|
|
@ -455,12 +454,13 @@ static int soc_camera_close(struct file *file)
|
|
|
|
|
icl->power(icd->pdev, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (icd->streamer == file)
|
|
|
|
|
icd->streamer = NULL;
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&icd->video_lock);
|
|
|
|
|
|
|
|
|
|
module_put(ici->ops->owner);
|
|
|
|
|
|
|
|
|
|
vfree(icf);
|
|
|
|
|
|
|
|
|
|
dev_dbg(&icd->dev, "camera device close\n");
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
@ -469,8 +469,7 @@ static int soc_camera_close(struct file *file)
|
|
|
|
|
static ssize_t soc_camera_read(struct file *file, char __user *buf,
|
|
|
|
|
size_t count, loff_t *ppos)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
int err = -EINVAL;
|
|
|
|
|
|
|
|
|
|
dev_err(&icd->dev, "camera device read not implemented\n");
|
|
|
|
@ -480,13 +479,15 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
|
|
|
|
|
|
|
|
|
|
static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
|
|
|
|
|
|
|
|
|
|
err = videobuf_mmap_mapper(&icf->vb_vidq, vma);
|
|
|
|
|
if (icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
|
|
|
|
|
|
|
|
|
|
dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
|
|
|
|
|
(unsigned long)vma->vm_start,
|
|
|
|
@ -498,11 +499,13 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
|
|
|
|
|
|
|
|
|
|
static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
if (list_empty(&icf->vb_vidq.stream)) {
|
|
|
|
|
if (icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
if (list_empty(&icd->vb_vidq.stream)) {
|
|
|
|
|
dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
|
|
|
|
|
return POLLERR;
|
|
|
|
|
}
|
|
|
|
@ -523,24 +526,29 @@ static struct v4l2_file_operations soc_camera_fops = {
|
|
|
|
|
static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_format *f)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
|
|
|
|
|
|
mutex_lock(&icf->vb_vidq.vb_lock);
|
|
|
|
|
if (icd->streamer && icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
if (icf->vb_vidq.bufs[0]) {
|
|
|
|
|
mutex_lock(&icd->vb_vidq.vb_lock);
|
|
|
|
|
|
|
|
|
|
if (icd->vb_vidq.bufs[0]) {
|
|
|
|
|
dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
|
|
|
|
|
ret = -EBUSY;
|
|
|
|
|
goto unlock;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = soc_camera_set_fmt(icf, f);
|
|
|
|
|
ret = soc_camera_set_fmt(icd, f);
|
|
|
|
|
|
|
|
|
|
if (!ret && !icd->streamer)
|
|
|
|
|
icd->streamer = file;
|
|
|
|
|
|
|
|
|
|
unlock:
|
|
|
|
|
mutex_unlock(&icf->vb_vidq.vb_lock);
|
|
|
|
|
mutex_unlock(&icd->vb_vidq.vb_lock);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
@ -548,8 +556,7 @@ unlock:
|
|
|
|
|
static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_fmtdesc *f)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
const struct soc_mbus_pixelfmt *format;
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
@ -568,15 +575,14 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_format *f)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_pix_format *pix = &f->fmt.pix;
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
|
|
|
|
|
|
pix->width = icd->user_width;
|
|
|
|
|
pix->height = icd->user_height;
|
|
|
|
|
pix->field = icf->vb_vidq.field;
|
|
|
|
|
pix->field = icd->vb_vidq.field;
|
|
|
|
|
pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
|
|
|
|
|
pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
|
|
|
|
|
icd->current_fmt->host_fmt);
|
|
|
|
@ -592,8 +598,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_querycap(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_capability *cap)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
@ -605,8 +610,7 @@ static int soc_camera_querycap(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_streamon(struct file *file, void *priv,
|
|
|
|
|
enum v4l2_buf_type i)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
@ -615,12 +619,15 @@ static int soc_camera_streamon(struct file *file, void *priv,
|
|
|
|
|
if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
mutex_lock(&icd->video_lock);
|
|
|
|
|
|
|
|
|
|
v4l2_subdev_call(sd, video, s_stream, 1);
|
|
|
|
|
|
|
|
|
|
/* This calls buf_queue from host driver's videobuf_queue_ops */
|
|
|
|
|
ret = videobuf_streamon(&icf->vb_vidq);
|
|
|
|
|
ret = videobuf_streamon(&icd->vb_vidq);
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&icd->video_lock);
|
|
|
|
|
|
|
|
|
@ -630,8 +637,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_streamoff(struct file *file, void *priv,
|
|
|
|
|
enum v4l2_buf_type i)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
|
|
|
|
|
WARN_ON(priv != file->private_data);
|
|
|
|
@ -639,13 +645,16 @@ static int soc_camera_streamoff(struct file *file, void *priv,
|
|
|
|
|
if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (icd->streamer != file)
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
|
|
|
|
|
mutex_lock(&icd->video_lock);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This calls buf_release from host driver's videobuf_queue_ops for all
|
|
|
|
|
* remaining buffers. When the last buffer is freed, stop capture
|
|
|
|
|
*/
|
|
|
|
|
videobuf_streamoff(&icf->vb_vidq);
|
|
|
|
|
videobuf_streamoff(&icd->vb_vidq);
|
|
|
|
|
|
|
|
|
|
v4l2_subdev_call(sd, video, s_stream, 0);
|
|
|
|
|
|
|
|
|
@ -657,8 +666,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_queryctrl(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_queryctrl *qc)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
@ -689,8 +697,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_g_ctrl(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_control *ctrl)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
int ret;
|
|
|
|
@ -709,8 +716,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_s_ctrl(struct file *file, void *priv,
|
|
|
|
|
struct v4l2_control *ctrl)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
int ret;
|
|
|
|
@ -729,8 +735,7 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
|
|
|
|
|
static int soc_camera_cropcap(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_cropcap *a)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
return ici->ops->cropcap(icd, a);
|
|
|
|
@ -739,14 +744,13 @@ static int soc_camera_cropcap(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_g_crop(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_crop *a)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
mutex_lock(&icf->vb_vidq.vb_lock);
|
|
|
|
|
mutex_lock(&icd->vb_vidq.vb_lock);
|
|
|
|
|
ret = ici->ops->get_crop(icd, a);
|
|
|
|
|
mutex_unlock(&icf->vb_vidq.vb_lock);
|
|
|
|
|
mutex_unlock(&icd->vb_vidq.vb_lock);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
@ -759,8 +763,7 @@ static int soc_camera_g_crop(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_s_crop(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_crop *a)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
struct v4l2_rect *rect = &a->c;
|
|
|
|
|
struct v4l2_crop current_crop;
|
|
|
|
@ -773,7 +776,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
|
|
|
|
|
rect->width, rect->height, rect->left, rect->top);
|
|
|
|
|
|
|
|
|
|
/* Cropping is allowed during a running capture, guard consistency */
|
|
|
|
|
mutex_lock(&icf->vb_vidq.vb_lock);
|
|
|
|
|
mutex_lock(&icd->vb_vidq.vb_lock);
|
|
|
|
|
|
|
|
|
|
/* If get_crop fails, we'll let host and / or client drivers decide */
|
|
|
|
|
ret = ici->ops->get_crop(icd, ¤t_crop);
|
|
|
|
@ -782,7 +785,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
dev_err(&icd->dev,
|
|
|
|
|
"S_CROP denied: getting current crop failed\n");
|
|
|
|
|
} else if (icf->vb_vidq.bufs[0] &&
|
|
|
|
|
} else if (icd->vb_vidq.bufs[0] &&
|
|
|
|
|
(a->c.width != current_crop.c.width ||
|
|
|
|
|
a->c.height != current_crop.c.height)) {
|
|
|
|
|
dev_err(&icd->dev,
|
|
|
|
@ -792,7 +795,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
|
|
|
|
|
ret = ici->ops->set_crop(icd, a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mutex_unlock(&icf->vb_vidq.vb_lock);
|
|
|
|
|
mutex_unlock(&icd->vb_vidq.vb_lock);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
@ -800,8 +803,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_g_parm(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_streamparm *a)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
if (ici->ops->get_parm)
|
|
|
|
@ -813,8 +815,7 @@ static int soc_camera_g_parm(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_s_parm(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_streamparm *a)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
|
|
|
|
|
|
|
|
|
|
if (ici->ops->set_parm)
|
|
|
|
@ -826,8 +827,7 @@ static int soc_camera_s_parm(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_g_chip_ident(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_dbg_chip_ident *id)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
|
|
|
|
|
return v4l2_subdev_call(sd, core, g_chip_ident, id);
|
|
|
|
@ -837,8 +837,7 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_g_register(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_dbg_register *reg)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
|
|
|
|
|
return v4l2_subdev_call(sd, core, g_register, reg);
|
|
|
|
@ -847,8 +846,7 @@ static int soc_camera_g_register(struct file *file, void *fh,
|
|
|
|
|
static int soc_camera_s_register(struct file *file, void *fh,
|
|
|
|
|
struct v4l2_dbg_register *reg)
|
|
|
|
|
{
|
|
|
|
|
struct soc_camera_file *icf = file->private_data;
|
|
|
|
|
struct soc_camera_device *icd = icf->icd;
|
|
|
|
|
struct soc_camera_device *icd = file->private_data;
|
|
|
|
|
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
|
|
|
|
|
|
|
|
|
return v4l2_subdev_call(sd, core, s_register, reg);
|
|
|
|
|