Lines Matching +full:not +full:- +full:swapped
1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (C) 2017-2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
6 * Based on soc-camera driver "soc_camera/sh_mobile_ceu_camera.c"
9 * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
16 #include <linux/dma-mapping.h>
33 #include <media/v4l2-async.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/v4l2-dev.h>
37 #include <media/v4l2-device.h>
38 #include <media/v4l2-event.h>
39 #include <media/v4l2-fwnode.h>
40 #include <media/v4l2-image-sizes.h>
41 #include <media/v4l2-ioctl.h>
42 #include <media/v4l2-mediabus.h>
43 #include <media/videobuf2-dma-contig.h>
45 #include <media/drv-intf/renesas-ceu.h>
47 #define DRIVER_NAME "renesas-ceu"
89 /* Swap all input data in 8-bit, 16-bits and 32-bits units (Figure 46.45). */
106 /* One-frame capture end interrupt. */
119 * ceu_bus_fmt - describe a 8-bits yuyv format the sensor can produce
123 * @fmt_order_swap: swapped CEU_CAMCR.DTARY ordering of input components
125 * @swapped: does Cr appear before Cb?
133 bool swapped; member
139 * ceu_buffer - Link vb2 buffer to the list of available buffers.
152 * ceu_subdev - Wraps v4l2 sub-device and provides async subdevice.
158 /* per-subdevice mbus configuration options */
169 * ceu_device - CEU device instance
199 /* mlock - lock access to interface reset and vb2 queue */
202 /* lock - lock access to capture buffer queue and active buffer */
205 /* base - CEU memory base address */
214 /* --- CEU memory output formats --- */
217 * ceu_fmt - describe a memory output format supported by CEU interface.
228 * ceu_format_list - List of supported memory output formats
231 * formats are available thanks to CEU re-ordering and sub-sampling
275 if (fmt->fourcc == fourcc) in get_ceu_fmt_from_fourcc()
283 switch (pix->pixelformat) { in ceu_fmt_mplane()
299 /* --- CEU HW operations --- */
303 iowrite32(data, priv->base + reg_offs); in ceu_write()
308 return ioread32(priv->base + reg_offs); in ceu_read()
312 * ceu_soft_reset() - Software reset the CEU interface.
315 * Returns 0 for success, -EIO for error.
330 dev_err(ceudev->dev, "soft reset time out\n"); in ceu_soft_reset()
331 return -EIO; in ceu_soft_reset()
340 /* If we get here, CEU has not reset properly. */ in ceu_soft_reset()
341 return -EIO; in ceu_soft_reset()
344 /* --- CEU Capture Operations --- */
347 * ceu_hw_config() - Configure CEU interface registers.
352 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_hw_config()
353 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_hw_config()
354 struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; in ceu_hw_config()
355 unsigned int mbus_flags = ceu_sd->mbus_flags; in ceu_hw_config()
364 capwr = (pix->height << 16) | pix->width * mbus_fmt->bpp / 8; in ceu_hw_config()
382 * If the memory output planar format is 'swapped' (Cr before Cb) and in ceu_hw_config()
383 * input format is not, use the swapped version of CAMCR.DTARY. in ceu_hw_config()
385 * If the memory output planar format is not 'swapped' (Cb before Cr) in ceu_hw_config()
386 * and input format is, use the swapped version of CAMCR.DTARY. in ceu_hw_config()
393 switch (pix->pixelformat) { in ceu_hw_config()
401 cfzsr = (pix->height << 16) | pix->width; in ceu_hw_config()
402 cdwdr = pix->plane_fmt[0].bytesperline; in ceu_hw_config()
405 /* Non-swapped planar image capture mode. */ in ceu_hw_config()
410 if (mbus_fmt->swapped) in ceu_hw_config()
411 camcr = mbus_fmt->fmt_order_swap; in ceu_hw_config()
413 camcr = mbus_fmt->fmt_order; in ceu_hw_config()
415 cfzsr = (pix->height << 16) | pix->width; in ceu_hw_config()
416 cdwdr = pix->width; in ceu_hw_config()
419 /* Swapped planar image capture mode. */ in ceu_hw_config()
424 if (mbus_fmt->swapped) in ceu_hw_config()
425 camcr = mbus_fmt->fmt_order; in ceu_hw_config()
427 camcr = mbus_fmt->fmt_order_swap; in ceu_hw_config()
429 cfzsr = (pix->height << 16) | pix->width; in ceu_hw_config()
430 cdwdr = pix->width; in ceu_hw_config()
434 return -EINVAL; in ceu_hw_config()
452 /* TODO: 16 bit bus width require re-calculation of cdwdr and cfzsr */ in ceu_hw_config()
461 * ceu_capture() - Trigger start of a capture sequence.
467 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_capture()
471 vb2_dma_contig_plane_dma_addr(&ceudev->active->vb2_buf, 0); in ceu_capture()
474 /* Ignore CbCr plane for non multi-planar image formats. */ in ceu_capture()
477 vb2_dma_contig_plane_dma_addr(&ceudev->active->vb2_buf, in ceu_capture()
484 * one-frame capture mode. in ceu_capture()
500 ceu_write(ceudev, CEU_CETCR, ~ceudev->irq_mask); in ceu_irq()
506 spin_lock(&ceudev->lock); in ceu_irq()
509 vbuf = ceudev->active; in ceu_irq()
511 spin_unlock(&ceudev->lock); in ceu_irq()
517 * and the image of that frame is not captured correctly. in ceu_irq()
520 dev_err(ceudev->dev, "VBP interrupt: abort capture\n"); in ceu_irq()
525 vbuf->vb2_buf.timestamp = ktime_get_ns(); in ceu_irq()
526 vbuf->sequence = ceudev->sequence++; in ceu_irq()
527 vbuf->field = ceudev->field; in ceu_irq()
530 if (!list_empty(&ceudev->capture)) { in ceu_irq()
531 buf = list_first_entry(&ceudev->capture, struct ceu_buffer, in ceu_irq()
533 list_del(&buf->queue); in ceu_irq()
534 ceudev->active = &buf->vb; in ceu_irq()
540 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); in ceu_irq()
542 spin_unlock(&ceudev->lock); in ceu_irq()
548 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR); in ceu_irq()
550 list_for_each_entry(buf, &ceudev->capture, queue) in ceu_irq()
551 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in ceu_irq()
553 spin_unlock(&ceudev->lock); in ceu_irq()
558 /* --- CEU Videobuf2 operations --- */
565 plane->sizeimage = szimage; in ceu_update_plane_sizes()
566 if (plane->bytesperline < bpl || plane->bytesperline > CEU_MAX_BPL) in ceu_update_plane_sizes()
567 plane->bytesperline = bpl; in ceu_update_plane_sizes()
571 * ceu_calc_plane_sizes() - Fill per-plane 'struct v4l2_plane_pix_format'
584 switch (pix->pixelformat) { in ceu_calc_plane_sizes()
589 pix->num_planes = 1; in ceu_calc_plane_sizes()
590 bpl = pix->width * ceu_fmt->bpp / 8; in ceu_calc_plane_sizes()
591 szimage = pix->height * bpl; in ceu_calc_plane_sizes()
592 ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); in ceu_calc_plane_sizes()
597 pix->num_planes = 2; in ceu_calc_plane_sizes()
598 bpl = pix->width; in ceu_calc_plane_sizes()
599 szimage = pix->height * pix->width; in ceu_calc_plane_sizes()
600 ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); in ceu_calc_plane_sizes()
601 ceu_update_plane_sizes(&pix->plane_fmt[1], bpl, szimage / 2); in ceu_calc_plane_sizes()
607 pix->num_planes = 2; in ceu_calc_plane_sizes()
608 bpl = pix->width; in ceu_calc_plane_sizes()
609 szimage = pix->height * pix->width; in ceu_calc_plane_sizes()
610 ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); in ceu_calc_plane_sizes()
611 ceu_update_plane_sizes(&pix->plane_fmt[1], bpl, szimage); in ceu_calc_plane_sizes()
617 * ceu_vb2_setup() - is called to check whether the driver can accept the
626 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_vb2_setup()
631 for (i = 0; i < pix->num_planes; i++) in ceu_vb2_setup()
632 if (sizes[i] < pix->plane_fmt[i].sizeimage) in ceu_vb2_setup()
633 return -EINVAL; in ceu_vb2_setup()
638 /* num_planes not set: called from REQBUFS, just set plane sizes. */ in ceu_vb2_setup()
639 *num_planes = pix->num_planes; in ceu_vb2_setup()
640 for (i = 0; i < pix->num_planes; i++) in ceu_vb2_setup()
641 sizes[i] = pix->plane_fmt[i].sizeimage; in ceu_vb2_setup()
648 struct ceu_device *ceudev = vb2_get_drv_priv(vb->vb2_queue); in ceu_vb2_queue()
653 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_vb2_queue()
654 list_add_tail(&buf->queue, &ceudev->capture); in ceu_vb2_queue()
655 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_vb2_queue()
660 struct ceu_device *ceudev = vb2_get_drv_priv(vb->vb2_queue); in ceu_vb2_prepare()
661 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_vb2_prepare()
664 for (i = 0; i < pix->num_planes; i++) { in ceu_vb2_prepare()
665 if (vb2_plane_size(vb, i) < pix->plane_fmt[i].sizeimage) { in ceu_vb2_prepare()
666 dev_err(ceudev->dev, in ceu_vb2_prepare()
669 pix->plane_fmt[i].sizeimage); in ceu_vb2_prepare()
670 return -EINVAL; in ceu_vb2_prepare()
673 vb2_set_plane_payload(vb, i, pix->plane_fmt[i].sizeimage); in ceu_vb2_prepare()
682 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_start_streaming()
693 if (ret && ret != -ENOIOCTLCMD) { in ceu_start_streaming()
694 dev_dbg(ceudev->dev, in ceu_start_streaming()
699 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_start_streaming()
700 ceudev->sequence = 0; in ceu_start_streaming()
703 buf = list_first_entry(&ceudev->capture, struct ceu_buffer, in ceu_start_streaming()
706 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_start_streaming()
707 dev_dbg(ceudev->dev, in ceu_start_streaming()
712 list_del(&buf->queue); in ceu_start_streaming()
713 ceudev->active = &buf->vb; in ceu_start_streaming()
716 ceu_write(ceudev, CEU_CETCR, ~ceudev->irq_mask); in ceu_start_streaming()
721 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_start_streaming()
729 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_start_streaming()
730 list_for_each_entry(buf, &ceudev->capture, queue) in ceu_start_streaming()
731 vb2_buffer_done(&ceudev->active->vb2_buf, in ceu_start_streaming()
733 ceudev->active = NULL; in ceu_start_streaming()
734 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_start_streaming()
742 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_stop_streaming()
748 ceu_read(ceudev, CEU_CETCR) & ceudev->irq_mask); in ceu_stop_streaming()
753 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_stop_streaming()
754 if (ceudev->active) { in ceu_stop_streaming()
755 vb2_buffer_done(&ceudev->active->vb2_buf, in ceu_stop_streaming()
757 ceudev->active = NULL; in ceu_stop_streaming()
761 list_for_each_entry(buf, &ceudev->capture, queue) in ceu_stop_streaming()
762 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in ceu_stop_streaming()
763 INIT_LIST_HEAD(&ceudev->capture); in ceu_stop_streaming()
765 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_stop_streaming()
780 /* --- CEU image formats handling --- */
783 * __ceu_try_fmt() - test format on CEU and sensor
793 struct ceu_subdev *ceu_sd = ceudev->sd; in __ceu_try_fmt()
794 struct v4l2_pix_format_mplane *pix = &v4l2_fmt->fmt.pix_mp; in __ceu_try_fmt()
795 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in __ceu_try_fmt()
811 mbus_code_old = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
813 switch (pix->pixelformat) { in __ceu_try_fmt()
830 mbus_code = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
834 pix->pixelformat = V4L2_PIX_FMT_NV16; in __ceu_try_fmt()
835 mbus_code = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
839 ceu_fmt = get_ceu_fmt_from_fourcc(pix->pixelformat); in __ceu_try_fmt()
841 /* CFSZR requires height and width to be 4-pixel aligned. */ in __ceu_try_fmt()
842 v4l_bound_align_image(&pix->width, 2, CEU_MAX_WIDTH, 4, in __ceu_try_fmt()
843 &pix->height, 4, CEU_MAX_HEIGHT, 4, 0); in __ceu_try_fmt()
855 if (ret == -EINVAL) { in __ceu_try_fmt()
869 /* Calculate per-plane sizes based on image format. */ in __ceu_try_fmt()
879 * ceu_try_fmt() - Wrapper for __ceu_try_fmt; discard configured mbus_fmt
889 * ceu_set_fmt() - Apply the supplied format to both sensor and CEU
893 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_set_fmt()
894 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_set_fmt()
911 v4l2_fill_mbus_format_mplane(&format.format, &v4l2_fmt->fmt.pix_mp); in ceu_set_fmt()
916 ceudev->v4l2_pix = v4l2_fmt->fmt.pix_mp; in ceu_set_fmt()
917 ceudev->field = V4L2_FIELD_NONE; in ceu_set_fmt()
923 * ceu_set_default_fmt() - Apply default NV16 memory output format with VGA
955 ceudev->v4l2_pix = v4l2_fmt.fmt.pix_mp; in ceu_set_default_fmt()
956 ceudev->field = V4L2_FIELD_NONE; in ceu_set_default_fmt()
962 * ceu_init_mbus_fmt() - Query sensor for supported formats and initialize
965 * Find out if sensor can produce a permutation of 8-bits YUYV bus format.
966 * From a single 8-bits YUYV bus format the CEU can produce several memory
968 * - NV[12|21|16|61] through image fetch mode;
969 * - YUYV422 if sensor provides YUYV422
976 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_init_mbus_fmt()
977 struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; in ceu_init_mbus_fmt()
978 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_init_mbus_fmt()
986 /* Find out if sensor can produce any permutation of 8-bits YUYV422. */ in ceu_init_mbus_fmt()
999 * Only support 8-bits YUYV bus formats at the moment; in ceu_init_mbus_fmt()
1011 return -ENXIO; in ceu_init_mbus_fmt()
1016 * well as for data synch fetch mode (YUYV - YVYU etc. ). in ceu_init_mbus_fmt()
1018 mbus_fmt->mbus_code = sd_mbus_fmt.code; in ceu_init_mbus_fmt()
1019 mbus_fmt->bps = 8; in ceu_init_mbus_fmt()
1024 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YUYV; in ceu_init_mbus_fmt()
1025 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YVYU; in ceu_init_mbus_fmt()
1026 mbus_fmt->swapped = false; in ceu_init_mbus_fmt()
1027 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1031 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YVYU; in ceu_init_mbus_fmt()
1032 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YUYV; in ceu_init_mbus_fmt()
1033 mbus_fmt->swapped = true; in ceu_init_mbus_fmt()
1034 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1038 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_UYVY; in ceu_init_mbus_fmt()
1039 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_VYUY; in ceu_init_mbus_fmt()
1040 mbus_fmt->swapped = false; in ceu_init_mbus_fmt()
1041 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1045 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_VYUY; in ceu_init_mbus_fmt()
1046 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_UYVY; in ceu_init_mbus_fmt()
1047 mbus_fmt->swapped = true; in ceu_init_mbus_fmt()
1048 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1055 /* --- Runtime PM Handlers --- */
1058 * ceu_runtime_resume() - soft-reset the interface and turn sensor power on.
1063 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_runtime_resume()
1073 * ceu_runtime_suspend() - disable capture and interrupts and soft-reset.
1079 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_runtime_suspend()
1089 /* --- File Operations --- */
1100 mutex_lock(&ceudev->mlock); in ceu_open()
1101 /* Causes soft-reset and sensor power on on first open */ in ceu_open()
1102 pm_runtime_get_sync(ceudev->dev); in ceu_open()
1103 mutex_unlock(&ceudev->mlock); in ceu_open()
1114 mutex_lock(&ceudev->mlock); in ceu_release()
1115 /* Causes soft-reset and sensor power down on last close */ in ceu_release()
1116 pm_runtime_put(ceudev->dev); in ceu_release()
1117 mutex_unlock(&ceudev->mlock); in ceu_release()
1131 /* --- Video Device IOCTLs --- */
1138 strscpy(cap->card, "Renesas CEU", sizeof(cap->card)); in ceu_querycap()
1139 strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); in ceu_querycap()
1140 snprintf(cap->bus_info, sizeof(cap->bus_info), in ceu_querycap()
1141 "platform:renesas-ceu-%s", dev_name(ceudev->dev)); in ceu_querycap()
1151 if (f->index >= ARRAY_SIZE(ceu_fmt_list)) in ceu_enum_fmt_vid_cap()
1152 return -EINVAL; in ceu_enum_fmt_vid_cap()
1154 fmt = &ceu_fmt_list[f->index]; in ceu_enum_fmt_vid_cap()
1155 f->pixelformat = fmt->fourcc; in ceu_enum_fmt_vid_cap()
1173 if (vb2_is_streaming(&ceudev->vb2_vq)) in ceu_s_fmt_vid_cap()
1174 return -EBUSY; in ceu_s_fmt_vid_cap()
1184 f->fmt.pix_mp = ceudev->v4l2_pix; in ceu_g_fmt_vid_cap()
1195 if (inp->index >= ceudev->num_sd) in ceu_enum_input()
1196 return -EINVAL; in ceu_enum_input()
1198 ceusd = &ceudev->subdevs[inp->index]; in ceu_enum_input()
1200 inp->type = V4L2_INPUT_TYPE_CAMERA; in ceu_enum_input()
1201 inp->std = 0; in ceu_enum_input()
1202 snprintf(inp->name, sizeof(inp->name), "Camera%u: %s", in ceu_enum_input()
1203 inp->index, ceusd->v4l2_sd->name); in ceu_enum_input()
1212 *i = ceudev->sd_index; in ceu_g_input()
1223 if (i >= ceudev->num_sd) in ceu_s_input()
1224 return -EINVAL; in ceu_s_input()
1226 if (vb2_is_streaming(&ceudev->vb2_vq)) in ceu_s_input()
1227 return -EBUSY; in ceu_s_input()
1229 if (i == ceudev->sd_index) in ceu_s_input()
1232 ceu_sd_old = ceudev->sd; in ceu_s_input()
1233 ceudev->sd = &ceudev->subdevs[i]; in ceu_s_input()
1241 ceudev->sd = ceu_sd_old; in ceu_s_input()
1242 return -EINVAL; in ceu_s_input()
1247 ceudev->sd = ceu_sd_old; in ceu_s_input()
1248 return -EINVAL; in ceu_s_input()
1252 v4l2_subdev_call(ceu_sd_old->v4l2_sd, core, s_power, 0); in ceu_s_input()
1253 v4l2_subdev_call(ceudev->sd->v4l2_sd, core, s_power, 1); in ceu_s_input()
1255 ceudev->sd_index = i; in ceu_s_input()
1264 return v4l2_g_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); in ceu_g_parm()
1271 return v4l2_s_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); in ceu_s_parm()
1278 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_enum_framesizes()
1280 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_enum_framesizes()
1284 .code = ceu_sd->mbus_fmt.mbus_code, in ceu_enum_framesizes()
1285 .index = fsize->index, in ceu_enum_framesizes()
1290 ceu_fmt = get_ceu_fmt_from_fourcc(fsize->pixel_format); in ceu_enum_framesizes()
1292 return -EINVAL; in ceu_enum_framesizes()
1299 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in ceu_enum_framesizes()
1300 fsize->discrete.width = CEU_W_MAX(fse.max_width); in ceu_enum_framesizes()
1301 fsize->discrete.height = CEU_H_MAX(fse.max_height); in ceu_enum_framesizes()
1310 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_enum_frameintervals()
1312 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_enum_frameintervals()
1316 .code = ceu_sd->mbus_fmt.mbus_code, in ceu_enum_frameintervals()
1317 .index = fival->index, in ceu_enum_frameintervals()
1318 .width = fival->width, in ceu_enum_frameintervals()
1319 .height = fival->height, in ceu_enum_frameintervals()
1324 ceu_fmt = get_ceu_fmt_from_fourcc(fival->pixel_format); in ceu_enum_frameintervals()
1326 return -EINVAL; in ceu_enum_frameintervals()
1333 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; in ceu_enum_frameintervals()
1334 fival->discrete = fie.interval; in ceu_enum_frameintervals()
1372 * ceu_vdev_release() - release CEU video device memory when last reference
1386 struct v4l2_device *v4l2_dev = notifier->v4l2_dev; in ceu_notify_bound()
1390 ceu_sd->v4l2_sd = v4l2_sd; in ceu_notify_bound()
1391 ceudev->num_sd++; in ceu_notify_bound()
1398 struct v4l2_device *v4l2_dev = notifier->v4l2_dev; in ceu_notify_complete()
1400 struct video_device *vdev = &ceudev->vdev; in ceu_notify_complete()
1401 struct vb2_queue *q = &ceudev->vb2_vq; in ceu_notify_complete()
1406 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in ceu_notify_complete()
1407 q->io_modes = VB2_MMAP | VB2_DMABUF; in ceu_notify_complete()
1408 q->drv_priv = ceudev; in ceu_notify_complete()
1409 q->ops = &ceu_vb2_ops; in ceu_notify_complete()
1410 q->mem_ops = &vb2_dma_contig_memops; in ceu_notify_complete()
1411 q->buf_struct_size = sizeof(struct ceu_buffer); in ceu_notify_complete()
1412 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in ceu_notify_complete()
1413 q->min_buffers_needed = 2; in ceu_notify_complete()
1414 q->lock = &ceudev->mlock; in ceu_notify_complete()
1415 q->dev = ceudev->v4l2_dev.dev; in ceu_notify_complete()
1425 if (!ceudev->sd) { in ceu_notify_complete()
1426 ceudev->sd = &ceudev->subdevs[0]; in ceu_notify_complete()
1427 ceudev->sd_index = 0; in ceu_notify_complete()
1430 v4l2_sd = ceudev->sd->v4l2_sd; in ceu_notify_complete()
1441 strscpy(vdev->name, DRIVER_NAME, sizeof(vdev->name)); in ceu_notify_complete()
1442 vdev->v4l2_dev = v4l2_dev; in ceu_notify_complete()
1443 vdev->lock = &ceudev->mlock; in ceu_notify_complete()
1444 vdev->queue = &ceudev->vb2_vq; in ceu_notify_complete()
1445 vdev->ctrl_handler = v4l2_sd->ctrl_handler; in ceu_notify_complete()
1446 vdev->fops = &ceu_fops; in ceu_notify_complete()
1447 vdev->ioctl_ops = &ceu_ioctl_ops; in ceu_notify_complete()
1448 vdev->release = ceu_vdev_release; in ceu_notify_complete()
1449 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | in ceu_notify_complete()
1453 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in ceu_notify_complete()
1455 v4l2_err(vdev->v4l2_dev, in ceu_notify_complete()
1469 * ceu_init_async_subdevs() - Initialize CEU subdevices and async_subdevs in
1473 * Returns 0 for success, -ENOMEM for failure.
1478 ceudev->subdevs = devm_kcalloc(ceudev->dev, n_sd, in ceu_init_async_subdevs()
1479 sizeof(*ceudev->subdevs), GFP_KERNEL); in ceu_init_async_subdevs()
1480 if (!ceudev->subdevs) in ceu_init_async_subdevs()
1481 return -ENOMEM; in ceu_init_async_subdevs()
1483 ceudev->sd = NULL; in ceu_init_async_subdevs()
1484 ceudev->sd_index = 0; in ceu_init_async_subdevs()
1485 ceudev->num_sd = 0; in ceu_init_async_subdevs()
1491 * ceu_parse_platform_data() - Initialize async_subdevices using platform
1502 if (pdata->num_subdevs == 0) in ceu_parse_platform_data()
1503 return -ENODEV; in ceu_parse_platform_data()
1505 ret = ceu_init_async_subdevs(ceudev, pdata->num_subdevs); in ceu_parse_platform_data()
1509 for (i = 0; i < pdata->num_subdevs; i++) { in ceu_parse_platform_data()
1512 async_sd = &pdata->subdevs[i]; in ceu_parse_platform_data()
1513 ceu_sd = &ceudev->subdevs[i]; in ceu_parse_platform_data()
1515 INIT_LIST_HEAD(&ceu_sd->asd.list); in ceu_parse_platform_data()
1517 ceu_sd->mbus_flags = async_sd->flags; in ceu_parse_platform_data()
1518 ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_I2C; in ceu_parse_platform_data()
1519 ceu_sd->asd.match.i2c.adapter_id = async_sd->i2c_adapter_id; in ceu_parse_platform_data()
1520 ceu_sd->asd.match.i2c.address = async_sd->i2c_address; in ceu_parse_platform_data()
1522 ret = v4l2_async_notifier_add_subdev(&ceudev->notifier, in ceu_parse_platform_data()
1523 &ceu_sd->asd); in ceu_parse_platform_data()
1525 v4l2_async_notifier_cleanup(&ceudev->notifier); in ceu_parse_platform_data()
1530 return pdata->num_subdevs; in ceu_parse_platform_data()
1534 * ceu_parse_dt() - Initialize async_subdevs parsing device tree graph.
1538 struct device_node *of = ceudev->dev->of_node; in ceu_parse_dt()
1547 return -ENODEV; in ceu_parse_dt()
1567 dev_err(ceudev->dev, in ceu_parse_dt()
1569 ret = -ENODEV; in ceu_parse_dt()
1575 dev_err(ceudev->dev, in ceu_parse_dt()
1581 ceu_sd = &ceudev->subdevs[i]; in ceu_parse_dt()
1582 INIT_LIST_HEAD(&ceu_sd->asd.list); in ceu_parse_dt()
1585 ceu_sd->mbus_flags = fw_ep.bus.parallel.flags; in ceu_parse_dt()
1586 ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; in ceu_parse_dt()
1587 ceu_sd->asd.match.fwnode = of_fwnode_handle(remote); in ceu_parse_dt()
1589 ret = v4l2_async_notifier_add_subdev(&ceudev->notifier, in ceu_parse_dt()
1590 &ceu_sd->asd); in ceu_parse_dt()
1602 v4l2_async_notifier_cleanup(&ceudev->notifier); in ceu_parse_dt()
1608 * struct ceu_data - Platform specific CEU data
1626 { .compatible = "renesas,r7s72100-ceu", .data = &ceu_data_rz },
1627 { .compatible = "renesas,r8a7740-ceu", .data = &ceu_data_rz },
1635 struct device *dev = &pdev->dev; in ceu_probe()
1645 return -ENOMEM; in ceu_probe()
1648 ceudev->dev = dev; in ceu_probe()
1650 INIT_LIST_HEAD(&ceudev->capture); in ceu_probe()
1651 spin_lock_init(&ceudev->lock); in ceu_probe()
1652 mutex_init(&ceudev->mlock); in ceu_probe()
1655 ceudev->base = devm_ioremap_resource(dev, res); in ceu_probe()
1656 if (IS_ERR(ceudev->base)) { in ceu_probe()
1657 ret = PTR_ERR(ceudev->base); in ceu_probe()
1669 dev_err(&pdev->dev, "Unable to request CEU interrupt.\n"); in ceu_probe()
1675 ret = v4l2_device_register(dev, &ceudev->v4l2_dev); in ceu_probe()
1679 v4l2_async_notifier_init(&ceudev->notifier); in ceu_probe()
1681 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { in ceu_probe()
1682 ceu_data = of_match_device(ceu_of_match, dev)->data; in ceu_probe()
1684 } else if (dev->platform_data) { in ceu_probe()
1688 dev->platform_data); in ceu_probe()
1690 num_subdevs = -EINVAL; in ceu_probe()
1697 ceudev->irq_mask = ceu_data->irq_mask; in ceu_probe()
1699 ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; in ceu_probe()
1700 ceudev->notifier.ops = &ceu_notify_ops; in ceu_probe()
1701 ret = v4l2_async_notifier_register(&ceudev->v4l2_dev, in ceu_probe()
1702 &ceudev->notifier); in ceu_probe()
1711 v4l2_async_notifier_cleanup(&ceudev->notifier); in ceu_probe()
1713 v4l2_device_unregister(&ceudev->v4l2_dev); in ceu_probe()
1726 pm_runtime_disable(ceudev->dev); in ceu_remove()
1728 v4l2_async_notifier_unregister(&ceudev->notifier); in ceu_remove()
1730 v4l2_async_notifier_cleanup(&ceudev->notifier); in ceu_remove()
1732 v4l2_device_unregister(&ceudev->v4l2_dev); in ceu_remove()
1734 video_unregister_device(&ceudev->vdev); in ceu_remove()