Lines Matching +full:r7s72100 +full:- +full:ceu
1 // SPDX-License-Identifier: GPL-2.0
3 * V4L2 Driver for Renesas Capture Engine Unit (CEU) interface
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"
49 /* CEU registers offsets and masks. */
56 #define CEU_CRCNTR 0x28 /* CEU register control register */
57 #define CEU_CRCMPR 0x2c /* CEU register forcible control register */
89 /* Swap all input data in 8-bit, 16-bits and 32-bits units (Figure 46.45). */
96 /* CEU operating flag bit. */
106 /* One-frame capture end interrupt. */
119 * ceu_bus_fmt - describe a 8-bits yuyv format the sensor can produce
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.
313 * @ceu_device: CEU device.
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()
357 /* Start configuring CEU registers */ in ceu_hw_config()
364 capwr = (pix->height << 16) | pix->width * mbus_fmt->bpp / 8; in ceu_hw_config()
388 * CEU by default downsample to planar YUV420 (CDCOR[4] = 0). 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()
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.
463 * Program the CEU DMA registers with addresses where to transfer image data.
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()
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'
574 * @ceu_device: CEU device.
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()
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()
687 /* Program the CEU interface according to the CEU image format. */ 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
784 * @ceudev: The CEU device.
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()
814 mbus_code_old = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
816 switch (pix->pixelformat) { in __ceu_try_fmt()
833 mbus_code = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
837 pix->pixelformat = V4L2_PIX_FMT_NV16; in __ceu_try_fmt()
838 mbus_code = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
842 ceu_fmt = get_ceu_fmt_from_fourcc(pix->pixelformat); in __ceu_try_fmt()
844 /* CFSZR requires height and width to be 4-pixel aligned. */ in __ceu_try_fmt()
845 v4l_bound_align_image(&pix->width, 2, CEU_MAX_WIDTH, 4, in __ceu_try_fmt()
846 &pix->height, 4, CEU_MAX_HEIGHT, 4, 0); in __ceu_try_fmt()
858 if (ret == -EINVAL) { in __ceu_try_fmt()
869 /* Apply size returned by sensor as the CEU can't scale. */ in __ceu_try_fmt()
872 /* Calculate per-plane sizes based on image format. */ in __ceu_try_fmt()
882 * ceu_try_fmt() - Wrapper for __ceu_try_fmt; discard configured mbus_fmt
892 * ceu_set_fmt() - Apply the supplied format to both sensor and CEU
896 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_set_fmt()
897 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_set_fmt()
914 v4l2_fill_mbus_format_mplane(&format.format, &v4l2_fmt->fmt.pix_mp); in ceu_set_fmt()
919 ceudev->v4l2_pix = v4l2_fmt->fmt.pix_mp; in ceu_set_fmt()
920 ceudev->field = V4L2_FIELD_NONE; in ceu_set_fmt()
926 * ceu_set_default_fmt() - Apply default NV16 memory output format with VGA
958 ceudev->v4l2_pix = v4l2_fmt.fmt.pix_mp; in ceu_set_default_fmt()
959 ceudev->field = V4L2_FIELD_NONE; in ceu_set_default_fmt()
965 * ceu_init_mbus_fmt() - Query sensor for supported formats and initialize
966 * CEU media bus format used to produce memory formats.
968 * Find out if sensor can produce a permutation of 8-bits YUYV bus format.
969 * From a single 8-bits YUYV bus format the CEU can produce several memory
971 * - NV[12|21|16|61] through image fetch mode;
972 * - YUYV422 if sensor provides YUYV422
979 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_init_mbus_fmt()
980 struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; in ceu_init_mbus_fmt()
981 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_init_mbus_fmt()
989 /* Find out if sensor can produce any permutation of 8-bits YUYV422. */ in ceu_init_mbus_fmt()
1002 * Only support 8-bits YUYV bus formats at the moment; in ceu_init_mbus_fmt()
1014 return -ENXIO; in ceu_init_mbus_fmt()
1019 * well as for data synch fetch mode (YUYV - YVYU etc. ). in ceu_init_mbus_fmt()
1021 mbus_fmt->mbus_code = sd_mbus_fmt.code; in ceu_init_mbus_fmt()
1022 mbus_fmt->bps = 8; in ceu_init_mbus_fmt()
1027 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YUYV; in ceu_init_mbus_fmt()
1028 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YVYU; in ceu_init_mbus_fmt()
1029 mbus_fmt->swapped = false; in ceu_init_mbus_fmt()
1030 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1034 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YVYU; in ceu_init_mbus_fmt()
1035 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YUYV; in ceu_init_mbus_fmt()
1036 mbus_fmt->swapped = true; in ceu_init_mbus_fmt()
1037 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1041 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_UYVY; in ceu_init_mbus_fmt()
1042 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_VYUY; in ceu_init_mbus_fmt()
1043 mbus_fmt->swapped = false; in ceu_init_mbus_fmt()
1044 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1048 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_VYUY; in ceu_init_mbus_fmt()
1049 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_UYVY; in ceu_init_mbus_fmt()
1050 mbus_fmt->swapped = true; in ceu_init_mbus_fmt()
1051 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1058 /* --- Runtime PM Handlers --- */
1061 * ceu_runtime_resume() - soft-reset the interface and turn sensor power on.
1066 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_runtime_resume()
1076 * ceu_runtime_suspend() - disable capture and interrupts and soft-reset.
1082 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_runtime_suspend()
1092 /* --- File Operations --- */
1103 mutex_lock(&ceudev->mlock); in ceu_open()
1104 /* Causes soft-reset and sensor power on on first open */ in ceu_open()
1105 ret = pm_runtime_resume_and_get(ceudev->dev); in ceu_open()
1106 mutex_unlock(&ceudev->mlock); in ceu_open()
1117 mutex_lock(&ceudev->mlock); in ceu_release()
1118 /* Causes soft-reset and sensor power down on last close */ in ceu_release()
1119 pm_runtime_put(ceudev->dev); in ceu_release()
1120 mutex_unlock(&ceudev->mlock); in ceu_release()
1134 /* --- Video Device IOCTLs --- */
1141 strscpy(cap->card, "Renesas CEU", sizeof(cap->card)); in ceu_querycap()
1142 strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); in ceu_querycap()
1143 snprintf(cap->bus_info, sizeof(cap->bus_info), in ceu_querycap()
1144 "platform:renesas-ceu-%s", dev_name(ceudev->dev)); in ceu_querycap()
1154 if (f->index >= ARRAY_SIZE(ceu_fmt_list)) in ceu_enum_fmt_vid_cap()
1155 return -EINVAL; in ceu_enum_fmt_vid_cap()
1157 fmt = &ceu_fmt_list[f->index]; in ceu_enum_fmt_vid_cap()
1158 f->pixelformat = fmt->fourcc; in ceu_enum_fmt_vid_cap()
1176 if (vb2_is_streaming(&ceudev->vb2_vq)) in ceu_s_fmt_vid_cap()
1177 return -EBUSY; in ceu_s_fmt_vid_cap()
1187 f->fmt.pix_mp = ceudev->v4l2_pix; in ceu_g_fmt_vid_cap()
1198 if (inp->index >= ceudev->num_sd) in ceu_enum_input()
1199 return -EINVAL; in ceu_enum_input()
1201 ceusd = ceudev->subdevs[inp->index]; in ceu_enum_input()
1203 inp->type = V4L2_INPUT_TYPE_CAMERA; in ceu_enum_input()
1204 inp->std = 0; in ceu_enum_input()
1205 snprintf(inp->name, sizeof(inp->name), "Camera%u: %s", in ceu_enum_input()
1206 inp->index, ceusd->v4l2_sd->name); in ceu_enum_input()
1215 *i = ceudev->sd_index; in ceu_g_input()
1226 if (i >= ceudev->num_sd) in ceu_s_input()
1227 return -EINVAL; in ceu_s_input()
1229 if (vb2_is_streaming(&ceudev->vb2_vq)) in ceu_s_input()
1230 return -EBUSY; in ceu_s_input()
1232 if (i == ceudev->sd_index) in ceu_s_input()
1235 ceu_sd_old = ceudev->sd; in ceu_s_input()
1236 ceudev->sd = ceudev->subdevs[i]; in ceu_s_input()
1244 ceudev->sd = ceu_sd_old; in ceu_s_input()
1245 return -EINVAL; in ceu_s_input()
1250 ceudev->sd = ceu_sd_old; in ceu_s_input()
1251 return -EINVAL; in ceu_s_input()
1255 v4l2_subdev_call(ceu_sd_old->v4l2_sd, core, s_power, 0); in ceu_s_input()
1256 v4l2_subdev_call(ceudev->sd->v4l2_sd, core, s_power, 1); in ceu_s_input()
1258 ceudev->sd_index = i; in ceu_s_input()
1267 return v4l2_g_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); in ceu_g_parm()
1274 return v4l2_s_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); in ceu_s_parm()
1281 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_enum_framesizes()
1283 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_enum_framesizes()
1287 .code = ceu_sd->mbus_fmt.mbus_code, in ceu_enum_framesizes()
1288 .index = fsize->index, in ceu_enum_framesizes()
1293 ceu_fmt = get_ceu_fmt_from_fourcc(fsize->pixel_format); in ceu_enum_framesizes()
1295 return -EINVAL; in ceu_enum_framesizes()
1302 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in ceu_enum_framesizes()
1303 fsize->discrete.width = CEU_W_MAX(fse.max_width); in ceu_enum_framesizes()
1304 fsize->discrete.height = CEU_H_MAX(fse.max_height); in ceu_enum_framesizes()
1313 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_enum_frameintervals()
1315 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_enum_frameintervals()
1319 .code = ceu_sd->mbus_fmt.mbus_code, in ceu_enum_frameintervals()
1320 .index = fival->index, in ceu_enum_frameintervals()
1321 .width = fival->width, in ceu_enum_frameintervals()
1322 .height = fival->height, in ceu_enum_frameintervals()
1327 ceu_fmt = get_ceu_fmt_from_fourcc(fival->pixel_format); in ceu_enum_frameintervals()
1329 return -EINVAL; in ceu_enum_frameintervals()
1336 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; in ceu_enum_frameintervals()
1337 fival->discrete = fie.interval; in ceu_enum_frameintervals()
1375 * ceu_vdev_release() - release CEU video device memory when last reference
1389 struct v4l2_device *v4l2_dev = notifier->v4l2_dev; in ceu_notify_bound()
1393 ceu_sd->v4l2_sd = v4l2_sd; in ceu_notify_bound()
1394 ceudev->num_sd++; in ceu_notify_bound()
1401 struct v4l2_device *v4l2_dev = notifier->v4l2_dev; in ceu_notify_complete()
1403 struct video_device *vdev = &ceudev->vdev; in ceu_notify_complete()
1404 struct vb2_queue *q = &ceudev->vb2_vq; in ceu_notify_complete()
1409 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in ceu_notify_complete()
1410 q->io_modes = VB2_MMAP | VB2_DMABUF; in ceu_notify_complete()
1411 q->drv_priv = ceudev; in ceu_notify_complete()
1412 q->ops = &ceu_vb2_ops; in ceu_notify_complete()
1413 q->mem_ops = &vb2_dma_contig_memops; in ceu_notify_complete()
1414 q->buf_struct_size = sizeof(struct ceu_buffer); in ceu_notify_complete()
1415 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in ceu_notify_complete()
1416 q->min_buffers_needed = 2; in ceu_notify_complete()
1417 q->lock = &ceudev->mlock; in ceu_notify_complete()
1418 q->dev = ceudev->v4l2_dev.dev; in ceu_notify_complete()
1426 * ceu formats. in ceu_notify_complete()
1428 if (!ceudev->sd) { in ceu_notify_complete()
1429 ceudev->sd = ceudev->subdevs[0]; in ceu_notify_complete()
1430 ceudev->sd_index = 0; in ceu_notify_complete()
1433 v4l2_sd = ceudev->sd->v4l2_sd; in ceu_notify_complete()
1444 strscpy(vdev->name, DRIVER_NAME, sizeof(vdev->name)); in ceu_notify_complete()
1445 vdev->v4l2_dev = v4l2_dev; in ceu_notify_complete()
1446 vdev->lock = &ceudev->mlock; in ceu_notify_complete()
1447 vdev->queue = &ceudev->vb2_vq; in ceu_notify_complete()
1448 vdev->ctrl_handler = v4l2_sd->ctrl_handler; in ceu_notify_complete()
1449 vdev->fops = &ceu_fops; in ceu_notify_complete()
1450 vdev->ioctl_ops = &ceu_ioctl_ops; in ceu_notify_complete()
1451 vdev->release = ceu_vdev_release; in ceu_notify_complete()
1452 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | in ceu_notify_complete()
1456 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in ceu_notify_complete()
1458 v4l2_err(vdev->v4l2_dev, in ceu_notify_complete()
1472 * ceu_init_async_subdevs() - Initialize CEU subdevices and async_subdevs in
1473 * ceu device. Both DT and platform data parsing use
1476 * Returns 0 for success, -ENOMEM for failure.
1481 ceudev->subdevs = devm_kcalloc(ceudev->dev, n_sd, in ceu_init_async_subdevs()
1482 sizeof(*ceudev->subdevs), GFP_KERNEL); in ceu_init_async_subdevs()
1483 if (!ceudev->subdevs) in ceu_init_async_subdevs()
1484 return -ENOMEM; in ceu_init_async_subdevs()
1486 ceudev->sd = NULL; in ceu_init_async_subdevs()
1487 ceudev->sd_index = 0; in ceu_init_async_subdevs()
1488 ceudev->num_sd = 0; in ceu_init_async_subdevs()
1494 * ceu_parse_platform_data() - Initialize async_subdevices using platform
1505 if (pdata->num_subdevs == 0) in ceu_parse_platform_data()
1506 return -ENODEV; in ceu_parse_platform_data()
1508 ret = ceu_init_async_subdevs(ceudev, pdata->num_subdevs); in ceu_parse_platform_data()
1512 for (i = 0; i < pdata->num_subdevs; i++) { in ceu_parse_platform_data()
1514 /* Setup the ceu subdevice and the async subdevice. */ in ceu_parse_platform_data()
1515 async_sd = &pdata->subdevs[i]; in ceu_parse_platform_data()
1516 ceu_sd = v4l2_async_nf_add_i2c(&ceudev->notifier, in ceu_parse_platform_data()
1517 async_sd->i2c_adapter_id, in ceu_parse_platform_data()
1518 async_sd->i2c_address, in ceu_parse_platform_data()
1521 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_parse_platform_data()
1524 ceu_sd->mbus_flags = async_sd->flags; in ceu_parse_platform_data()
1525 ceudev->subdevs[i] = ceu_sd; in ceu_parse_platform_data()
1528 return pdata->num_subdevs; in ceu_parse_platform_data()
1532 * ceu_parse_dt() - Initialize async_subdevs parsing device tree graph.
1536 struct device_node *of = ceudev->dev->of_node; in ceu_parse_dt()
1545 return -ENODEV; in ceu_parse_dt()
1565 dev_err(ceudev->dev, in ceu_parse_dt()
1567 ret = -ENODEV; in ceu_parse_dt()
1573 dev_err(ceudev->dev, in ceu_parse_dt()
1578 /* Setup the ceu subdevice and the async subdevice. */ in ceu_parse_dt()
1579 ceu_sd = v4l2_async_nf_add_fwnode_remote(&ceudev->notifier, in ceu_parse_dt()
1586 ceu_sd->mbus_flags = fw_ep.bus.parallel.flags; in ceu_parse_dt()
1587 ceudev->subdevs[i] = ceu_sd; in ceu_parse_dt()
1595 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_parse_dt()
1601 * struct ceu_data - Platform specific CEU data
1619 { .compatible = "renesas,r7s72100-ceu", .data = &ceu_data_rz },
1620 { .compatible = "renesas,r8a7740-ceu", .data = &ceu_data_rz },
1628 struct device *dev = &pdev->dev; in ceu_probe()
1637 return -ENOMEM; in ceu_probe()
1640 ceudev->dev = dev; in ceu_probe()
1642 INIT_LIST_HEAD(&ceudev->capture); in ceu_probe()
1643 spin_lock_init(&ceudev->lock); in ceu_probe()
1644 mutex_init(&ceudev->mlock); in ceu_probe()
1646 ceudev->base = devm_platform_ioremap_resource(pdev, 0); in ceu_probe()
1647 if (IS_ERR(ceudev->base)) { in ceu_probe()
1648 ret = PTR_ERR(ceudev->base); in ceu_probe()
1660 dev_err(&pdev->dev, "Unable to request CEU interrupt.\n"); in ceu_probe()
1666 ret = v4l2_device_register(dev, &ceudev->v4l2_dev); in ceu_probe()
1670 v4l2_async_nf_init(&ceudev->notifier); in ceu_probe()
1672 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { in ceu_probe()
1675 } else if (dev->platform_data) { in ceu_probe()
1679 dev->platform_data); in ceu_probe()
1681 num_subdevs = -EINVAL; in ceu_probe()
1688 ceudev->irq_mask = ceu_data->irq_mask; in ceu_probe()
1690 ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; in ceu_probe()
1691 ceudev->notifier.ops = &ceu_notify_ops; in ceu_probe()
1692 ret = v4l2_async_nf_register(&ceudev->v4l2_dev, &ceudev->notifier); in ceu_probe()
1701 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_probe()
1703 v4l2_device_unregister(&ceudev->v4l2_dev); in ceu_probe()
1716 pm_runtime_disable(ceudev->dev); in ceu_remove()
1718 v4l2_async_nf_unregister(&ceudev->notifier); in ceu_remove()
1720 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_remove()
1722 v4l2_device_unregister(&ceudev->v4l2_dev); in ceu_remove()
1724 video_unregister_device(&ceudev->vdev); in ceu_remove()
1747 MODULE_DESCRIPTION("Renesas CEU camera driver");