Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Video Capture Subdev for Freescale i.MX5/6 SOC
0004  *
0005  * Copyright (c) 2012-2016 Mentor Graphics Inc.
0006  */
0007 #include <linux/delay.h>
0008 #include <linux/fs.h>
0009 #include <linux/module.h>
0010 #include <linux/of_platform.h>
0011 #include <linux/pinctrl/consumer.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/sched.h>
0014 #include <linux/slab.h>
0015 #include <linux/spinlock.h>
0016 #include <linux/timer.h>
0017 #include <media/v4l2-ctrls.h>
0018 #include <media/v4l2-device.h>
0019 #include <media/v4l2-event.h>
0020 #include <media/v4l2-fwnode.h>
0021 #include <media/v4l2-ioctl.h>
0022 #include <media/v4l2-mc.h>
0023 #include <media/v4l2-subdev.h>
0024 #include <media/videobuf2-dma-contig.h>
0025 #include <video/imx-ipu-v3.h>
0026 #include <media/imx.h>
0027 #include "imx-media.h"
0028 
0029 #define IMX_CAPTURE_NAME "imx-capture"
0030 
0031 struct capture_priv {
0032     struct imx_media_dev *md;       /* Media device */
0033     struct device *dev;         /* Physical device */
0034 
0035     struct imx_media_video_dev vdev;    /* Video device */
0036     struct media_pad vdev_pad;      /* Video device pad */
0037 
0038     struct v4l2_subdev *src_sd;     /* Source subdev */
0039     int src_sd_pad;             /* Source subdev pad */
0040 
0041     struct mutex mutex;         /* Protect vdev operations */
0042 
0043     struct vb2_queue q;         /* The videobuf2 queue */
0044     struct list_head ready_q;       /* List of queued buffers */
0045     spinlock_t q_lock;          /* Protect ready_q */
0046 
0047     struct v4l2_ctrl_handler ctrl_hdlr; /* Controls inherited from subdevs */
0048 
0049     bool legacy_api;            /* Use the legacy (pre-MC) API */
0050 };
0051 
0052 #define to_capture_priv(v) container_of(v, struct capture_priv, vdev)
0053 
0054 /* In bytes, per queue */
0055 #define VID_MEM_LIMIT   SZ_64M
0056 
0057 /* -----------------------------------------------------------------------------
0058  * MC-Centric Video IOCTLs
0059  */
0060 
0061 static const struct imx_media_pixfmt *capture_find_format(u32 code, u32 fourcc)
0062 {
0063     const struct imx_media_pixfmt *cc;
0064 
0065     cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV_RGB);
0066     if (cc) {
0067         enum imx_pixfmt_sel fmt_sel = cc->cs == IPUV3_COLORSPACE_YUV
0068                         ? PIXFMT_SEL_YUV : PIXFMT_SEL_RGB;
0069 
0070         cc = imx_media_find_pixel_format(fourcc, fmt_sel);
0071         if (!cc) {
0072             imx_media_enum_pixel_formats(&fourcc, 0, fmt_sel, 0);
0073             cc = imx_media_find_pixel_format(fourcc, fmt_sel);
0074         }
0075 
0076         return cc;
0077     }
0078 
0079     return imx_media_find_mbus_format(code, PIXFMT_SEL_ANY);
0080 }
0081 
0082 static int capture_querycap(struct file *file, void *fh,
0083                 struct v4l2_capability *cap)
0084 {
0085     struct capture_priv *priv = video_drvdata(file);
0086 
0087     strscpy(cap->driver, IMX_CAPTURE_NAME, sizeof(cap->driver));
0088     strscpy(cap->card, IMX_CAPTURE_NAME, sizeof(cap->card));
0089     snprintf(cap->bus_info, sizeof(cap->bus_info),
0090          "platform:%s", dev_name(priv->dev));
0091 
0092     return 0;
0093 }
0094 
0095 static int capture_enum_fmt_vid_cap(struct file *file, void *fh,
0096                     struct v4l2_fmtdesc *f)
0097 {
0098     return imx_media_enum_pixel_formats(&f->pixelformat, f->index,
0099                         PIXFMT_SEL_ANY, f->mbus_code);
0100 }
0101 
0102 static int capture_enum_framesizes(struct file *file, void *fh,
0103                    struct v4l2_frmsizeenum *fsize)
0104 {
0105     const struct imx_media_pixfmt *cc;
0106 
0107     if (fsize->index > 0)
0108         return -EINVAL;
0109 
0110     cc = imx_media_find_pixel_format(fsize->pixel_format, PIXFMT_SEL_ANY);
0111     if (!cc)
0112         return -EINVAL;
0113 
0114     /*
0115      * TODO: The constraints are hardware-specific and may depend on the
0116      * pixel format. This should come from the driver using
0117      * imx_media_capture.
0118      */
0119     fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
0120     fsize->stepwise.min_width = 1;
0121     fsize->stepwise.max_width = 65535;
0122     fsize->stepwise.min_height = 1;
0123     fsize->stepwise.max_height = 65535;
0124     fsize->stepwise.step_width = 1;
0125     fsize->stepwise.step_height = 1;
0126 
0127     return 0;
0128 }
0129 
0130 static int capture_g_fmt_vid_cap(struct file *file, void *fh,
0131                  struct v4l2_format *f)
0132 {
0133     struct capture_priv *priv = video_drvdata(file);
0134 
0135     f->fmt.pix = priv->vdev.fmt;
0136 
0137     return 0;
0138 }
0139 
0140 static const struct imx_media_pixfmt *
0141 __capture_try_fmt(struct v4l2_pix_format *pixfmt, struct v4l2_rect *compose)
0142 {
0143     struct v4l2_mbus_framefmt fmt_src;
0144     const struct imx_media_pixfmt *cc;
0145 
0146     /*
0147      * Find the pixel format, default to the first supported format if not
0148      * found.
0149      */
0150     cc = imx_media_find_pixel_format(pixfmt->pixelformat, PIXFMT_SEL_ANY);
0151     if (!cc) {
0152         imx_media_enum_pixel_formats(&pixfmt->pixelformat, 0,
0153                          PIXFMT_SEL_ANY, 0);
0154         cc = imx_media_find_pixel_format(pixfmt->pixelformat,
0155                          PIXFMT_SEL_ANY);
0156     }
0157 
0158     /* Allow IDMAC interweave but enforce field order from source. */
0159     if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) {
0160         switch (pixfmt->field) {
0161         case V4L2_FIELD_SEQ_TB:
0162             pixfmt->field = V4L2_FIELD_INTERLACED_TB;
0163             break;
0164         case V4L2_FIELD_SEQ_BT:
0165             pixfmt->field = V4L2_FIELD_INTERLACED_BT;
0166             break;
0167         default:
0168             break;
0169         }
0170     }
0171 
0172     v4l2_fill_mbus_format(&fmt_src, pixfmt, 0);
0173     imx_media_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src, cc);
0174 
0175     if (compose) {
0176         compose->width = fmt_src.width;
0177         compose->height = fmt_src.height;
0178     }
0179 
0180     return cc;
0181 }
0182 
0183 static int capture_try_fmt_vid_cap(struct file *file, void *fh,
0184                    struct v4l2_format *f)
0185 {
0186     __capture_try_fmt(&f->fmt.pix, NULL);
0187     return 0;
0188 }
0189 
0190 static int capture_s_fmt_vid_cap(struct file *file, void *fh,
0191                  struct v4l2_format *f)
0192 {
0193     struct capture_priv *priv = video_drvdata(file);
0194     const struct imx_media_pixfmt *cc;
0195 
0196     if (vb2_is_busy(&priv->q)) {
0197         dev_err(priv->dev, "%s queue busy\n", __func__);
0198         return -EBUSY;
0199     }
0200 
0201     cc = __capture_try_fmt(&f->fmt.pix, &priv->vdev.compose);
0202 
0203     priv->vdev.cc = cc;
0204     priv->vdev.fmt = f->fmt.pix;
0205 
0206     return 0;
0207 }
0208 
0209 static int capture_g_selection(struct file *file, void *fh,
0210                    struct v4l2_selection *s)
0211 {
0212     struct capture_priv *priv = video_drvdata(file);
0213 
0214     switch (s->target) {
0215     case V4L2_SEL_TGT_COMPOSE:
0216     case V4L2_SEL_TGT_COMPOSE_DEFAULT:
0217     case V4L2_SEL_TGT_COMPOSE_BOUNDS:
0218         /* The compose rectangle is fixed to the source format. */
0219         s->r = priv->vdev.compose;
0220         break;
0221     case V4L2_SEL_TGT_COMPOSE_PADDED:
0222         /*
0223          * The hardware writes with a configurable but fixed DMA burst
0224          * size. If the source format width is not burst size aligned,
0225          * the written frame contains padding to the right.
0226          */
0227         s->r.left = 0;
0228         s->r.top = 0;
0229         s->r.width = priv->vdev.fmt.width;
0230         s->r.height = priv->vdev.fmt.height;
0231         break;
0232     default:
0233         return -EINVAL;
0234     }
0235 
0236     return 0;
0237 }
0238 
0239 static int capture_subscribe_event(struct v4l2_fh *fh,
0240                    const struct v4l2_event_subscription *sub)
0241 {
0242     switch (sub->type) {
0243     case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR:
0244         return v4l2_event_subscribe(fh, sub, 0, NULL);
0245     default:
0246         return -EINVAL;
0247     }
0248 }
0249 
0250 static const struct v4l2_ioctl_ops capture_ioctl_ops = {
0251     .vidioc_querycap        = capture_querycap,
0252 
0253     .vidioc_enum_fmt_vid_cap    = capture_enum_fmt_vid_cap,
0254     .vidioc_enum_framesizes     = capture_enum_framesizes,
0255 
0256     .vidioc_g_fmt_vid_cap       = capture_g_fmt_vid_cap,
0257     .vidioc_try_fmt_vid_cap     = capture_try_fmt_vid_cap,
0258     .vidioc_s_fmt_vid_cap       = capture_s_fmt_vid_cap,
0259 
0260     .vidioc_g_selection     = capture_g_selection,
0261 
0262     .vidioc_reqbufs         = vb2_ioctl_reqbufs,
0263     .vidioc_create_bufs     = vb2_ioctl_create_bufs,
0264     .vidioc_prepare_buf     = vb2_ioctl_prepare_buf,
0265     .vidioc_querybuf        = vb2_ioctl_querybuf,
0266     .vidioc_qbuf            = vb2_ioctl_qbuf,
0267     .vidioc_dqbuf           = vb2_ioctl_dqbuf,
0268     .vidioc_expbuf          = vb2_ioctl_expbuf,
0269     .vidioc_streamon        = vb2_ioctl_streamon,
0270     .vidioc_streamoff       = vb2_ioctl_streamoff,
0271 
0272     .vidioc_subscribe_event     = capture_subscribe_event,
0273     .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
0274 };
0275 
0276 /* -----------------------------------------------------------------------------
0277  * Legacy Video IOCTLs
0278  */
0279 
0280 static int capture_legacy_enum_framesizes(struct file *file, void *fh,
0281                       struct v4l2_frmsizeenum *fsize)
0282 {
0283     struct capture_priv *priv = video_drvdata(file);
0284     const struct imx_media_pixfmt *cc;
0285     struct v4l2_subdev_frame_size_enum fse = {
0286         .index = fsize->index,
0287         .pad = priv->src_sd_pad,
0288         .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0289     };
0290     int ret;
0291 
0292     cc = imx_media_find_pixel_format(fsize->pixel_format, PIXFMT_SEL_ANY);
0293     if (!cc)
0294         return -EINVAL;
0295 
0296     fse.code = cc->codes ? cc->codes[0] : 0;
0297 
0298     ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_size, NULL, &fse);
0299     if (ret)
0300         return ret;
0301 
0302     if (fse.min_width == fse.max_width &&
0303         fse.min_height == fse.max_height) {
0304         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
0305         fsize->discrete.width = fse.min_width;
0306         fsize->discrete.height = fse.min_height;
0307     } else {
0308         fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
0309         fsize->stepwise.min_width = fse.min_width;
0310         fsize->stepwise.max_width = fse.max_width;
0311         fsize->stepwise.min_height = fse.min_height;
0312         fsize->stepwise.max_height = fse.max_height;
0313         fsize->stepwise.step_width = 1;
0314         fsize->stepwise.step_height = 1;
0315     }
0316 
0317     return 0;
0318 }
0319 
0320 static int capture_legacy_enum_frameintervals(struct file *file, void *fh,
0321                           struct v4l2_frmivalenum *fival)
0322 {
0323     struct capture_priv *priv = video_drvdata(file);
0324     const struct imx_media_pixfmt *cc;
0325     struct v4l2_subdev_frame_interval_enum fie = {
0326         .index = fival->index,
0327         .pad = priv->src_sd_pad,
0328         .width = fival->width,
0329         .height = fival->height,
0330         .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0331     };
0332     int ret;
0333 
0334     cc = imx_media_find_pixel_format(fival->pixel_format, PIXFMT_SEL_ANY);
0335     if (!cc)
0336         return -EINVAL;
0337 
0338     fie.code = cc->codes ? cc->codes[0] : 0;
0339 
0340     ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_interval,
0341                    NULL, &fie);
0342     if (ret)
0343         return ret;
0344 
0345     fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
0346     fival->discrete = fie.interval;
0347 
0348     return 0;
0349 }
0350 
0351 static int capture_legacy_enum_fmt_vid_cap(struct file *file, void *fh,
0352                        struct v4l2_fmtdesc *f)
0353 {
0354     struct capture_priv *priv = video_drvdata(file);
0355     const struct imx_media_pixfmt *cc_src;
0356     struct v4l2_subdev_format fmt_src;
0357     u32 fourcc;
0358     int ret;
0359 
0360     fmt_src.pad = priv->src_sd_pad;
0361     fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
0362     ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
0363     if (ret) {
0364         dev_err(priv->dev, "failed to get src_sd format\n");
0365         return ret;
0366     }
0367 
0368     cc_src = imx_media_find_ipu_format(fmt_src.format.code,
0369                        PIXFMT_SEL_YUV_RGB);
0370     if (cc_src) {
0371         enum imx_pixfmt_sel fmt_sel =
0372             (cc_src->cs == IPUV3_COLORSPACE_YUV) ?
0373             PIXFMT_SEL_YUV : PIXFMT_SEL_RGB;
0374 
0375         ret = imx_media_enum_pixel_formats(&fourcc, f->index, fmt_sel,
0376                            0);
0377         if (ret)
0378             return ret;
0379     } else {
0380         cc_src = imx_media_find_mbus_format(fmt_src.format.code,
0381                             PIXFMT_SEL_ANY);
0382         if (WARN_ON(!cc_src))
0383             return -EINVAL;
0384 
0385         if (f->index != 0)
0386             return -EINVAL;
0387         fourcc = cc_src->fourcc;
0388     }
0389 
0390     f->pixelformat = fourcc;
0391 
0392     return 0;
0393 }
0394 
0395 static const struct imx_media_pixfmt *
0396 __capture_legacy_try_fmt(struct capture_priv *priv,
0397              struct v4l2_subdev_format *fmt_src,
0398              struct v4l2_pix_format *pixfmt)
0399 {
0400     const struct imx_media_pixfmt *cc;
0401 
0402     cc = capture_find_format(fmt_src->format.code, pixfmt->pixelformat);
0403     if (WARN_ON(!cc))
0404         return NULL;
0405 
0406     /* allow IDMAC interweave but enforce field order from source */
0407     if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) {
0408         switch (fmt_src->format.field) {
0409         case V4L2_FIELD_SEQ_TB:
0410             fmt_src->format.field = V4L2_FIELD_INTERLACED_TB;
0411             break;
0412         case V4L2_FIELD_SEQ_BT:
0413             fmt_src->format.field = V4L2_FIELD_INTERLACED_BT;
0414             break;
0415         default:
0416             break;
0417         }
0418     }
0419 
0420     imx_media_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src->format, cc);
0421 
0422     return cc;
0423 }
0424 
0425 static int capture_legacy_try_fmt_vid_cap(struct file *file, void *fh,
0426                       struct v4l2_format *f)
0427 {
0428     struct capture_priv *priv = video_drvdata(file);
0429     struct v4l2_subdev_format fmt_src;
0430     int ret;
0431 
0432     fmt_src.pad = priv->src_sd_pad;
0433     fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
0434     ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
0435     if (ret)
0436         return ret;
0437 
0438     if (!__capture_legacy_try_fmt(priv, &fmt_src, &f->fmt.pix))
0439         return -EINVAL;
0440 
0441     return 0;
0442 }
0443 
0444 static int capture_legacy_s_fmt_vid_cap(struct file *file, void *fh,
0445                     struct v4l2_format *f)
0446 {
0447     struct capture_priv *priv = video_drvdata(file);
0448     struct v4l2_subdev_format fmt_src;
0449     const struct imx_media_pixfmt *cc;
0450     int ret;
0451 
0452     if (vb2_is_busy(&priv->q)) {
0453         dev_err(priv->dev, "%s queue busy\n", __func__);
0454         return -EBUSY;
0455     }
0456 
0457     fmt_src.pad = priv->src_sd_pad;
0458     fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
0459     ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
0460     if (ret)
0461         return ret;
0462 
0463     cc = __capture_legacy_try_fmt(priv, &fmt_src, &f->fmt.pix);
0464     if (!cc)
0465         return -EINVAL;
0466 
0467     priv->vdev.cc = cc;
0468     priv->vdev.fmt = f->fmt.pix;
0469     priv->vdev.compose.width = fmt_src.format.width;
0470     priv->vdev.compose.height = fmt_src.format.height;
0471 
0472     return 0;
0473 }
0474 
0475 static int capture_legacy_querystd(struct file *file, void *fh,
0476                    v4l2_std_id *std)
0477 {
0478     struct capture_priv *priv = video_drvdata(file);
0479 
0480     return v4l2_subdev_call(priv->src_sd, video, querystd, std);
0481 }
0482 
0483 static int capture_legacy_g_std(struct file *file, void *fh, v4l2_std_id *std)
0484 {
0485     struct capture_priv *priv = video_drvdata(file);
0486 
0487     return v4l2_subdev_call(priv->src_sd, video, g_std, std);
0488 }
0489 
0490 static int capture_legacy_s_std(struct file *file, void *fh, v4l2_std_id std)
0491 {
0492     struct capture_priv *priv = video_drvdata(file);
0493 
0494     if (vb2_is_busy(&priv->q))
0495         return -EBUSY;
0496 
0497     return v4l2_subdev_call(priv->src_sd, video, s_std, std);
0498 }
0499 
0500 static int capture_legacy_g_parm(struct file *file, void *fh,
0501                  struct v4l2_streamparm *a)
0502 {
0503     struct capture_priv *priv = video_drvdata(file);
0504     struct v4l2_subdev_frame_interval fi;
0505     int ret;
0506 
0507     if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0508         return -EINVAL;
0509 
0510     memset(&fi, 0, sizeof(fi));
0511     fi.pad = priv->src_sd_pad;
0512     ret = v4l2_subdev_call(priv->src_sd, video, g_frame_interval, &fi);
0513     if (ret < 0)
0514         return ret;
0515 
0516     a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
0517     a->parm.capture.timeperframe = fi.interval;
0518 
0519     return 0;
0520 }
0521 
0522 static int capture_legacy_s_parm(struct file *file, void *fh,
0523                  struct v4l2_streamparm *a)
0524 {
0525     struct capture_priv *priv = video_drvdata(file);
0526     struct v4l2_subdev_frame_interval fi;
0527     int ret;
0528 
0529     if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0530         return -EINVAL;
0531 
0532     memset(&fi, 0, sizeof(fi));
0533     fi.pad = priv->src_sd_pad;
0534     fi.interval = a->parm.capture.timeperframe;
0535     ret = v4l2_subdev_call(priv->src_sd, video, s_frame_interval, &fi);
0536     if (ret < 0)
0537         return ret;
0538 
0539     a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
0540     a->parm.capture.timeperframe = fi.interval;
0541 
0542     return 0;
0543 }
0544 
0545 static int capture_legacy_subscribe_event(struct v4l2_fh *fh,
0546                       const struct v4l2_event_subscription *sub)
0547 {
0548     switch (sub->type) {
0549     case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR:
0550         return v4l2_event_subscribe(fh, sub, 0, NULL);
0551     case V4L2_EVENT_SOURCE_CHANGE:
0552         return v4l2_src_change_event_subscribe(fh, sub);
0553     case V4L2_EVENT_CTRL:
0554         return v4l2_ctrl_subscribe_event(fh, sub);
0555     default:
0556         return -EINVAL;
0557     }
0558 }
0559 
0560 static const struct v4l2_ioctl_ops capture_legacy_ioctl_ops = {
0561     .vidioc_querycap        = capture_querycap,
0562 
0563     .vidioc_enum_framesizes     = capture_legacy_enum_framesizes,
0564     .vidioc_enum_frameintervals = capture_legacy_enum_frameintervals,
0565 
0566     .vidioc_enum_fmt_vid_cap    = capture_legacy_enum_fmt_vid_cap,
0567     .vidioc_g_fmt_vid_cap       = capture_g_fmt_vid_cap,
0568     .vidioc_try_fmt_vid_cap     = capture_legacy_try_fmt_vid_cap,
0569     .vidioc_s_fmt_vid_cap       = capture_legacy_s_fmt_vid_cap,
0570 
0571     .vidioc_querystd        = capture_legacy_querystd,
0572     .vidioc_g_std           = capture_legacy_g_std,
0573     .vidioc_s_std           = capture_legacy_s_std,
0574 
0575     .vidioc_g_selection     = capture_g_selection,
0576 
0577     .vidioc_g_parm          = capture_legacy_g_parm,
0578     .vidioc_s_parm          = capture_legacy_s_parm,
0579 
0580     .vidioc_reqbufs         = vb2_ioctl_reqbufs,
0581     .vidioc_create_bufs     = vb2_ioctl_create_bufs,
0582     .vidioc_prepare_buf     = vb2_ioctl_prepare_buf,
0583     .vidioc_querybuf        = vb2_ioctl_querybuf,
0584     .vidioc_qbuf            = vb2_ioctl_qbuf,
0585     .vidioc_dqbuf           = vb2_ioctl_dqbuf,
0586     .vidioc_expbuf          = vb2_ioctl_expbuf,
0587     .vidioc_streamon        = vb2_ioctl_streamon,
0588     .vidioc_streamoff       = vb2_ioctl_streamoff,
0589 
0590     .vidioc_subscribe_event     = capture_legacy_subscribe_event,
0591     .vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
0592 };
0593 
0594 /* -----------------------------------------------------------------------------
0595  * Queue Operations
0596  */
0597 
0598 static int capture_queue_setup(struct vb2_queue *vq,
0599                    unsigned int *nbuffers,
0600                    unsigned int *nplanes,
0601                    unsigned int sizes[],
0602                    struct device *alloc_devs[])
0603 {
0604     struct capture_priv *priv = vb2_get_drv_priv(vq);
0605     struct v4l2_pix_format *pix = &priv->vdev.fmt;
0606     unsigned int count = *nbuffers;
0607 
0608     if (vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
0609         return -EINVAL;
0610 
0611     if (*nplanes) {
0612         if (*nplanes != 1 || sizes[0] < pix->sizeimage)
0613             return -EINVAL;
0614         count += vq->num_buffers;
0615     }
0616 
0617     count = min_t(__u32, VID_MEM_LIMIT / pix->sizeimage, count);
0618 
0619     if (*nplanes)
0620         *nbuffers = (count < vq->num_buffers) ? 0 :
0621             count - vq->num_buffers;
0622     else
0623         *nbuffers = count;
0624 
0625     *nplanes = 1;
0626     sizes[0] = pix->sizeimage;
0627 
0628     return 0;
0629 }
0630 
0631 static int capture_buf_init(struct vb2_buffer *vb)
0632 {
0633     struct imx_media_buffer *buf = to_imx_media_vb(vb);
0634 
0635     INIT_LIST_HEAD(&buf->list);
0636 
0637     return 0;
0638 }
0639 
0640 static int capture_buf_prepare(struct vb2_buffer *vb)
0641 {
0642     struct vb2_queue *vq = vb->vb2_queue;
0643     struct capture_priv *priv = vb2_get_drv_priv(vq);
0644     struct v4l2_pix_format *pix = &priv->vdev.fmt;
0645 
0646     if (vb2_plane_size(vb, 0) < pix->sizeimage) {
0647         dev_err(priv->dev,
0648             "data will not fit into plane (%lu < %lu)\n",
0649             vb2_plane_size(vb, 0), (long)pix->sizeimage);
0650         return -EINVAL;
0651     }
0652 
0653     vb2_set_plane_payload(vb, 0, pix->sizeimage);
0654 
0655     return 0;
0656 }
0657 
0658 static void capture_buf_queue(struct vb2_buffer *vb)
0659 {
0660     struct capture_priv *priv = vb2_get_drv_priv(vb->vb2_queue);
0661     struct imx_media_buffer *buf = to_imx_media_vb(vb);
0662     unsigned long flags;
0663 
0664     spin_lock_irqsave(&priv->q_lock, flags);
0665 
0666     list_add_tail(&buf->list, &priv->ready_q);
0667 
0668     spin_unlock_irqrestore(&priv->q_lock, flags);
0669 }
0670 
0671 static int capture_validate_fmt(struct capture_priv *priv)
0672 {
0673     struct v4l2_subdev_format fmt_src;
0674     const struct imx_media_pixfmt *cc;
0675     int ret;
0676 
0677     /* Retrieve the media bus format on the source subdev. */
0678     fmt_src.pad = priv->src_sd_pad;
0679     fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
0680     ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
0681     if (ret)
0682         return ret;
0683 
0684     /*
0685      * Verify that the media bus size matches the size set on the video
0686      * node. It is sufficient to check the compose rectangle size without
0687      * checking the rounded size from vdev.fmt, as the rounded size is
0688      * derived directly from the compose rectangle size, and will thus
0689      * always match if the compose rectangle matches.
0690      */
0691     if (priv->vdev.compose.width != fmt_src.format.width ||
0692         priv->vdev.compose.height != fmt_src.format.height)
0693         return -EPIPE;
0694 
0695     /*
0696      * Verify that the media bus code is compatible with the pixel format
0697      * set on the video node.
0698      */
0699     cc = capture_find_format(fmt_src.format.code, 0);
0700     if (!cc || priv->vdev.cc->cs != cc->cs)
0701         return -EPIPE;
0702 
0703     return 0;
0704 }
0705 
0706 static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
0707 {
0708     struct capture_priv *priv = vb2_get_drv_priv(vq);
0709     struct imx_media_buffer *buf, *tmp;
0710     unsigned long flags;
0711     int ret;
0712 
0713     ret = capture_validate_fmt(priv);
0714     if (ret) {
0715         dev_err(priv->dev, "capture format not valid\n");
0716         goto return_bufs;
0717     }
0718 
0719     ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
0720                         true);
0721     if (ret) {
0722         dev_err(priv->dev, "pipeline start failed with %d\n", ret);
0723         goto return_bufs;
0724     }
0725 
0726     return 0;
0727 
0728 return_bufs:
0729     spin_lock_irqsave(&priv->q_lock, flags);
0730     list_for_each_entry_safe(buf, tmp, &priv->ready_q, list) {
0731         list_del(&buf->list);
0732         vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
0733     }
0734     spin_unlock_irqrestore(&priv->q_lock, flags);
0735     return ret;
0736 }
0737 
0738 static void capture_stop_streaming(struct vb2_queue *vq)
0739 {
0740     struct capture_priv *priv = vb2_get_drv_priv(vq);
0741     struct imx_media_buffer *frame;
0742     struct imx_media_buffer *tmp;
0743     unsigned long flags;
0744     int ret;
0745 
0746     ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
0747                         false);
0748     if (ret)
0749         dev_warn(priv->dev, "pipeline stop failed with %d\n", ret);
0750 
0751     /* release all active buffers */
0752     spin_lock_irqsave(&priv->q_lock, flags);
0753     list_for_each_entry_safe(frame, tmp, &priv->ready_q, list) {
0754         list_del(&frame->list);
0755         vb2_buffer_done(&frame->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
0756     }
0757     spin_unlock_irqrestore(&priv->q_lock, flags);
0758 }
0759 
0760 static const struct vb2_ops capture_qops = {
0761     .queue_setup     = capture_queue_setup,
0762     .buf_init        = capture_buf_init,
0763     .buf_prepare     = capture_buf_prepare,
0764     .buf_queue   = capture_buf_queue,
0765     .wait_prepare    = vb2_ops_wait_prepare,
0766     .wait_finish     = vb2_ops_wait_finish,
0767     .start_streaming = capture_start_streaming,
0768     .stop_streaming  = capture_stop_streaming,
0769 };
0770 
0771 /* -----------------------------------------------------------------------------
0772  * File Operations
0773  */
0774 
0775 static int capture_open(struct file *file)
0776 {
0777     struct capture_priv *priv = video_drvdata(file);
0778     struct video_device *vfd = priv->vdev.vfd;
0779     int ret;
0780 
0781     if (mutex_lock_interruptible(&priv->mutex))
0782         return -ERESTARTSYS;
0783 
0784     ret = v4l2_fh_open(file);
0785     if (ret) {
0786         dev_err(priv->dev, "v4l2_fh_open failed\n");
0787         goto out;
0788     }
0789 
0790     ret = v4l2_pipeline_pm_get(&vfd->entity);
0791     if (ret)
0792         v4l2_fh_release(file);
0793 
0794 out:
0795     mutex_unlock(&priv->mutex);
0796     return ret;
0797 }
0798 
0799 static int capture_release(struct file *file)
0800 {
0801     struct capture_priv *priv = video_drvdata(file);
0802     struct video_device *vfd = priv->vdev.vfd;
0803     struct vb2_queue *vq = &priv->q;
0804 
0805     mutex_lock(&priv->mutex);
0806 
0807     if (file->private_data == vq->owner) {
0808         vb2_queue_release(vq);
0809         vq->owner = NULL;
0810     }
0811 
0812     v4l2_pipeline_pm_put(&vfd->entity);
0813 
0814     v4l2_fh_release(file);
0815     mutex_unlock(&priv->mutex);
0816     return 0;
0817 }
0818 
0819 static const struct v4l2_file_operations capture_fops = {
0820     .owner      = THIS_MODULE,
0821     .open       = capture_open,
0822     .release    = capture_release,
0823     .poll       = vb2_fop_poll,
0824     .unlocked_ioctl = video_ioctl2,
0825     .mmap       = vb2_fop_mmap,
0826 };
0827 
0828 /* -----------------------------------------------------------------------------
0829  * Public API
0830  */
0831 
0832 struct imx_media_buffer *
0833 imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
0834 {
0835     struct capture_priv *priv = to_capture_priv(vdev);
0836     struct imx_media_buffer *buf = NULL;
0837     unsigned long flags;
0838 
0839     spin_lock_irqsave(&priv->q_lock, flags);
0840 
0841     /* get next queued buffer */
0842     if (!list_empty(&priv->ready_q)) {
0843         buf = list_entry(priv->ready_q.next, struct imx_media_buffer,
0844                  list);
0845         list_del(&buf->list);
0846     }
0847 
0848     spin_unlock_irqrestore(&priv->q_lock, flags);
0849 
0850     return buf;
0851 }
0852 EXPORT_SYMBOL_GPL(imx_media_capture_device_next_buf);
0853 
0854 void imx_media_capture_device_error(struct imx_media_video_dev *vdev)
0855 {
0856     struct capture_priv *priv = to_capture_priv(vdev);
0857     struct vb2_queue *vq = &priv->q;
0858     unsigned long flags;
0859 
0860     if (!vb2_is_streaming(vq))
0861         return;
0862 
0863     spin_lock_irqsave(&priv->q_lock, flags);
0864     vb2_queue_error(vq);
0865     spin_unlock_irqrestore(&priv->q_lock, flags);
0866 }
0867 EXPORT_SYMBOL_GPL(imx_media_capture_device_error);
0868 
0869 static int capture_init_format(struct capture_priv *priv)
0870 {
0871     struct v4l2_subdev_format fmt_src = {
0872         .pad = priv->src_sd_pad,
0873         .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0874     };
0875     struct imx_media_video_dev *vdev = &priv->vdev;
0876     int ret;
0877 
0878     if (priv->legacy_api) {
0879         ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL,
0880                        &fmt_src);
0881         if (ret) {
0882             dev_err(priv->dev, "failed to get source format\n");
0883             return ret;
0884         }
0885     } else {
0886         fmt_src.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
0887         fmt_src.format.width = IMX_MEDIA_DEF_PIX_WIDTH;
0888         fmt_src.format.height = IMX_MEDIA_DEF_PIX_HEIGHT;
0889     }
0890 
0891     imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt, &fmt_src.format, NULL);
0892     vdev->compose.width = fmt_src.format.width;
0893     vdev->compose.height = fmt_src.format.height;
0894 
0895     vdev->cc = imx_media_find_pixel_format(vdev->fmt.pixelformat,
0896                            PIXFMT_SEL_ANY);
0897 
0898     return 0;
0899 }
0900 
0901 int imx_media_capture_device_register(struct imx_media_video_dev *vdev,
0902                       u32 link_flags)
0903 {
0904     struct capture_priv *priv = to_capture_priv(vdev);
0905     struct v4l2_subdev *sd = priv->src_sd;
0906     struct v4l2_device *v4l2_dev = sd->v4l2_dev;
0907     struct video_device *vfd = vdev->vfd;
0908     int ret;
0909 
0910     /* get media device */
0911     priv->md = container_of(v4l2_dev->mdev, struct imx_media_dev, md);
0912 
0913     vfd->v4l2_dev = v4l2_dev;
0914 
0915     /* Initialize the default format and compose rectangle. */
0916     ret = capture_init_format(priv);
0917     if (ret < 0)
0918         return ret;
0919 
0920     /* Register the video device. */
0921     ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
0922     if (ret) {
0923         dev_err(priv->dev, "Failed to register video device\n");
0924         return ret;
0925     }
0926 
0927     dev_info(priv->dev, "Registered %s as /dev/%s\n", vfd->name,
0928          video_device_node_name(vfd));
0929 
0930     /* Create the link from the src_sd devnode pad to device node. */
0931     if (link_flags & MEDIA_LNK_FL_IMMUTABLE)
0932         link_flags |= MEDIA_LNK_FL_ENABLED;
0933     ret = media_create_pad_link(&sd->entity, priv->src_sd_pad,
0934                     &vfd->entity, 0, link_flags);
0935     if (ret) {
0936         dev_err(priv->dev, "failed to create link to device node\n");
0937         video_unregister_device(vfd);
0938         return ret;
0939     }
0940 
0941     /* Add vdev to the video devices list. */
0942     imx_media_add_video_device(priv->md, vdev);
0943 
0944     return 0;
0945 }
0946 EXPORT_SYMBOL_GPL(imx_media_capture_device_register);
0947 
0948 void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev)
0949 {
0950     struct capture_priv *priv = to_capture_priv(vdev);
0951     struct video_device *vfd = priv->vdev.vfd;
0952 
0953     media_entity_cleanup(&vfd->entity);
0954     video_unregister_device(vfd);
0955 }
0956 EXPORT_SYMBOL_GPL(imx_media_capture_device_unregister);
0957 
0958 struct imx_media_video_dev *
0959 imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd,
0960                   int pad, bool legacy_api)
0961 {
0962     struct capture_priv *priv;
0963     struct video_device *vfd;
0964     struct vb2_queue *vq;
0965     int ret;
0966 
0967     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0968     if (!priv)
0969         return ERR_PTR(-ENOMEM);
0970 
0971     priv->src_sd = src_sd;
0972     priv->src_sd_pad = pad;
0973     priv->dev = dev;
0974     priv->legacy_api = legacy_api;
0975 
0976     mutex_init(&priv->mutex);
0977     INIT_LIST_HEAD(&priv->ready_q);
0978     spin_lock_init(&priv->q_lock);
0979 
0980     /* Allocate and initialize the video device. */
0981     vfd = video_device_alloc();
0982     if (!vfd)
0983         return ERR_PTR(-ENOMEM);
0984 
0985     vfd->fops = &capture_fops;
0986     vfd->ioctl_ops = legacy_api ? &capture_legacy_ioctl_ops
0987                : &capture_ioctl_ops;
0988     vfd->minor = -1;
0989     vfd->release = video_device_release;
0990     vfd->vfl_dir = VFL_DIR_RX;
0991     vfd->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
0992     vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
0993              | (!legacy_api ? V4L2_CAP_IO_MC : 0);
0994     vfd->lock = &priv->mutex;
0995     vfd->queue = &priv->q;
0996 
0997     snprintf(vfd->name, sizeof(vfd->name), "%s capture", src_sd->name);
0998 
0999     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 }
1039 EXPORT_SYMBOL_GPL(imx_media_capture_device_init);
1040 
1041 void 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 }
1047 EXPORT_SYMBOL_GPL(imx_media_capture_device_remove);
1048 
1049 MODULE_DESCRIPTION("i.MX5/6 v4l2 video capture interface driver");
1050 MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
1051 MODULE_LICENSE("GPL");