From 1fea3d6069ae446e084177430f66c11cd4fc8751 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 20 Jul 2015 10:09:28 -0300 Subject: [media] fsl-viu: convert to the control framework Interestingly enough, the existing control handling code basically did nothing. At least the new code will inherit the controls from the saa7115 driver. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 110 +++++---------------------------------- 1 file changed, 14 insertions(+), 96 deletions(-) (limited to 'drivers/media/platform/fsl-viu.c') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 5b76e3db6a92..f0ec55134b45 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #define DRV_NAME "fsl_viu" @@ -40,49 +41,6 @@ /* I2C address of video decoder chip is 0x4A */ #define VIU_VIDEO_DECODER_ADDR 0x25 -/* supported controls */ -static struct v4l2_queryctrl viu_qctrl[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 127, - .flags = 0, - }, { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - }, { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 127, - .flags = 0, - }, { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -128, - .maximum = 127, - .step = 0x1, - .default_value = 0, - .flags = 0, - } -}; - -static int qctl_regs[ARRAY_SIZE(viu_qctrl)]; - static int info_level; #define dprintk(level, fmt, arg...) \ @@ -156,6 +114,7 @@ struct viu_reg { struct viu_dev { struct v4l2_device v4l2_dev; + struct v4l2_ctrl_handler hdl; struct mutex lock; spinlock_t slock; int users; @@ -1009,51 +968,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -/* Controls */ -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) { - if (qc->id && qc->id == viu_qctrl[i].id) { - memcpy(qc, &(viu_qctrl[i]), sizeof(*qc)); - return 0; - } - } - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) { - if (ctrl->id == viu_qctrl[i].id) { - ctrl->value = qctl_regs[i]; - return 0; - } - } - return -EINVAL; -} -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) { - if (ctrl->id == viu_qctrl[i].id) { - if (ctrl->value < viu_qctrl[i].minimum - || ctrl->value > viu_qctrl[i].maximum) - return -ERANGE; - qctl_regs[i] = ctrl->value; - return 0; - } - } - return -EINVAL; -} - inline void viu_activate_next_buf(struct viu_dev *dev, struct viu_dmaqueue *viuq) { @@ -1265,7 +1179,6 @@ static int viu_open(struct file *file) struct viu_reg *vr; int minor = vdev->minor; u32 status_cfg; - int i; dprintk(1, "viu: open (minor=%d)\n", minor); @@ -1303,10 +1216,6 @@ static int viu_open(struct file *file) dev->crop_current.width = fh->width; dev->crop_current.height = fh->height; - /* Put all controls at a sane state */ - for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) - qctl_regs[i] = viu_qctrl[i].default_value; - dprintk(1, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n", (unsigned long)fh, (unsigned long)dev, (unsigned long)&dev->vidq); @@ -1463,9 +1372,6 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = { .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, }; @@ -1543,6 +1449,16 @@ static int viu_of_probe(struct platform_device *op) } ad = i2c_get_adapter(0); + + v4l2_ctrl_handler_init(&viu_dev->hdl, 5); + if (viu_dev->hdl.error) { + ret = viu_dev->hdl.error; + dev_err(&op->dev, "couldn't register control\n"); + goto err_vdev; + } + /* This control handler will inherit the control(s) from the + sub-device(s). */ + viu_dev->v4l2_dev.ctrl_handler = &viu_dev->hdl; viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL); @@ -1614,6 +1530,7 @@ err_irq: err_clk: video_unregister_device(viu_dev->vdev); err_vdev: + v4l2_ctrl_handler_free(&viu_dev->hdl); mutex_unlock(&viu_dev->lock); i2c_put_adapter(ad); v4l2_device_unregister(&viu_dev->v4l2_dev); @@ -1635,6 +1552,7 @@ static int viu_of_remove(struct platform_device *op) clk_disable_unprepare(dev->clk); + v4l2_ctrl_handler_free(&dev->hdl); video_unregister_device(dev->vdev); i2c_put_adapter(client->adapter); v4l2_device_unregister(&dev->v4l2_dev); -- cgit v1.2.3 From 282b3fb831d64b38cac67a912d99ca3dd547aac9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 20 Jul 2015 10:09:29 -0300 Subject: [media] fsl-viu: fill in bus_info in vidioc_querycap The bus_info field was never filled. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/platform/fsl-viu.c') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index f0ec55134b45..ab8012c7635e 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -563,6 +563,7 @@ static int vidioc_querycap(struct file *file, void *priv, { strcpy(cap->driver, "viu"); strcpy(cap->card, "viu"); + strcpy(cap->bus_info, "platform:viu"); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OVERLAY | -- cgit v1.2.3 From e299bc99bfa7188d3b52c9aed28e0882f5abd137 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 20 Jul 2015 10:09:30 -0300 Subject: [media] fsl-viu: fill in colorspace, always set field to interlaced - fill in the missing colorspace value. - don't reject incorrect field values, always replace with a valid value. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/media/platform/fsl-viu.c') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index ab8012c7635e..7d0e360e58f1 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -597,6 +597,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3; f->fmt.pix.sizeimage = fh->sizeimage; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } @@ -604,7 +605,6 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { struct viu_fmt *fmt; - enum v4l2_field field; unsigned int maxw, maxh; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -614,19 +614,10 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, return -EINVAL; } - field = f->fmt.pix.field; - - if (field == V4L2_FIELD_ANY) { - field = V4L2_FIELD_INTERLACED; - } else if (field != V4L2_FIELD_INTERLACED) { - dprintk(1, "Field type invalid.\n"); - return -EINVAL; - } - maxw = norm_maxw(); maxh = norm_maxh(); - f->fmt.pix.field = field; + f->fmt.pix.field = V4L2_FIELD_INTERLACED; if (f->fmt.pix.height < 32) f->fmt.pix.height = 32; if (f->fmt.pix.height > maxh) @@ -638,6 +629,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } -- cgit v1.2.3 From 7fe0b3d7c721ddb5a37e868ad27c2476b4042a54 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 20 Jul 2015 10:09:31 -0300 Subject: [media] fsl-viu: add control event support Convert the driver to use v4l2_fh in order to support control events. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers/media/platform/fsl-viu.c') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 7d0e360e58f1..906442ecd518 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #define DRV_NAME "fsl_viu" @@ -154,6 +156,8 @@ struct viu_dev { }; struct viu_fh { + /* must remain the first field of this struct */ + struct v4l2_fh fh; struct viu_dev *dev; /* video capture */ @@ -1199,6 +1203,7 @@ static int viu_open(struct file *file) return -ENOMEM; } + v4l2_fh_init(&fh->fh, vdev); file->private_data = fh; fh->dev = dev; @@ -1234,6 +1239,7 @@ static int viu_open(struct file *file) fh->type, V4L2_FIELD_INTERLACED, sizeof(struct viu_buf), fh, &fh->dev->lock); + v4l2_fh_add(&fh->fh); mutex_unlock(&dev->lock); return 0; } @@ -1266,13 +1272,17 @@ static unsigned int viu_poll(struct file *file, struct poll_table_struct *wait) struct viu_fh *fh = file->private_data; struct videobuf_queue *q = &fh->vb_vidq; struct viu_dev *dev = fh->dev; - unsigned int res; + unsigned long req_events = poll_requested_events(wait); + unsigned int res = v4l2_ctrl_poll(file, wait); if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) return POLLERR; + if (!(req_events & (POLLIN | POLLRDNORM))) + return res; + mutex_lock(&dev->lock); - res = videobuf_poll_stream(file, q, wait); + res |= videobuf_poll_stream(file, q, wait); mutex_unlock(&dev->lock); return res; } @@ -1287,6 +1297,8 @@ static int viu_release(struct file *file) viu_stop_dma(dev); videobuf_stop(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vidq); + v4l2_fh_del(&fh->fh); + v4l2_fh_exit(&fh->fh); mutex_unlock(&dev->lock); kfree(fh); @@ -1367,6 +1379,9 @@ static const struct v4l2_ioctl_ops viu_ioctl_ops = { .vidioc_s_input = vidioc_s_input, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device viu_template = { @@ -1468,7 +1483,7 @@ static int viu_of_probe(struct platform_device *op) goto err_vdev; } - memcpy(vdev, &viu_template, sizeof(viu_template)); + *vdev = viu_template; vdev->v4l2_dev = &viu_dev->v4l2_dev; -- cgit v1.2.3 From 9acc8093282456f920f7d3e34b0b1b58c3f07dbd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 20 Jul 2015 10:09:32 -0300 Subject: [media] fsl-viu: small fixes - Fix an off-by-one index check in vidioc_enum_fmt() - Fill in the pix.sizeimage field in vidioc_try_fmt_cap() - Fix an off-by-one index check in vidioc_s_input() Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media/platform/fsl-viu.c') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 906442ecd518..69ee2b6c2ffc 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -581,7 +581,7 @@ static int vidioc_enum_fmt(struct file *file, void *priv, { int index = f->index; - if (f->index > NUM_FORMATS) + if (f->index >= NUM_FORMATS) return -EINVAL; strlcpy(f->description, formats[index].name, sizeof(f->description)); @@ -633,6 +633,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, f->fmt.pix.width &= ~0x03; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; @@ -958,7 +959,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct viu_fh *fh = priv; - if (i > 1) + if (i) return -EINVAL; decoder_call(fh->dev, video, s_routing, i, 0, 0); -- cgit v1.2.3 From 0a6b9b04dbe81d781720e077aea147805af0ee87 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 20 Jul 2015 10:09:33 -0300 Subject: [media] fsl-viu: drop format names The names of the pixelformats is set by the core. So there no longer is any need for drivers to fill it in. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/fsl-viu.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/media/platform/fsl-viu.c') diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 69ee2b6c2ffc..ae8c6b35a357 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -55,7 +55,6 @@ static int info_level; * Basic structures */ struct viu_fmt { - char name[32]; u32 fourcc; /* v4l2 format id */ u32 pixelformat; int depth; @@ -63,12 +62,10 @@ struct viu_fmt { static struct viu_fmt formats[] = { { - .name = "RGB-16 (5/B-6/G-5/R)", .fourcc = V4L2_PIX_FMT_RGB565, .pixelformat = V4L2_PIX_FMT_RGB565, .depth = 16, }, { - .name = "RGB-32 (A-R-G-B)", .fourcc = V4L2_PIX_FMT_RGB32, .pixelformat = V4L2_PIX_FMT_RGB32, .depth = 32, @@ -584,7 +581,6 @@ static int vidioc_enum_fmt(struct file *file, void *priv, if (f->index >= NUM_FORMATS) return -EINVAL; - strlcpy(f->description, formats[index].name, sizeof(f->description)); f->pixelformat = formats[index].fourcc; return 0; } @@ -655,7 +651,6 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, fh->sizeimage = f->fmt.pix.sizeimage; fh->vb_vidq.field = f->fmt.pix.field; fh->type = f->type; - dprintk(1, "set to pixelformat '%4.6s'\n", (char *)&fh->fmt->name); return 0; } @@ -721,8 +716,8 @@ static int viu_setup_preview(struct viu_dev *dev, struct viu_fh *fh) { int bpp; - dprintk(1, "%s %dx%d %s\n", __func__, - fh->win.w.width, fh->win.w.height, dev->ovfmt->name); + dprintk(1, "%s %dx%d\n", __func__, + fh->win.w.width, fh->win.w.height); reg_val.status_cfg = 0; -- cgit v1.2.3