[RFCv4 20/21] media: vivid: add request support for the video capture device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Allow to use requests with the video capture device.

Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxxxx>
---
 drivers/media/platform/vivid/Kconfig          |  1 +
 drivers/media/platform/vivid/vivid-core.c     | 63 ++++++++++++++++++-
 drivers/media/platform/vivid/vivid-core.h     |  3 +
 .../media/platform/vivid/vivid-kthread-cap.c  | 17 +++++
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index 154de92dd809..a6494dabae95 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -7,6 +7,7 @@ config VIDEO_VIVID
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select MEDIA_REQUEST_API
 	select VIDEOBUF2_VMALLOC
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEO_V4L2_TPG
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index 82ec216f2ad8..c1cf8e7ca2c9 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -23,6 +23,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
+#include <media/v4l2-request.h>
 
 #include "vivid-core.h"
 #include "vivid-vid-common.h"
@@ -486,6 +487,33 @@ static const struct v4l2_file_operations vivid_fops = {
 	.mmap           = vb2_fop_mmap,
 };
 
+static int vivid_cap_open(struct file *filp)
+{
+	struct vivid_dev *dev;
+	struct v4l2_fh *fh;
+	int ret;
+
+	ret = v4l2_fh_open(filp);
+	if (ret)
+		return ret;
+
+	dev = container_of(video_devdata(filp), struct vivid_dev, vid_cap_dev);
+	fh = filp->private_data;
+	fh->entity = &dev->vid_cap_req_entity.base;
+
+	return ret;
+}
+
+static const struct v4l2_file_operations vivid_cap_fops = {
+	.owner		= THIS_MODULE,
+	.open           = vivid_cap_open,
+	.release        = vivid_fop_release,
+	.read           = vb2_fop_read,
+	.write          = vb2_fop_write,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap           = vb2_fop_mmap,
+};
 static const struct v4l2_file_operations vivid_radio_fops = {
 	.owner		= THIS_MODULE,
 	.open           = v4l2_fh_open,
@@ -607,6 +635,31 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 };
 
+struct media_request_entity_data *
+vid_cap_entity_data_alloc(struct media_request *req,
+			struct media_request_entity *entity)
+{
+	struct vivid_dev *dev;
+
+	dev = container_of(entity, struct vivid_dev, vid_cap_req_entity.base);
+	return v4l2_request_entity_data_alloc(req, &dev->ctrl_hdl_vid_cap);
+}
+
+static int vid_cap_request_submit(struct media_request *req,
+				struct media_request_entity_data *_data)
+{
+	struct v4l2_request_entity_data *data;
+
+	data = to_v4l2_entity_data(_data);
+	return vb2_request_submit(data);
+}
+
+static const struct media_request_entity_ops vivid_request_entity_ops = {
+	.data_alloc	= vid_cap_entity_data_alloc,
+	.data_free	= v4l2_request_entity_data_free,
+	.submit		= vid_cap_request_submit,
+};
+
 /* -----------------------------------------------------------------
 	Initialization and module stuff
    ------------------------------------------------------------------*/
@@ -1057,6 +1110,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 		q->mem_ops = vivid_mem_ops[allocator];
 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 		q->min_buffers_needed = 2;
+		q->allow_requests = true;
 		q->lock = &dev->mutex;
 		q->dev = dev->v4l2_dev.dev;
 
@@ -1158,13 +1212,19 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 		vfd = &dev->vid_cap_dev;
 		snprintf(vfd->name, sizeof(vfd->name),
 			 "vivid-%03d-vid-cap", inst);
-		vfd->fops = &vivid_fops;
+		vfd->fops = &vivid_cap_fops;
 		vfd->ioctl_ops = &vivid_ioctl_ops;
 		vfd->device_caps = dev->vid_cap_caps;
 		vfd->release = video_device_release_empty;
 		vfd->v4l2_dev = &dev->v4l2_dev;
 		vfd->queue = &dev->vb_vid_cap_q;
 		vfd->tvnorms = tvnorms_cap;
+		vfd->req_mgr = &dev->vid_cap_req_mgr.base;
+		v4l2_request_mgr_init(&dev->vid_cap_req_mgr, vfd,
+				      &v4l2_request_ops);
+		v4l2_request_entity_init(&dev->vid_cap_req_entity,
+					 &vivid_request_entity_ops,
+					 vfd);
 
 		/*
 		 * Provide a mutex to v4l2 core. It will be used to protect
@@ -1448,6 +1508,7 @@ static int vivid_remove(struct platform_device *pdev)
 			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
 				video_device_node_name(&dev->vid_cap_dev));
 			video_unregister_device(&dev->vid_cap_dev);
+			v4l2_request_mgr_free(&dev->vid_cap_req_mgr);
 		}
 		if (dev->has_vid_out) {
 			v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 477c80a4d44c..c8adcbb1c1d1 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -11,6 +11,7 @@
 #include <linux/fb.h>
 #include <linux/workqueue.h>
 #include <media/cec.h>
+#include <media/v4l2-request.h>
 #include <media/videobuf2-v4l2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-dev.h>
@@ -145,6 +146,8 @@ struct vivid_dev {
 	struct v4l2_ctrl_handler	ctrl_hdl_fb;
 	struct video_device		vid_cap_dev;
 	struct v4l2_ctrl_handler	ctrl_hdl_vid_cap;
+	struct v4l2_request_mgr		vid_cap_req_mgr;
+	struct v4l2_request_entity	vid_cap_req_entity;
 	struct video_device		vid_out_dev;
 	struct v4l2_ctrl_handler	ctrl_hdl_vid_out;
 	struct video_device		vbi_cap_dev;
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 3fdb280c36ca..0d0866dc11b3 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -19,6 +19,7 @@
 #include <linux/random.h>
 #include <linux/v4l2-dv-timings.h>
 #include <asm/div64.h>
+#include <media/media-request.h>
 #include <media/videobuf2-vmalloc.h>
 #include <media/v4l2-dv-timings.h>
 #include <media/v4l2-ioctl.h>
@@ -703,6 +704,17 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
 		goto update_mv;
 
 	if (vid_cap_buf) {
+		struct media_request *req = vid_cap_buf->vb.vb2_buf.request;
+
+		/* Using request? Apply its controls */
+		if (req) {
+			struct v4l2_request_entity_data *data;
+			data = to_v4l2_entity_data(
+				media_request_get_entity_data(req,
+						&dev->vid_cap_req_entity.base));
+			if (!WARN_ON(IS_ERR(data)))
+				v4l2_ctrl_request_setup(&data->ctrls);
+		}
 		/* Fill buffer */
 		vivid_fillbuff(dev, vid_cap_buf);
 		dprintk(dev, 1, "filled buffer %d\n",
@@ -717,6 +729,11 @@ static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
 				VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
 		dprintk(dev, 2, "vid_cap buffer %d done\n",
 				vid_cap_buf->vb.vb2_buf.index);
+		if (req)
+			media_request_entity_complete(req,
+						 &dev->vid_cap_req_entity.base);
+		dprintk(dev, 2, "vid_cap buffer %d request completed\n",
+				vid_cap_buf->vb.vb2_buf.index);
 	}
 
 	if (vbi_cap_buf) {
-- 
2.16.1.291.g4437f3f132-goog




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux