0001
0002
0003
0004
0005
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;
0033 struct device *dev;
0034
0035 struct imx_media_video_dev vdev;
0036 struct media_pad vdev_pad;
0037
0038 struct v4l2_subdev *src_sd;
0039 int src_sd_pad;
0040
0041 struct mutex mutex;
0042
0043 struct vb2_queue q;
0044 struct list_head ready_q;
0045 spinlock_t q_lock;
0046
0047 struct v4l2_ctrl_handler ctrl_hdlr;
0048
0049 bool legacy_api;
0050 };
0051
0052 #define to_capture_priv(v) container_of(v, struct capture_priv, vdev)
0053
0054
0055 #define VID_MEM_LIMIT SZ_64M
0056
0057
0058
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
0116
0117
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
0148
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
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
0219 s->r = priv->vdev.compose;
0220 break;
0221 case V4L2_SEL_TGT_COMPOSE_PADDED:
0222
0223
0224
0225
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
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
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
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
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
0686
0687
0688
0689
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
0697
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
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
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
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
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
0911 priv->md = container_of(v4l2_dev->mdev, struct imx_media_dev, md);
0912
0913 vfd->v4l2_dev = v4l2_dev;
0914
0915
0916 ret = capture_init_format(priv);
0917 if (ret < 0)
0918 return ret;
0919
0920
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
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
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
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
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
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
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");