mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Steve Longerbeam <slongerbeam@gmail.com>
To: robh+dt@kernel.org, mark.rutland@arm.com, shawnguo@kernel.org,
	kernel@pengutronix.de, fabio.estevam@nxp.com,
	linux@armlinux.org.uk, mchehab@kernel.org, hverkuil@xs4all.nl,
	nick@shmanahar.org, markus.heiser@darmarIT.de,
	p.zabel@pengutronix.de,
	laurent.pinchart+renesas@ideasonboard.com, bparrot@ti.com,
	geert@linux-m68k.org, arnd@arndb.de, sudipm.mukherjee@gmail.com,
	minghsiu.tsai@mediatek.com, tiffany.lin@mediatek.com,
	jean-christophe.trotin@st.com, horms+renesas@verge.net.au,
	niklas.soderlund+renesas@ragnatech.se, robert.jarzmik@free.fr,
	songjun.wu@microchip.com, andrew-ct.chen@mediatek.com,
	gregkh@linuxfoundation.org, shuah@kernel.org,
	sakari.ailus@linux.intel.com, pavel@ucw.cz
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-media@vger.kernel.org, devel@driverdev.osuosl.org,
	Steve Longerbeam <steve_longerbeam@mentor.com>
Subject: [PATCH v5 24/39] media: imx: Add Capture Device Interface
Date: Thu,  9 Mar 2017 20:53:04 -0800	[thread overview]
Message-ID: <1489121599-23206-25-git-send-email-steve_longerbeam@mentor.com> (raw)
In-Reply-To: <1489121599-23206-1-git-send-email-steve_longerbeam@mentor.com>

This is the capture device interface driver that provides the v4l2
user interface. Frames can be received from various sources:

- directly from CSI for capturing unconverted images directly from
  camera sensors.

- from the IC pre-process encode task.

- from the IC pre-process viewfinder task.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 drivers/staging/media/imx/Makefile            |   1 +
 drivers/staging/media/imx/imx-media-capture.c | 655 ++++++++++++++++++++++++++
 2 files changed, 656 insertions(+)
 create mode 100644 drivers/staging/media/imx/imx-media-capture.c

diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
index ddd7d94..4606a3a 100644
--- a/drivers/staging/media/imx/Makefile
+++ b/drivers/staging/media/imx/Makefile
@@ -3,3 +3,4 @@ imx-media-common-objs := imx-media-utils.o imx-media-fim.o
 
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media.o
 obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o
+obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-capture.o
diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c
new file mode 100644
index 0000000..704ed85
--- /dev/null
+++ b/drivers/staging/media/imx/imx-media-capture.c
@@ -0,0 +1,655 @@
+/*
+ * Video Capture Subdev for Freescale i.MX5/6 SOC
+ *
+ * Copyright (c) 2012-2016 Mentor Graphics Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-of.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-dma-contig.h>
+#include <video/imx-ipu-v3.h>
+#include <media/imx.h>
+#include "imx-media.h"
+
+struct capture_priv {
+	struct imx_media_video_dev vdev;
+
+	struct v4l2_subdev    *src_sd;
+	int                   src_sd_pad;
+	struct device         *dev;
+
+	struct media_pipeline mp;
+	struct imx_media_dev  *md;
+
+	struct media_pad      vdev_pad;
+
+	struct mutex          mutex;       /* capture device mutex */
+
+	/* the videobuf2 queue */
+	struct vb2_queue       q;
+	/* list of ready imx_media_buffer's from q */
+	struct list_head       ready_q;
+	/* protect ready_q */
+	spinlock_t             q_lock;
+
+	/* controls inherited from subdevs */
+	struct v4l2_ctrl_handler ctrl_hdlr;
+
+	/* misc status */
+	bool                  stop;          /* streaming is stopping */
+};
+
+#define to_capture_priv(v) container_of(v, struct capture_priv, vdev)
+
+/* In bytes, per queue */
+#define VID_MEM_LIMIT	SZ_64M
+
+static struct vb2_ops capture_qops;
+
+/*
+ * Video ioctls follow
+ */
+
+static int vidioc_querycap(struct file *file, void *fh,
+			   struct v4l2_capability *cap)
+{
+	struct capture_priv *priv = video_drvdata(file);
+
+	strncpy(cap->driver, "imx-media-capture", sizeof(cap->driver) - 1);
+	strncpy(cap->card, "imx-media-capture", sizeof(cap->card) - 1);
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:%s", dev_name(priv->dev));
+
+	return 0;
+}
+
+static int capture_enum_fmt_vid_cap(struct file *file, void *fh,
+				    struct v4l2_fmtdesc *f)
+{
+	u32 fourcc;
+	int ret;
+
+	ret = imx_media_enum_format(&fourcc, NULL, f->index, true, true);
+	if (ret)
+		return ret;
+
+	f->pixelformat = fourcc;
+
+	return 0;
+}
+
+static int capture_g_fmt_vid_cap(struct file *file, void *fh,
+				 struct v4l2_format *f)
+{
+	struct capture_priv *priv = video_drvdata(file);
+
+	*f = priv->vdev.fmt;
+
+	return 0;
+}
+
+static int capture_try_fmt_vid_cap(struct file *file, void *fh,
+				   struct v4l2_format *f)
+{
+	struct capture_priv *priv = video_drvdata(file);
+	struct v4l2_subdev_format fmt_src;
+	const struct imx_media_pixfmt *cc, *src_cc;
+	u32 fourcc;
+	int ret;
+
+	fourcc = f->fmt.pix.pixelformat;
+	cc = imx_media_find_format(fourcc, 0, true, true);
+	if (!cc) {
+		imx_media_enum_format(&fourcc, NULL, 0, true, true);
+		cc = imx_media_find_format(fourcc, 0, true, true);
+	}
+
+	/*
+	 * user frame dimensions are the same as src_sd's pad.
+	 */
+	fmt_src.pad = priv->src_sd_pad;
+	fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
+	if (ret)
+		return ret;
+
+	/*
+	 * but we can allow planar pixel formats if the src_sd's
+	 * pad configured a YUV format
+	 */
+	src_cc = imx_media_find_format(0, fmt_src.format.code, true, false);
+	if (src_cc->cs == IPUV3_COLORSPACE_YUV &&
+	    cc->cs == IPUV3_COLORSPACE_YUV) {
+		imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix,
+					      &fmt_src.format, cc);
+	} else {
+		imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix,
+					      &fmt_src.format, src_cc);
+	}
+
+	return 0;
+}
+
+static int capture_s_fmt_vid_cap(struct file *file, void *fh,
+				 struct v4l2_format *f)
+{
+	struct capture_priv *priv = video_drvdata(file);
+	int ret;
+
+	if (vb2_is_busy(&priv->q)) {
+		v4l2_err(priv->src_sd, "%s queue busy\n", __func__);
+		return -EBUSY;
+	}
+
+	ret = capture_try_fmt_vid_cap(file, priv, f);
+	if (ret)
+		return ret;
+
+	priv->vdev.fmt.fmt.pix = f->fmt.pix;
+	priv->vdev.cc = imx_media_find_format(f->fmt.pix.pixelformat, 0,
+					      true, true);
+
+	return 0;
+}
+
+static int capture_querystd(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct capture_priv *priv = video_drvdata(file);
+
+	return v4l2_subdev_call(priv->src_sd, video, querystd, std);
+}
+
+static int capture_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct capture_priv *priv = video_drvdata(file);
+
+	return v4l2_subdev_call(priv->src_sd, video, g_std, std);
+}
+
+static int capture_s_std(struct file *file, void *fh, v4l2_std_id std)
+{
+	struct capture_priv *priv = video_drvdata(file);
+
+	if (vb2_is_busy(&priv->q))
+		return -EBUSY;
+
+	return v4l2_subdev_call(priv->src_sd, video, s_std, std);
+}
+
+static int capture_g_parm(struct file *file, void *fh,
+			  struct v4l2_streamparm *a)
+{
+	struct capture_priv *priv = video_drvdata(file);
+	struct v4l2_subdev_frame_interval fi;
+	int ret;
+
+	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	memset(&fi, 0, sizeof(fi));
+	fi.pad = priv->src_sd_pad;
+	ret = v4l2_subdev_call(priv->src_sd, video, g_frame_interval, &fi);
+	if (ret < 0)
+		return ret;
+
+	a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	a->parm.capture.timeperframe = fi.interval;
+
+	return 0;
+}
+
+static int capture_s_parm(struct file *file, void *fh,
+			  struct v4l2_streamparm *a)
+{
+	struct capture_priv *priv = video_drvdata(file);
+	struct v4l2_subdev_frame_interval fi;
+	int ret;
+
+	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	memset(&fi, 0, sizeof(fi));
+	fi.pad = priv->src_sd_pad;
+	fi.interval = a->parm.capture.timeperframe;
+	ret = v4l2_subdev_call(priv->src_sd, video, s_frame_interval, &fi);
+	if (ret < 0)
+		return ret;
+
+	a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	a->parm.capture.timeperframe = fi.interval;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops capture_ioctl_ops = {
+	.vidioc_querycap	= vidioc_querycap,
+
+	.vidioc_enum_fmt_vid_cap        = capture_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap           = capture_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap         = capture_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap           = capture_s_fmt_vid_cap,
+
+	.vidioc_querystd        = capture_querystd,
+	.vidioc_g_std           = capture_g_std,
+	.vidioc_s_std           = capture_s_std,
+
+	.vidioc_g_parm          = capture_g_parm,
+	.vidioc_s_parm          = capture_s_parm,
+
+	.vidioc_reqbufs		= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs     = vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf     = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf	= vb2_ioctl_querybuf,
+	.vidioc_qbuf		= vb2_ioctl_qbuf,
+	.vidioc_dqbuf		= vb2_ioctl_dqbuf,
+	.vidioc_expbuf		= vb2_ioctl_expbuf,
+	.vidioc_streamon	= vb2_ioctl_streamon,
+	.vidioc_streamoff	= vb2_ioctl_streamoff,
+};
+
+/*
+ * Queue operations
+ */
+
+static int capture_queue_setup(struct vb2_queue *vq,
+			       unsigned int *nbuffers,
+			       unsigned int *nplanes,
+			       unsigned int sizes[],
+			       struct device *alloc_devs[])
+{
+	struct capture_priv *priv = vb2_get_drv_priv(vq);
+	struct v4l2_pix_format *pix = &priv->vdev.fmt.fmt.pix;
+	unsigned int count = *nbuffers;
+
+	if (vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	if (*nplanes) {
+		if (*nplanes != 1 || sizes[0] < pix->sizeimage)
+			return -EINVAL;
+		count += vq->num_buffers;
+	}
+
+	count = min_t(__u32, VID_MEM_LIMIT / pix->sizeimage, count);
+
+	if (*nplanes)
+		*nbuffers = (count < vq->num_buffers) ? 0 :
+			count - vq->num_buffers;
+	else
+		*nbuffers = count;
+
+	*nplanes = 1;
+	sizes[0] = pix->sizeimage;
+
+	return 0;
+}
+
+static int capture_buf_init(struct vb2_buffer *vb)
+{
+	struct imx_media_buffer *buf = to_imx_media_vb(vb);
+
+	INIT_LIST_HEAD(&buf->list);
+
+	return 0;
+}
+
+static int capture_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vb2_queue *vq = vb->vb2_queue;
+	struct capture_priv *priv = vb2_get_drv_priv(vq);
+	struct v4l2_pix_format *pix = &priv->vdev.fmt.fmt.pix;
+
+	if (vb2_plane_size(vb, 0) < pix->sizeimage) {
+		v4l2_err(priv->src_sd,
+			 "data will not fit into plane (%lu < %lu)\n",
+			 vb2_plane_size(vb, 0), (long)pix->sizeimage);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, pix->sizeimage);
+
+	return 0;
+}
+
+static void capture_buf_queue(struct vb2_buffer *vb)
+{
+	struct capture_priv *priv = vb2_get_drv_priv(vb->vb2_queue);
+	struct imx_media_buffer *buf = to_imx_media_vb(vb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->q_lock, flags);
+
+	list_add_tail(&buf->list, &priv->ready_q);
+
+	spin_unlock_irqrestore(&priv->q_lock, flags);
+}
+
+static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct capture_priv *priv = vb2_get_drv_priv(vq);
+	struct imx_media_buffer *buf, *tmp;
+	unsigned long flags;
+	int ret;
+
+	if (vb2_is_streaming(vq))
+		return 0;
+
+	ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
+					    &priv->mp, true);
+	if (ret) {
+		v4l2_err(priv->src_sd, "pipeline start failed with %d\n", ret);
+		goto return_bufs;
+	}
+
+	priv->stop = false;
+
+	return 0;
+
+return_bufs:
+	spin_lock_irqsave(&priv->q_lock, flags);
+	list_for_each_entry_safe(buf, tmp, &priv->ready_q, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
+	}
+	spin_unlock_irqrestore(&priv->q_lock, flags);
+	return ret;
+}
+
+static void capture_stop_streaming(struct vb2_queue *vq)
+{
+	struct capture_priv *priv = vb2_get_drv_priv(vq);
+	struct imx_media_buffer *frame;
+	unsigned long flags;
+	int ret;
+
+	if (!vb2_is_streaming(vq))
+		return;
+
+	spin_lock_irqsave(&priv->q_lock, flags);
+	priv->stop = true;
+	spin_unlock_irqrestore(&priv->q_lock, flags);
+
+	ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
+					    &priv->mp, false);
+	if (ret)
+		v4l2_warn(priv->src_sd, "pipeline stop failed with %d\n", ret);
+
+	/* release all active buffers */
+	spin_lock_irqsave(&priv->q_lock, flags);
+	while (!list_empty(&priv->ready_q)) {
+		frame = list_entry(priv->ready_q.next,
+				   struct imx_media_buffer, list);
+		list_del(&frame->list);
+		vb2_buffer_done(&frame->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+	spin_unlock_irqrestore(&priv->q_lock, flags);
+}
+
+static struct vb2_ops capture_qops = {
+	.queue_setup	 = capture_queue_setup,
+	.buf_init        = capture_buf_init,
+	.buf_prepare	 = capture_buf_prepare,
+	.buf_queue	 = capture_buf_queue,
+	.wait_prepare	 = vb2_ops_wait_prepare,
+	.wait_finish	 = vb2_ops_wait_finish,
+	.start_streaming = capture_start_streaming,
+	.stop_streaming  = capture_stop_streaming,
+};
+
+/*
+ * File operations
+ */
+static int capture_open(struct file *file)
+{
+	struct capture_priv *priv = video_drvdata(file);
+	int ret;
+
+	if (mutex_lock_interruptible(&priv->mutex))
+		return -ERESTARTSYS;
+
+	ret = v4l2_fh_open(file);
+	if (ret)
+		v4l2_err(priv->src_sd, "v4l2_fh_open failed\n");
+
+	mutex_unlock(&priv->mutex);
+	return ret;
+}
+
+static int capture_release(struct file *file)
+{
+	struct capture_priv *priv = video_drvdata(file);
+	struct vb2_queue *vq = &priv->q;
+	int ret = 0;
+
+	mutex_lock(&priv->mutex);
+
+	if (file->private_data == vq->owner) {
+		vb2_queue_release(vq);
+		vq->owner = NULL;
+	}
+
+	v4l2_fh_release(file);
+	mutex_unlock(&priv->mutex);
+	return ret;
+}
+
+static const struct v4l2_file_operations capture_fops = {
+	.owner		= THIS_MODULE,
+	.open		= capture_open,
+	.release	= capture_release,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl	= video_ioctl2,
+	.mmap		= vb2_fop_mmap,
+};
+
+static struct video_device capture_videodev = {
+	.fops		= &capture_fops,
+	.ioctl_ops	= &capture_ioctl_ops,
+	.minor		= -1,
+	.release	= video_device_release,
+	.vfl_dir	= VFL_DIR_RX,
+	.tvnorms	= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
+	.device_caps	= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
+};
+
+struct imx_media_buffer *
+imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
+{
+	struct capture_priv *priv = to_capture_priv(vdev);
+	struct imx_media_buffer *buf = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->q_lock, flags);
+
+	/* get next queued buffer */
+	if (!list_empty(&priv->ready_q)) {
+		buf = list_entry(priv->ready_q.next, struct imx_media_buffer,
+				 list);
+		list_del(&buf->list);
+	}
+
+	spin_unlock_irqrestore(&priv->q_lock, flags);
+
+	return buf;
+}
+EXPORT_SYMBOL_GPL(imx_media_capture_device_next_buf);
+
+void imx_media_capture_device_error(struct imx_media_video_dev *vdev)
+{
+	struct capture_priv *priv = to_capture_priv(vdev);
+	struct vb2_queue *vq = &priv->q;
+	unsigned long flags;
+
+	if (!vb2_is_streaming(vq))
+		return;
+
+	spin_lock_irqsave(&priv->q_lock, flags);
+	vb2_queue_error(vq);
+	spin_unlock_irqrestore(&priv->q_lock, flags);
+}
+EXPORT_SYMBOL_GPL(imx_media_capture_device_error);
+
+int imx_media_capture_device_register(struct imx_media_video_dev *vdev)
+{
+	struct capture_priv *priv = to_capture_priv(vdev);
+	struct v4l2_subdev *sd = priv->src_sd;
+	struct video_device *vfd = vdev->vfd;
+	struct vb2_queue *vq = &priv->q;
+	struct v4l2_subdev_format fmt_src;
+	int ret;
+
+	/* get media device */
+	priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
+
+	vfd->v4l2_dev = sd->v4l2_dev;
+
+	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+	if (ret) {
+		v4l2_err(sd, "Failed to register video device\n");
+		return ret;
+	}
+
+	vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	vq->drv_priv = priv;
+	vq->buf_struct_size = sizeof(struct imx_media_buffer);
+	vq->ops = &capture_qops;
+	vq->mem_ops = &vb2_dma_contig_memops;
+	vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	vq->lock = &priv->mutex;
+	vq->min_buffers_needed = 2;
+	vq->dev = priv->dev;
+
+	ret = vb2_queue_init(vq);
+	if (ret) {
+		v4l2_err(sd, "vb2_queue_init failed\n");
+		goto unreg;
+	}
+
+	INIT_LIST_HEAD(&priv->ready_q);
+
+	priv->vdev_pad.flags = MEDIA_PAD_FL_SINK;
+	ret = media_entity_pads_init(&vfd->entity, 1, &priv->vdev_pad);
+	if (ret) {
+		v4l2_err(sd, "failed to init dev pad\n");
+		goto unreg;
+	}
+
+	/* create the link from the src_sd devnode pad to device node */
+	ret = media_create_pad_link(&sd->entity, priv->src_sd_pad,
+				    &vfd->entity, 0, 0);
+	if (ret) {
+		v4l2_err(sd, "failed to create link to device node\n");
+		goto unreg;
+	}
+
+	/* setup default format */
+	fmt_src.pad = priv->src_sd_pad;
+	fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt_src);
+	if (ret) {
+		v4l2_err(sd, "failed to get src_sd format\n");
+		goto unreg;
+	}
+
+	vdev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt.fmt.pix,
+				      &fmt_src.format, NULL);
+	vdev->cc = imx_media_find_format(0, fmt_src.format.code,
+					 true, false);
+
+	v4l2_info(sd, "Registered %s as /dev/%s\n", vfd->name,
+		  video_device_node_name(vfd));
+
+	vfd->ctrl_handler = &priv->ctrl_hdlr;
+
+	return 0;
+unreg:
+	video_unregister_device(vfd);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(imx_media_capture_device_register);
+
+void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev)
+{
+	struct capture_priv *priv = to_capture_priv(vdev);
+	struct video_device *vfd = priv->vdev.vfd;
+
+	mutex_lock(&priv->mutex);
+
+	if (video_is_registered(vfd)) {
+		video_unregister_device(vfd);
+		media_entity_cleanup(&vfd->entity);
+	}
+
+	mutex_unlock(&priv->mutex);
+}
+EXPORT_SYMBOL_GPL(imx_media_capture_device_unregister);
+
+struct imx_media_video_dev *
+imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad)
+{
+	struct capture_priv *priv;
+	struct video_device *vfd;
+
+	priv = devm_kzalloc(src_sd->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return ERR_PTR(-ENOMEM);
+
+	priv->src_sd = src_sd;
+	priv->src_sd_pad = pad;
+	priv->dev = src_sd->dev;
+
+	mutex_init(&priv->mutex);
+	spin_lock_init(&priv->q_lock);
+
+	snprintf(capture_videodev.name, sizeof(capture_videodev.name),
+		 "%s capture", src_sd->name);
+
+	vfd = video_device_alloc();
+	if (!vfd)
+		return ERR_PTR(-ENOMEM);
+
+	*vfd = capture_videodev;
+	vfd->lock = &priv->mutex;
+	vfd->queue = &priv->q;
+	priv->vdev.vfd = vfd;
+
+	video_set_drvdata(vfd, priv);
+
+	v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
+
+	return &priv->vdev;
+}
+EXPORT_SYMBOL_GPL(imx_media_capture_device_init);
+
+void imx_media_capture_device_remove(struct imx_media_video_dev *vdev)
+{
+	struct capture_priv *priv = to_capture_priv(vdev);
+
+	v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
+}
+EXPORT_SYMBOL_GPL(imx_media_capture_device_remove);
+
+MODULE_DESCRIPTION("i.MX5/6 v4l2 video capture interface driver");
+MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
+MODULE_LICENSE("GPL");
-- 
2.7.4

  parent reply	other threads:[~2017-03-10  4:54 UTC|newest]

Thread overview: 175+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-10  4:52 [PATCH v5 00/39] i.MX Media Driver Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 01/39] [media] dt-bindings: Add bindings for video-multiplexer device Steve Longerbeam
2017-03-16 21:21   ` Rob Herring
2017-03-10  4:52 ` [PATCH v5 02/39] [media] dt-bindings: Add bindings for i.MX media driver Steve Longerbeam
2017-03-20 15:02   ` Rob Herring
2017-03-10  4:52 ` [PATCH v5 03/39] [media] dt/bindings: Add bindings for OV5640 Steve Longerbeam
2017-03-20 15:03   ` Rob Herring
2017-03-10  4:52 ` [PATCH v5 04/39] ARM: dts: imx6qdl: Add compatible, clocks, irqs to MIPI CSI-2 node Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 05/39] ARM: dts: imx6qdl: Add mipi_ipu1/2 multiplexers, mipi_csi, and their connections Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 06/39] ARM: dts: imx6qdl: add capture-subsystem device Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 07/39] ARM: dts: imx6qdl-sabrelite: remove erratum ERR006687 workaround Steve Longerbeam
2017-03-10 18:59   ` Troy Kisky
2017-03-10 19:17     ` Fabio Estevam
2017-03-10 21:57       ` Pavel Machek
2017-03-10 22:05         ` Fabio Estevam
2017-03-15 18:49       ` Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 08/39] ARM: dts: imx6-sabrelite: add OV5642 and OV5640 camera sensors Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 09/39] ARM: dts: imx6-sabresd: " Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 10/39] ARM: dts: imx6-sabreauto: create i2cmux for i2c3 Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 11/39] ARM: dts: imx6-sabreauto: add reset-gpios property for max7310_b Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 12/39] ARM: dts: imx6-sabreauto: add pinctrl for gpt input capture Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 13/39] ARM: dts: imx6-sabreauto: add the ADV7180 video decoder Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 14/39] add mux and video interface bridge entity functions Steve Longerbeam
2017-03-10  4:52 ` [PATCH v5 15/39] [media] v4l2: add a frame interval error event Steve Longerbeam
2017-03-10 12:03   ` Hans Verkuil
2017-03-10 18:37     ` Steve Longerbeam
2017-03-10 23:30       ` Pavel Machek
2017-03-10 23:42         ` Steve Longerbeam
2017-03-11 11:39       ` Hans Verkuil
2017-03-11 18:14         ` Steve Longerbeam
2017-03-11 18:51           ` Russell King - ARM Linux
2017-03-11 18:58             ` Steve Longerbeam
2017-03-11 19:00             ` Steve Longerbeam
2017-03-13 10:02           ` Hans Verkuil
2017-03-13 10:45             ` Russell King - ARM Linux
2017-03-13 10:53               ` Hans Verkuil
2017-03-13 17:06                 ` Steve Longerbeam
2017-03-13 17:10                   ` Hans Verkuil
2017-03-13 21:47                     ` Steve Longerbeam
2017-03-14 16:21               ` Nicolas Dufresne
2017-03-14 16:43                 ` Steve Longerbeam
2017-03-16 22:15                   ` Sakari Ailus
2017-03-14 16:47                 ` Russell King - ARM Linux
2017-03-14 16:50                   ` Steve Longerbeam
2017-03-14 18:26               ` Pavel Machek
2017-03-10  4:52 ` [PATCH v5 16/39] [media] v4l2: add a new-frame before end-of-frame event Steve Longerbeam
2017-03-10 12:07   ` Hans Verkuil
2017-03-10  4:52 ` [PATCH v5 17/39] [media] v4l2-mc: add a function to inherit controls from a pipeline Steve Longerbeam
2017-03-10 11:45   ` Hans Verkuil
2017-03-10  4:52 ` [PATCH v5 18/39] [media] v4l: subdev: Add function to validate frame interval Steve Longerbeam
2017-03-11 13:41   ` Sakari Ailus
2017-03-11 20:31     ` Steve Longerbeam
2017-03-16 22:17       ` Sakari Ailus
2017-03-10  4:52 ` [PATCH v5 19/39] [media] add Omnivision OV5640 sensor driver Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 20/39] platform: add video-multiplexer subdevice driver Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 21/39] UAPI: Add media UAPI Kbuild file Steve Longerbeam
2017-03-11 13:49   ` Sakari Ailus
2017-03-11 18:20     ` Steve Longerbeam
2017-03-13  9:55       ` Hans Verkuil
2017-03-10  4:53 ` [PATCH v5 22/39] media: Add userspace header file for i.MX Steve Longerbeam
2017-03-10 11:49   ` Hans Verkuil
2017-03-10 23:32   ` Pavel Machek
2017-03-10  4:53 ` [PATCH v5 23/39] media: Add i.MX media core driver Steve Longerbeam
2017-03-10  4:53 ` Steve Longerbeam [this message]
2017-03-10  4:53 ` [PATCH v5 25/39] media: imx: Add CSI subdev driver Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 26/39] media: imx: Add VDIC " Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 27/39] media: imx: Add IC subdev drivers Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 28/39] media: imx: Add MIPI CSI-2 Receiver subdev driver Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 29/39] ARM: imx_v6_v7_defconfig: Enable staging video4linux drivers Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 30/39] media: imx: add support for bayer formats Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 31/39] media: imx: csi: " Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 32/39] media: imx: csi: fix crop rectangle changes in set_fmt Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 33/39] media: imx: mipi-csi2: enable setting and getting of frame rates Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 34/39] media: imx: csi: add __csi_get_fmt Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 35/39] media: imx: csi/fim: add support for frame intervals Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 36/39] media: imx: redo pixel format enumeration and negotiation Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 37/39] media: imx: csi: add frame skipping support Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 38/39] media: imx: csi: fix crop rectangle reset in sink set_fmt Steve Longerbeam
2017-03-19 15:22   ` Russell King - ARM Linux
2017-03-19 19:08     ` Steve Longerbeam
2017-03-20 11:55       ` Philipp Zabel
2017-03-20 12:08         ` Russell King - ARM Linux
2017-03-20 14:00           ` Philipp Zabel
2017-03-20 14:17             ` Russell King - ARM Linux
2017-03-20 17:16               ` Russell King - ARM Linux
2017-03-20 17:23               ` Philipp Zabel
2017-03-20 20:47                 ` Russell King - ARM Linux
2017-03-21  4:03                 ` Steve Longerbeam
2017-03-21 11:27                 ` Russell King - ARM Linux
2017-03-21 23:56                   ` Steve Longerbeam
2017-03-21 23:33                 ` Steve Longerbeam
2017-03-20 17:40               ` Philipp Zabel
2017-03-20 17:59                 ` Russell King - ARM Linux
2017-03-20 19:48             ` Steve Longerbeam
2017-03-10  4:53 ` [PATCH v5 39/39] media: imx: propagate sink pad formats to source pads Steve Longerbeam
2017-03-10 20:13 ` [PATCH v5 00/39] i.MX Media Driver Russell King - ARM Linux
2017-03-10 23:20   ` Steve Longerbeam
2017-03-12 17:47     ` Russell King - ARM Linux
2017-03-12  0:30   ` Steve Longerbeam
2017-03-12 19:57     ` Russell King - ARM Linux
2017-03-12 20:05       ` Steve Longerbeam
2017-03-12 20:22         ` Russell King - ARM Linux
2017-03-13  4:26           ` Steve Longerbeam
2017-03-13  8:16             ` Russell King - ARM Linux
2017-03-13  9:30               ` Russell King - ARM Linux
2017-03-13 23:39                 ` Steve Longerbeam
2017-03-13 23:37               ` Steve Longerbeam
2017-03-12 17:51 ` Russell King - ARM Linux
2017-03-12 19:21   ` Steve Longerbeam
2017-03-12 19:29     ` Russell King - ARM Linux
2017-03-12 19:44       ` Steve Longerbeam
2017-03-12 20:16         ` Steve Longerbeam
2017-03-12 20:36           ` Steve Longerbeam
2017-03-12 20:39             ` Steve Longerbeam
2017-03-12 20:40             ` Russell King - ARM Linux
2017-03-12 21:09               ` Russell King - ARM Linux
2017-03-14 17:29                 ` Steve Longerbeam
2017-03-18 20:02                   ` Steve Longerbeam
2017-03-12 19:47 ` Russell King - ARM Linux
2017-03-12 20:00   ` Steve Longerbeam
2017-03-12 20:59   ` Mauro Carvalho Chehab
2017-03-12 21:13     ` Russell King - ARM Linux
2017-03-12 22:10       ` Mauro Carvalho Chehab
2017-03-14 17:02         ` Steve Longerbeam
2017-03-18 19:22 ` Russell King - ARM Linux
2017-03-18 19:58   ` Steve Longerbeam
2017-03-18 20:43     ` Russell King - ARM Linux
2017-03-19  0:41       ` Nicolas Dufresne
2017-03-19  0:54         ` Russell King - ARM Linux
2017-03-19 14:33           ` Nicolas Dufresne
2017-03-19 14:51             ` Russell King - ARM Linux
2017-03-19  9:55         ` Russell King - ARM Linux
2017-03-19 14:45           ` Nicolas Dufresne
2017-03-19 13:57       ` Vladimir Zapolskiy
2017-03-19 14:21         ` Russell King - ARM Linux
2017-03-19 14:22           ` Russell King - ARM Linux
2017-03-19 15:00             ` Vladimir Zapolskiy
2017-03-19 15:09               ` Russell King - ARM Linux
2017-03-19 14:47           ` Nicolas Dufresne
2017-03-19 10:38     ` Russell King - ARM Linux
2017-03-19 10:48       ` [PATCH 1/4] media: imx-media-csi: fix v4l2-compliance check Russell King
2017-03-19 22:00         ` Steve Longerbeam
2017-03-19 10:48       ` [PATCH 2/4] media: imx: allow bayer pixel formats to be looked up Russell King
2017-03-19 22:02         ` Steve Longerbeam
2017-03-19 10:49       ` [PATCH 3/4] media: imx-csi: add frame size/interval enumeration Russell King
2017-03-19 22:18         ` Steve Longerbeam
2017-03-21 23:46         ` Steve Longerbeam
2017-03-19 10:49       ` [PATCH 4/4] media: imx-media-capture: add frame sizes/interval enumeration Russell King
2017-03-19 22:21         ` Steve Longerbeam
2017-03-19 22:39           ` Russell King - ARM Linux
2017-03-20  8:55         ` Philippe De Muyter
2017-03-20  9:05           ` Russell King - ARM Linux
2017-03-20  9:23             ` Philippe De Muyter
2017-03-20 10:41               ` Russell King - ARM Linux
2017-03-19 17:54       ` [PATCH v5 00/39] i.MX Media Driver Steve Longerbeam
2017-03-19 18:04         ` Russell King - ARM Linux
2017-03-20 13:01         ` Hans Verkuil
2017-03-20 13:29           ` Russell King - ARM Linux
2017-03-20 13:57             ` Hans Verkuil
2017-03-20 14:11               ` Russell King - ARM Linux
2017-03-20 15:57                 ` Hans Verkuil
2017-03-21 10:42                   ` Niklas Söderlund
2017-03-21 10:59                     ` Hans Verkuil
2017-03-21 11:36                       ` Russell King - ARM Linux
2017-03-22 18:10                         ` Nicolas Dufresne
2017-03-19 12:14     ` Russell King - ARM Linux
2017-03-19 18:37       ` Steve Longerbeam
2017-03-19 18:51         ` Russell King - ARM Linux
2017-03-19 18:56           ` Steve Longerbeam
2017-03-20 12:49       ` Hans Verkuil
2017-03-20 13:20       ` Philipp Zabel
2017-03-20 15:43         ` Russell King - ARM Linux
2017-03-20 16:29           ` Philipp Zabel
2017-03-20 16:35             ` Russell King - ARM Linux
2017-03-20 13:15     ` Philipp Zabel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1489121599-23206-25-git-send-email-steve_longerbeam@mentor.com \
    --to=slongerbeam@gmail.com \
    --cc=andrew-ct.chen@mediatek.com \
    --cc=arnd@arndb.de \
    --cc=bparrot@ti.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=devicetree@vger.kernel.org \
    --cc=fabio.estevam@nxp.com \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=horms+renesas@verge.net.au \
    --cc=hverkuil@xs4all.nl \
    --cc=jean-christophe.trotin@st.com \
    --cc=kernel@pengutronix.de \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=mark.rutland@arm.com \
    --cc=markus.heiser@darmarIT.de \
    --cc=mchehab@kernel.org \
    --cc=minghsiu.tsai@mediatek.com \
    --cc=nick@shmanahar.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    --cc=p.zabel@pengutronix.de \
    --cc=pavel@ucw.cz \
    --cc=robert.jarzmik@free.fr \
    --cc=robh+dt@kernel.org \
    --cc=sakari.ailus@linux.intel.com \
    --cc=shawnguo@kernel.org \
    --cc=shuah@kernel.org \
    --cc=songjun.wu@microchip.com \
    --cc=steve_longerbeam@mentor.com \
    --cc=sudipm.mukherjee@gmail.com \
    --cc=tiffany.lin@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®