cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

imx-media-capture.c (27547B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Video Capture Subdev for Freescale i.MX5/6 SOC
      4 *
      5 * Copyright (c) 2012-2016 Mentor Graphics Inc.
      6 */
      7#include <linux/delay.h>
      8#include <linux/fs.h>
      9#include <linux/module.h>
     10#include <linux/of_platform.h>
     11#include <linux/pinctrl/consumer.h>
     12#include <linux/platform_device.h>
     13#include <linux/sched.h>
     14#include <linux/slab.h>
     15#include <linux/spinlock.h>
     16#include <linux/timer.h>
     17#include <media/v4l2-ctrls.h>
     18#include <media/v4l2-device.h>
     19#include <media/v4l2-event.h>
     20#include <media/v4l2-fwnode.h>
     21#include <media/v4l2-ioctl.h>
     22#include <media/v4l2-mc.h>
     23#include <media/v4l2-subdev.h>
     24#include <media/videobuf2-dma-contig.h>
     25#include <video/imx-ipu-v3.h>
     26#include <media/imx.h>
     27#include "imx-media.h"
     28
     29#define IMX_CAPTURE_NAME "imx-capture"
     30
     31struct capture_priv {
     32	struct imx_media_dev *md;		/* Media device */
     33	struct device *dev;			/* Physical device */
     34
     35	struct imx_media_video_dev vdev;	/* Video device */
     36	struct media_pad vdev_pad;		/* Video device pad */
     37
     38	struct v4l2_subdev *src_sd;		/* Source subdev */
     39	int src_sd_pad;				/* Source subdev pad */
     40
     41	struct mutex mutex;			/* Protect vdev operations */
     42
     43	struct vb2_queue q;			/* The videobuf2 queue */
     44	struct list_head ready_q;		/* List of queued buffers */
     45	spinlock_t q_lock;			/* Protect ready_q */
     46
     47	struct v4l2_ctrl_handler ctrl_hdlr;	/* Controls inherited from subdevs */
     48
     49	bool legacy_api;			/* Use the legacy (pre-MC) API */
     50};
     51
     52#define to_capture_priv(v) container_of(v, struct capture_priv, vdev)
     53
     54/* In bytes, per queue */
     55#define VID_MEM_LIMIT	SZ_64M
     56
     57/* -----------------------------------------------------------------------------
     58 * MC-Centric Video IOCTLs
     59 */
     60
     61static const struct imx_media_pixfmt *capture_find_format(u32 code, u32 fourcc)
     62{
     63	const struct imx_media_pixfmt *cc;
     64
     65	cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV_RGB);
     66	if (cc) {
     67		enum imx_pixfmt_sel fmt_sel = cc->cs == IPUV3_COLORSPACE_YUV
     68					    ? PIXFMT_SEL_YUV : PIXFMT_SEL_RGB;
     69
     70		cc = imx_media_find_pixel_format(fourcc, fmt_sel);
     71		if (!cc) {
     72			imx_media_enum_pixel_formats(&fourcc, 0, fmt_sel, 0);
     73			cc = imx_media_find_pixel_format(fourcc, fmt_sel);
     74		}
     75
     76		return cc;
     77	}
     78
     79	return imx_media_find_mbus_format(code, PIXFMT_SEL_ANY);
     80}
     81
     82static int capture_querycap(struct file *file, void *fh,
     83			    struct v4l2_capability *cap)
     84{
     85	struct capture_priv *priv = video_drvdata(file);
     86
     87	strscpy(cap->driver, IMX_CAPTURE_NAME, sizeof(cap->driver));
     88	strscpy(cap->card, IMX_CAPTURE_NAME, sizeof(cap->card));
     89	snprintf(cap->bus_info, sizeof(cap->bus_info),
     90		 "platform:%s", dev_name(priv->dev));
     91
     92	return 0;
     93}
     94
     95static int capture_enum_fmt_vid_cap(struct file *file, void *fh,
     96				    struct v4l2_fmtdesc *f)
     97{
     98	return imx_media_enum_pixel_formats(&f->pixelformat, f->index,
     99					    PIXFMT_SEL_ANY, f->mbus_code);
    100}
    101
    102static int capture_enum_framesizes(struct file *file, void *fh,
    103				   struct v4l2_frmsizeenum *fsize)
    104{
    105	const struct imx_media_pixfmt *cc;
    106
    107	if (fsize->index > 0)
    108		return -EINVAL;
    109
    110	cc = imx_media_find_pixel_format(fsize->pixel_format, PIXFMT_SEL_ANY);
    111	if (!cc)
    112		return -EINVAL;
    113
    114	/*
    115	 * TODO: The constraints are hardware-specific and may depend on the
    116	 * pixel format. This should come from the driver using
    117	 * imx_media_capture.
    118	 */
    119	fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
    120	fsize->stepwise.min_width = 1;
    121	fsize->stepwise.max_width = 65535;
    122	fsize->stepwise.min_height = 1;
    123	fsize->stepwise.max_height = 65535;
    124	fsize->stepwise.step_width = 1;
    125	fsize->stepwise.step_height = 1;
    126
    127	return 0;
    128}
    129
    130static int capture_g_fmt_vid_cap(struct file *file, void *fh,
    131				 struct v4l2_format *f)
    132{
    133	struct capture_priv *priv = video_drvdata(file);
    134
    135	f->fmt.pix = priv->vdev.fmt;
    136
    137	return 0;
    138}
    139
    140static const struct imx_media_pixfmt *
    141__capture_try_fmt(struct v4l2_pix_format *pixfmt, struct v4l2_rect *compose)
    142{
    143	struct v4l2_mbus_framefmt fmt_src;
    144	const struct imx_media_pixfmt *cc;
    145
    146	/*
    147	 * Find the pixel format, default to the first supported format if not
    148	 * found.
    149	 */
    150	cc = imx_media_find_pixel_format(pixfmt->pixelformat, PIXFMT_SEL_ANY);
    151	if (!cc) {
    152		imx_media_enum_pixel_formats(&pixfmt->pixelformat, 0,
    153					     PIXFMT_SEL_ANY, 0);
    154		cc = imx_media_find_pixel_format(pixfmt->pixelformat,
    155						 PIXFMT_SEL_ANY);
    156	}
    157
    158	/* Allow IDMAC interweave but enforce field order from source. */
    159	if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) {
    160		switch (pixfmt->field) {
    161		case V4L2_FIELD_SEQ_TB:
    162			pixfmt->field = V4L2_FIELD_INTERLACED_TB;
    163			break;
    164		case V4L2_FIELD_SEQ_BT:
    165			pixfmt->field = V4L2_FIELD_INTERLACED_BT;
    166			break;
    167		default:
    168			break;
    169		}
    170	}
    171
    172	v4l2_fill_mbus_format(&fmt_src, pixfmt, 0);
    173	imx_media_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src, cc);
    174
    175	if (compose) {
    176		compose->width = fmt_src.width;
    177		compose->height = fmt_src.height;
    178	}
    179
    180	return cc;
    181}
    182
    183static int capture_try_fmt_vid_cap(struct file *file, void *fh,
    184				   struct v4l2_format *f)
    185{
    186	__capture_try_fmt(&f->fmt.pix, NULL);
    187	return 0;
    188}
    189
    190static int capture_s_fmt_vid_cap(struct file *file, void *fh,
    191				 struct v4l2_format *f)
    192{
    193	struct capture_priv *priv = video_drvdata(file);
    194	const struct imx_media_pixfmt *cc;
    195
    196	if (vb2_is_busy(&priv->q)) {
    197		dev_err(priv->dev, "%s queue busy\n", __func__);
    198		return -EBUSY;
    199	}
    200
    201	cc = __capture_try_fmt(&f->fmt.pix, &priv->vdev.compose);
    202
    203	priv->vdev.cc = cc;
    204	priv->vdev.fmt = f->fmt.pix;
    205
    206	return 0;
    207}
    208
    209static int capture_g_selection(struct file *file, void *fh,
    210			       struct v4l2_selection *s)
    211{
    212	struct capture_priv *priv = video_drvdata(file);
    213
    214	switch (s->target) {
    215	case V4L2_SEL_TGT_COMPOSE:
    216	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
    217	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
    218		/* The compose rectangle is fixed to the source format. */
    219		s->r = priv->vdev.compose;
    220		break;
    221	case V4L2_SEL_TGT_COMPOSE_PADDED:
    222		/*
    223		 * The hardware writes with a configurable but fixed DMA burst
    224		 * size. If the source format width is not burst size aligned,
    225		 * the written frame contains padding to the right.
    226		 */
    227		s->r.left = 0;
    228		s->r.top = 0;
    229		s->r.width = priv->vdev.fmt.width;
    230		s->r.height = priv->vdev.fmt.height;
    231		break;
    232	default:
    233		return -EINVAL;
    234	}
    235
    236	return 0;
    237}
    238
    239static int capture_subscribe_event(struct v4l2_fh *fh,
    240				   const struct v4l2_event_subscription *sub)
    241{
    242	switch (sub->type) {
    243	case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR:
    244		return v4l2_event_subscribe(fh, sub, 0, NULL);
    245	default:
    246		return -EINVAL;
    247	}
    248}
    249
    250static const struct v4l2_ioctl_ops capture_ioctl_ops = {
    251	.vidioc_querycap		= capture_querycap,
    252
    253	.vidioc_enum_fmt_vid_cap	= capture_enum_fmt_vid_cap,
    254	.vidioc_enum_framesizes		= capture_enum_framesizes,
    255
    256	.vidioc_g_fmt_vid_cap		= capture_g_fmt_vid_cap,
    257	.vidioc_try_fmt_vid_cap		= capture_try_fmt_vid_cap,
    258	.vidioc_s_fmt_vid_cap		= capture_s_fmt_vid_cap,
    259
    260	.vidioc_g_selection		= capture_g_selection,
    261
    262	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
    263	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
    264	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
    265	.vidioc_querybuf		= vb2_ioctl_querybuf,
    266	.vidioc_qbuf			= vb2_ioctl_qbuf,
    267	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
    268	.vidioc_expbuf			= vb2_ioctl_expbuf,
    269	.vidioc_streamon		= vb2_ioctl_streamon,
    270	.vidioc_streamoff		= vb2_ioctl_streamoff,
    271
    272	.vidioc_subscribe_event		= capture_subscribe_event,
    273	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
    274};
    275
    276/* -----------------------------------------------------------------------------
    277 * Legacy Video IOCTLs
    278 */
    279
    280static int capture_legacy_enum_framesizes(struct file *file, void *fh,
    281					  struct v4l2_frmsizeenum *fsize)
    282{
    283	struct capture_priv *priv = video_drvdata(file);
    284	const struct imx_media_pixfmt *cc;
    285	struct v4l2_subdev_frame_size_enum fse = {
    286		.index = fsize->index,
    287		.pad = priv->src_sd_pad,
    288		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
    289	};
    290	int ret;
    291
    292	cc = imx_media_find_pixel_format(fsize->pixel_format, PIXFMT_SEL_ANY);
    293	if (!cc)
    294		return -EINVAL;
    295
    296	fse.code = cc->codes ? cc->codes[0] : 0;
    297
    298	ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_size, NULL, &fse);
    299	if (ret)
    300		return ret;
    301
    302	if (fse.min_width == fse.max_width &&
    303	    fse.min_height == fse.max_height) {
    304		fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
    305		fsize->discrete.width = fse.min_width;
    306		fsize->discrete.height = fse.min_height;
    307	} else {
    308		fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
    309		fsize->stepwise.min_width = fse.min_width;
    310		fsize->stepwise.max_width = fse.max_width;
    311		fsize->stepwise.min_height = fse.min_height;
    312		fsize->stepwise.max_height = fse.max_height;
    313		fsize->stepwise.step_width = 1;
    314		fsize->stepwise.step_height = 1;
    315	}
    316
    317	return 0;
    318}
    319
    320static int capture_legacy_enum_frameintervals(struct file *file, void *fh,
    321					      struct v4l2_frmivalenum *fival)
    322{
    323	struct capture_priv *priv = video_drvdata(file);
    324	const struct imx_media_pixfmt *cc;
    325	struct v4l2_subdev_frame_interval_enum fie = {
    326		.index = fival->index,
    327		.pad = priv->src_sd_pad,
    328		.width = fival->width,
    329		.height = fival->height,
    330		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
    331	};
    332	int ret;
    333
    334	cc = imx_media_find_pixel_format(fival->pixel_format, PIXFMT_SEL_ANY);
    335	if (!cc)
    336		return -EINVAL;
    337
    338	fie.code = cc->codes ? cc->codes[0] : 0;
    339
    340	ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_interval,
    341			       NULL, &fie);
    342	if (ret)
    343		return ret;
    344
    345	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
    346	fival->discrete = fie.interval;
    347
    348	return 0;
    349}
    350
    351static int capture_legacy_enum_fmt_vid_cap(struct file *file, void *fh,
    352					   struct v4l2_fmtdesc *f)
    353{
    354	struct capture_priv *priv = video_drvdata(file);
    355	const struct imx_media_pixfmt *cc_src;
    356	struct v4l2_subdev_format fmt_src;
    357	u32 fourcc;
    358	int ret;
    359
    360	fmt_src.pad = priv->src_sd_pad;
    361	fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    362	ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
    363	if (ret) {
    364		dev_err(priv->dev, "failed to get src_sd format\n");
    365		return ret;
    366	}
    367
    368	cc_src = imx_media_find_ipu_format(fmt_src.format.code,
    369					   PIXFMT_SEL_YUV_RGB);
    370	if (cc_src) {
    371		enum imx_pixfmt_sel fmt_sel =
    372			(cc_src->cs == IPUV3_COLORSPACE_YUV) ?
    373			PIXFMT_SEL_YUV : PIXFMT_SEL_RGB;
    374
    375		ret = imx_media_enum_pixel_formats(&fourcc, f->index, fmt_sel,
    376						   0);
    377		if (ret)
    378			return ret;
    379	} else {
    380		cc_src = imx_media_find_mbus_format(fmt_src.format.code,
    381						    PIXFMT_SEL_ANY);
    382		if (WARN_ON(!cc_src))
    383			return -EINVAL;
    384
    385		if (f->index != 0)
    386			return -EINVAL;
    387		fourcc = cc_src->fourcc;
    388	}
    389
    390	f->pixelformat = fourcc;
    391
    392	return 0;
    393}
    394
    395static const struct imx_media_pixfmt *
    396__capture_legacy_try_fmt(struct capture_priv *priv,
    397			 struct v4l2_subdev_format *fmt_src,
    398			 struct v4l2_pix_format *pixfmt)
    399{
    400	const struct imx_media_pixfmt *cc;
    401
    402	cc = capture_find_format(fmt_src->format.code, pixfmt->pixelformat);
    403	if (WARN_ON(!cc))
    404		return NULL;
    405
    406	/* allow IDMAC interweave but enforce field order from source */
    407	if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) {
    408		switch (fmt_src->format.field) {
    409		case V4L2_FIELD_SEQ_TB:
    410			fmt_src->format.field = V4L2_FIELD_INTERLACED_TB;
    411			break;
    412		case V4L2_FIELD_SEQ_BT:
    413			fmt_src->format.field = V4L2_FIELD_INTERLACED_BT;
    414			break;
    415		default:
    416			break;
    417		}
    418	}
    419
    420	imx_media_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src->format, cc);
    421
    422	return cc;
    423}
    424
    425static int capture_legacy_try_fmt_vid_cap(struct file *file, void *fh,
    426					  struct v4l2_format *f)
    427{
    428	struct capture_priv *priv = video_drvdata(file);
    429	struct v4l2_subdev_format fmt_src;
    430	int ret;
    431
    432	fmt_src.pad = priv->src_sd_pad;
    433	fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    434	ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
    435	if (ret)
    436		return ret;
    437
    438	if (!__capture_legacy_try_fmt(priv, &fmt_src, &f->fmt.pix))
    439		return -EINVAL;
    440
    441	return 0;
    442}
    443
    444static int capture_legacy_s_fmt_vid_cap(struct file *file, void *fh,
    445					struct v4l2_format *f)
    446{
    447	struct capture_priv *priv = video_drvdata(file);
    448	struct v4l2_subdev_format fmt_src;
    449	const struct imx_media_pixfmt *cc;
    450	int ret;
    451
    452	if (vb2_is_busy(&priv->q)) {
    453		dev_err(priv->dev, "%s queue busy\n", __func__);
    454		return -EBUSY;
    455	}
    456
    457	fmt_src.pad = priv->src_sd_pad;
    458	fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    459	ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
    460	if (ret)
    461		return ret;
    462
    463	cc = __capture_legacy_try_fmt(priv, &fmt_src, &f->fmt.pix);
    464	if (!cc)
    465		return -EINVAL;
    466
    467	priv->vdev.cc = cc;
    468	priv->vdev.fmt = f->fmt.pix;
    469	priv->vdev.compose.width = fmt_src.format.width;
    470	priv->vdev.compose.height = fmt_src.format.height;
    471
    472	return 0;
    473}
    474
    475static int capture_legacy_querystd(struct file *file, void *fh,
    476				   v4l2_std_id *std)
    477{
    478	struct capture_priv *priv = video_drvdata(file);
    479
    480	return v4l2_subdev_call(priv->src_sd, video, querystd, std);
    481}
    482
    483static int capture_legacy_g_std(struct file *file, void *fh, v4l2_std_id *std)
    484{
    485	struct capture_priv *priv = video_drvdata(file);
    486
    487	return v4l2_subdev_call(priv->src_sd, video, g_std, std);
    488}
    489
    490static int capture_legacy_s_std(struct file *file, void *fh, v4l2_std_id std)
    491{
    492	struct capture_priv *priv = video_drvdata(file);
    493
    494	if (vb2_is_busy(&priv->q))
    495		return -EBUSY;
    496
    497	return v4l2_subdev_call(priv->src_sd, video, s_std, std);
    498}
    499
    500static int capture_legacy_g_parm(struct file *file, void *fh,
    501				 struct v4l2_streamparm *a)
    502{
    503	struct capture_priv *priv = video_drvdata(file);
    504	struct v4l2_subdev_frame_interval fi;
    505	int ret;
    506
    507	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    508		return -EINVAL;
    509
    510	memset(&fi, 0, sizeof(fi));
    511	fi.pad = priv->src_sd_pad;
    512	ret = v4l2_subdev_call(priv->src_sd, video, g_frame_interval, &fi);
    513	if (ret < 0)
    514		return ret;
    515
    516	a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
    517	a->parm.capture.timeperframe = fi.interval;
    518
    519	return 0;
    520}
    521
    522static int capture_legacy_s_parm(struct file *file, void *fh,
    523				 struct v4l2_streamparm *a)
    524{
    525	struct capture_priv *priv = video_drvdata(file);
    526	struct v4l2_subdev_frame_interval fi;
    527	int ret;
    528
    529	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    530		return -EINVAL;
    531
    532	memset(&fi, 0, sizeof(fi));
    533	fi.pad = priv->src_sd_pad;
    534	fi.interval = a->parm.capture.timeperframe;
    535	ret = v4l2_subdev_call(priv->src_sd, video, s_frame_interval, &fi);
    536	if (ret < 0)
    537		return ret;
    538
    539	a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
    540	a->parm.capture.timeperframe = fi.interval;
    541
    542	return 0;
    543}
    544
    545static int capture_legacy_subscribe_event(struct v4l2_fh *fh,
    546					  const struct v4l2_event_subscription *sub)
    547{
    548	switch (sub->type) {
    549	case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR:
    550		return v4l2_event_subscribe(fh, sub, 0, NULL);
    551	case V4L2_EVENT_SOURCE_CHANGE:
    552		return v4l2_src_change_event_subscribe(fh, sub);
    553	case V4L2_EVENT_CTRL:
    554		return v4l2_ctrl_subscribe_event(fh, sub);
    555	default:
    556		return -EINVAL;
    557	}
    558}
    559
    560static const struct v4l2_ioctl_ops capture_legacy_ioctl_ops = {
    561	.vidioc_querycap		= capture_querycap,
    562
    563	.vidioc_enum_framesizes		= capture_legacy_enum_framesizes,
    564	.vidioc_enum_frameintervals	= capture_legacy_enum_frameintervals,
    565
    566	.vidioc_enum_fmt_vid_cap	= capture_legacy_enum_fmt_vid_cap,
    567	.vidioc_g_fmt_vid_cap		= capture_g_fmt_vid_cap,
    568	.vidioc_try_fmt_vid_cap		= capture_legacy_try_fmt_vid_cap,
    569	.vidioc_s_fmt_vid_cap		= capture_legacy_s_fmt_vid_cap,
    570
    571	.vidioc_querystd		= capture_legacy_querystd,
    572	.vidioc_g_std			= capture_legacy_g_std,
    573	.vidioc_s_std			= capture_legacy_s_std,
    574
    575	.vidioc_g_selection		= capture_g_selection,
    576
    577	.vidioc_g_parm			= capture_legacy_g_parm,
    578	.vidioc_s_parm			= capture_legacy_s_parm,
    579
    580	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
    581	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
    582	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
    583	.vidioc_querybuf		= vb2_ioctl_querybuf,
    584	.vidioc_qbuf			= vb2_ioctl_qbuf,
    585	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
    586	.vidioc_expbuf			= vb2_ioctl_expbuf,
    587	.vidioc_streamon		= vb2_ioctl_streamon,
    588	.vidioc_streamoff		= vb2_ioctl_streamoff,
    589
    590	.vidioc_subscribe_event		= capture_legacy_subscribe_event,
    591	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
    592};
    593
    594/* -----------------------------------------------------------------------------
    595 * Queue Operations
    596 */
    597
    598static int capture_queue_setup(struct vb2_queue *vq,
    599			       unsigned int *nbuffers,
    600			       unsigned int *nplanes,
    601			       unsigned int sizes[],
    602			       struct device *alloc_devs[])
    603{
    604	struct capture_priv *priv = vb2_get_drv_priv(vq);
    605	struct v4l2_pix_format *pix = &priv->vdev.fmt;
    606	unsigned int count = *nbuffers;
    607
    608	if (vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    609		return -EINVAL;
    610
    611	if (*nplanes) {
    612		if (*nplanes != 1 || sizes[0] < pix->sizeimage)
    613			return -EINVAL;
    614		count += vq->num_buffers;
    615	}
    616
    617	count = min_t(__u32, VID_MEM_LIMIT / pix->sizeimage, count);
    618
    619	if (*nplanes)
    620		*nbuffers = (count < vq->num_buffers) ? 0 :
    621			count - vq->num_buffers;
    622	else
    623		*nbuffers = count;
    624
    625	*nplanes = 1;
    626	sizes[0] = pix->sizeimage;
    627
    628	return 0;
    629}
    630
    631static int capture_buf_init(struct vb2_buffer *vb)
    632{
    633	struct imx_media_buffer *buf = to_imx_media_vb(vb);
    634
    635	INIT_LIST_HEAD(&buf->list);
    636
    637	return 0;
    638}
    639
    640static int capture_buf_prepare(struct vb2_buffer *vb)
    641{
    642	struct vb2_queue *vq = vb->vb2_queue;
    643	struct capture_priv *priv = vb2_get_drv_priv(vq);
    644	struct v4l2_pix_format *pix = &priv->vdev.fmt;
    645
    646	if (vb2_plane_size(vb, 0) < pix->sizeimage) {
    647		dev_err(priv->dev,
    648			"data will not fit into plane (%lu < %lu)\n",
    649			vb2_plane_size(vb, 0), (long)pix->sizeimage);
    650		return -EINVAL;
    651	}
    652
    653	vb2_set_plane_payload(vb, 0, pix->sizeimage);
    654
    655	return 0;
    656}
    657
    658static void capture_buf_queue(struct vb2_buffer *vb)
    659{
    660	struct capture_priv *priv = vb2_get_drv_priv(vb->vb2_queue);
    661	struct imx_media_buffer *buf = to_imx_media_vb(vb);
    662	unsigned long flags;
    663
    664	spin_lock_irqsave(&priv->q_lock, flags);
    665
    666	list_add_tail(&buf->list, &priv->ready_q);
    667
    668	spin_unlock_irqrestore(&priv->q_lock, flags);
    669}
    670
    671static int capture_validate_fmt(struct capture_priv *priv)
    672{
    673	struct v4l2_subdev_format fmt_src;
    674	const struct imx_media_pixfmt *cc;
    675	int ret;
    676
    677	/* Retrieve the media bus format on the source subdev. */
    678	fmt_src.pad = priv->src_sd_pad;
    679	fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    680	ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
    681	if (ret)
    682		return ret;
    683
    684	/*
    685	 * Verify that the media bus size matches the size set on the video
    686	 * node. It is sufficient to check the compose rectangle size without
    687	 * checking the rounded size from vdev.fmt, as the rounded size is
    688	 * derived directly from the compose rectangle size, and will thus
    689	 * always match if the compose rectangle matches.
    690	 */
    691	if (priv->vdev.compose.width != fmt_src.format.width ||
    692	    priv->vdev.compose.height != fmt_src.format.height)
    693		return -EPIPE;
    694
    695	/*
    696	 * Verify that the media bus code is compatible with the pixel format
    697	 * set on the video node.
    698	 */
    699	cc = capture_find_format(fmt_src.format.code, 0);
    700	if (!cc || priv->vdev.cc->cs != cc->cs)
    701		return -EPIPE;
    702
    703	return 0;
    704}
    705
    706static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
    707{
    708	struct capture_priv *priv = vb2_get_drv_priv(vq);
    709	struct imx_media_buffer *buf, *tmp;
    710	unsigned long flags;
    711	int ret;
    712
    713	ret = capture_validate_fmt(priv);
    714	if (ret) {
    715		dev_err(priv->dev, "capture format not valid\n");
    716		goto return_bufs;
    717	}
    718
    719	ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
    720					    true);
    721	if (ret) {
    722		dev_err(priv->dev, "pipeline start failed with %d\n", ret);
    723		goto return_bufs;
    724	}
    725
    726	return 0;
    727
    728return_bufs:
    729	spin_lock_irqsave(&priv->q_lock, flags);
    730	list_for_each_entry_safe(buf, tmp, &priv->ready_q, list) {
    731		list_del(&buf->list);
    732		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
    733	}
    734	spin_unlock_irqrestore(&priv->q_lock, flags);
    735	return ret;
    736}
    737
    738static void capture_stop_streaming(struct vb2_queue *vq)
    739{
    740	struct capture_priv *priv = vb2_get_drv_priv(vq);
    741	struct imx_media_buffer *frame;
    742	struct imx_media_buffer *tmp;
    743	unsigned long flags;
    744	int ret;
    745
    746	ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
    747					    false);
    748	if (ret)
    749		dev_warn(priv->dev, "pipeline stop failed with %d\n", ret);
    750
    751	/* release all active buffers */
    752	spin_lock_irqsave(&priv->q_lock, flags);
    753	list_for_each_entry_safe(frame, tmp, &priv->ready_q, list) {
    754		list_del(&frame->list);
    755		vb2_buffer_done(&frame->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
    756	}
    757	spin_unlock_irqrestore(&priv->q_lock, flags);
    758}
    759
    760static const struct vb2_ops capture_qops = {
    761	.queue_setup	 = capture_queue_setup,
    762	.buf_init        = capture_buf_init,
    763	.buf_prepare	 = capture_buf_prepare,
    764	.buf_queue	 = capture_buf_queue,
    765	.wait_prepare	 = vb2_ops_wait_prepare,
    766	.wait_finish	 = vb2_ops_wait_finish,
    767	.start_streaming = capture_start_streaming,
    768	.stop_streaming  = capture_stop_streaming,
    769};
    770
    771/* -----------------------------------------------------------------------------
    772 * File Operations
    773 */
    774
    775static int capture_open(struct file *file)
    776{
    777	struct capture_priv *priv = video_drvdata(file);
    778	struct video_device *vfd = priv->vdev.vfd;
    779	int ret;
    780
    781	if (mutex_lock_interruptible(&priv->mutex))
    782		return -ERESTARTSYS;
    783
    784	ret = v4l2_fh_open(file);
    785	if (ret) {
    786		dev_err(priv->dev, "v4l2_fh_open failed\n");
    787		goto out;
    788	}
    789
    790	ret = v4l2_pipeline_pm_get(&vfd->entity);
    791	if (ret)
    792		v4l2_fh_release(file);
    793
    794out:
    795	mutex_unlock(&priv->mutex);
    796	return ret;
    797}
    798
    799static int capture_release(struct file *file)
    800{
    801	struct capture_priv *priv = video_drvdata(file);
    802	struct video_device *vfd = priv->vdev.vfd;
    803	struct vb2_queue *vq = &priv->q;
    804
    805	mutex_lock(&priv->mutex);
    806
    807	if (file->private_data == vq->owner) {
    808		vb2_queue_release(vq);
    809		vq->owner = NULL;
    810	}
    811
    812	v4l2_pipeline_pm_put(&vfd->entity);
    813
    814	v4l2_fh_release(file);
    815	mutex_unlock(&priv->mutex);
    816	return 0;
    817}
    818
    819static const struct v4l2_file_operations capture_fops = {
    820	.owner		= THIS_MODULE,
    821	.open		= capture_open,
    822	.release	= capture_release,
    823	.poll		= vb2_fop_poll,
    824	.unlocked_ioctl	= video_ioctl2,
    825	.mmap		= vb2_fop_mmap,
    826};
    827
    828/* -----------------------------------------------------------------------------
    829 * Public API
    830 */
    831
    832struct imx_media_buffer *
    833imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
    834{
    835	struct capture_priv *priv = to_capture_priv(vdev);
    836	struct imx_media_buffer *buf = NULL;
    837	unsigned long flags;
    838
    839	spin_lock_irqsave(&priv->q_lock, flags);
    840
    841	/* get next queued buffer */
    842	if (!list_empty(&priv->ready_q)) {
    843		buf = list_entry(priv->ready_q.next, struct imx_media_buffer,
    844				 list);
    845		list_del(&buf->list);
    846	}
    847
    848	spin_unlock_irqrestore(&priv->q_lock, flags);
    849
    850	return buf;
    851}
    852EXPORT_SYMBOL_GPL(imx_media_capture_device_next_buf);
    853
    854void imx_media_capture_device_error(struct imx_media_video_dev *vdev)
    855{
    856	struct capture_priv *priv = to_capture_priv(vdev);
    857	struct vb2_queue *vq = &priv->q;
    858	unsigned long flags;
    859
    860	if (!vb2_is_streaming(vq))
    861		return;
    862
    863	spin_lock_irqsave(&priv->q_lock, flags);
    864	vb2_queue_error(vq);
    865	spin_unlock_irqrestore(&priv->q_lock, flags);
    866}
    867EXPORT_SYMBOL_GPL(imx_media_capture_device_error);
    868
    869static int capture_init_format(struct capture_priv *priv)
    870{
    871	struct v4l2_subdev_format fmt_src = {
    872		.pad = priv->src_sd_pad,
    873		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
    874	};
    875	struct imx_media_video_dev *vdev = &priv->vdev;
    876	int ret;
    877
    878	if (priv->legacy_api) {
    879		ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL,
    880				       &fmt_src);
    881		if (ret) {
    882			dev_err(priv->dev, "failed to get source format\n");
    883			return ret;
    884		}
    885	} else {
    886		fmt_src.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
    887		fmt_src.format.width = IMX_MEDIA_DEF_PIX_WIDTH;
    888		fmt_src.format.height = IMX_MEDIA_DEF_PIX_HEIGHT;
    889	}
    890
    891	imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt, &fmt_src.format, NULL);
    892	vdev->compose.width = fmt_src.format.width;
    893	vdev->compose.height = fmt_src.format.height;
    894
    895	vdev->cc = imx_media_find_pixel_format(vdev->fmt.pixelformat,
    896					       PIXFMT_SEL_ANY);
    897
    898	return 0;
    899}
    900
    901int imx_media_capture_device_register(struct imx_media_video_dev *vdev,
    902				      u32 link_flags)
    903{
    904	struct capture_priv *priv = to_capture_priv(vdev);
    905	struct v4l2_subdev *sd = priv->src_sd;
    906	struct v4l2_device *v4l2_dev = sd->v4l2_dev;
    907	struct video_device *vfd = vdev->vfd;
    908	int ret;
    909
    910	/* get media device */
    911	priv->md = container_of(v4l2_dev->mdev, struct imx_media_dev, md);
    912
    913	vfd->v4l2_dev = v4l2_dev;
    914
    915	/* Initialize the default format and compose rectangle. */
    916	ret = capture_init_format(priv);
    917	if (ret < 0)
    918		return ret;
    919
    920	/* Register the video device. */
    921	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
    922	if (ret) {
    923		dev_err(priv->dev, "Failed to register video device\n");
    924		return ret;
    925	}
    926
    927	dev_info(priv->dev, "Registered %s as /dev/%s\n", vfd->name,
    928		 video_device_node_name(vfd));
    929
    930	/* Create the link from the src_sd devnode pad to device node. */
    931	if (link_flags & MEDIA_LNK_FL_IMMUTABLE)
    932		link_flags |= MEDIA_LNK_FL_ENABLED;
    933	ret = media_create_pad_link(&sd->entity, priv->src_sd_pad,
    934				    &vfd->entity, 0, link_flags);
    935	if (ret) {
    936		dev_err(priv->dev, "failed to create link to device node\n");
    937		video_unregister_device(vfd);
    938		return ret;
    939	}
    940
    941	/* Add vdev to the video devices list. */
    942	imx_media_add_video_device(priv->md, vdev);
    943
    944	return 0;
    945}
    946EXPORT_SYMBOL_GPL(imx_media_capture_device_register);
    947
    948void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev)
    949{
    950	struct capture_priv *priv = to_capture_priv(vdev);
    951	struct video_device *vfd = priv->vdev.vfd;
    952
    953	media_entity_cleanup(&vfd->entity);
    954	video_unregister_device(vfd);
    955}
    956EXPORT_SYMBOL_GPL(imx_media_capture_device_unregister);
    957
    958struct imx_media_video_dev *
    959imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd,
    960			      int pad, bool legacy_api)
    961{
    962	struct capture_priv *priv;
    963	struct video_device *vfd;
    964	struct vb2_queue *vq;
    965	int ret;
    966
    967	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    968	if (!priv)
    969		return ERR_PTR(-ENOMEM);
    970
    971	priv->src_sd = src_sd;
    972	priv->src_sd_pad = pad;
    973	priv->dev = dev;
    974	priv->legacy_api = legacy_api;
    975
    976	mutex_init(&priv->mutex);
    977	INIT_LIST_HEAD(&priv->ready_q);
    978	spin_lock_init(&priv->q_lock);
    979
    980	/* Allocate and initialize the video device. */
    981	vfd = video_device_alloc();
    982	if (!vfd)
    983		return ERR_PTR(-ENOMEM);
    984
    985	vfd->fops = &capture_fops;
    986	vfd->ioctl_ops = legacy_api ? &capture_legacy_ioctl_ops
    987		       : &capture_ioctl_ops;
    988	vfd->minor = -1;
    989	vfd->release = video_device_release;
    990	vfd->vfl_dir = VFL_DIR_RX;
    991	vfd->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
    992	vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
    993			 | (!legacy_api ? V4L2_CAP_IO_MC : 0);
    994	vfd->lock = &priv->mutex;
    995	vfd->queue = &priv->q;
    996
    997	snprintf(vfd->name, sizeof(vfd->name), "%s capture", src_sd->name);
    998
    999	video_set_drvdata(vfd, priv);
   1000	priv->vdev.vfd = vfd;
   1001	INIT_LIST_HEAD(&priv->vdev.list);
   1002
   1003	/* Initialize the video device pad. */
   1004	priv->vdev_pad.flags = MEDIA_PAD_FL_SINK;
   1005	ret = media_entity_pads_init(&vfd->entity, 1, &priv->vdev_pad);
   1006	if (ret) {
   1007		video_device_release(vfd);
   1008		return ERR_PTR(ret);
   1009	}
   1010
   1011	/* Initialize the vb2 queue. */
   1012	vq = &priv->q;
   1013	vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   1014	vq->io_modes = VB2_MMAP | VB2_DMABUF;
   1015	vq->drv_priv = priv;
   1016	vq->buf_struct_size = sizeof(struct imx_media_buffer);
   1017	vq->ops = &capture_qops;
   1018	vq->mem_ops = &vb2_dma_contig_memops;
   1019	vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
   1020	vq->lock = &priv->mutex;
   1021	vq->min_buffers_needed = 2;
   1022	vq->dev = priv->dev;
   1023
   1024	ret = vb2_queue_init(vq);
   1025	if (ret) {
   1026		dev_err(priv->dev, "vb2_queue_init failed\n");
   1027		video_device_release(vfd);
   1028		return ERR_PTR(ret);
   1029	}
   1030
   1031	if (legacy_api) {
   1032		/* Initialize the control handler. */
   1033		v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
   1034		vfd->ctrl_handler = &priv->ctrl_hdlr;
   1035	}
   1036
   1037	return &priv->vdev;
   1038}
   1039EXPORT_SYMBOL_GPL(imx_media_capture_device_init);
   1040
   1041void imx_media_capture_device_remove(struct imx_media_video_dev *vdev)
   1042{
   1043	struct capture_priv *priv = to_capture_priv(vdev);
   1044
   1045	v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
   1046}
   1047EXPORT_SYMBOL_GPL(imx_media_capture_device_remove);
   1048
   1049MODULE_DESCRIPTION("i.MX5/6 v4l2 video capture interface driver");
   1050MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
   1051MODULE_LICENSE("GPL");