Lines Matching +full:not +full:- +full:swapped
1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (C) 2017-2018 Jacopo Mondi <[email protected]>
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>
32 #include <media/v4l2-async.h>
33 #include <media/v4l2-common.h>
34 #include <media/v4l2-ctrls.h>
35 #include <media/v4l2-dev.h>
36 #include <media/v4l2-device.h>
37 #include <media/v4l2-event.h>
38 #include <media/v4l2-fwnode.h>
39 #include <media/v4l2-image-sizes.h>
40 #include <media/v4l2-ioctl.h>
41 #include <media/v4l2-mediabus.h>
42 #include <media/videobuf2-dma-contig.h>
44 #include <media/drv-intf/renesas-ceu.h>
46 #define DRIVER_NAME "renesas-ceu"
88 /* Swap all input data in 8-bit, 16-bits and 32-bits units (Figure 46.45). */
105 /* One-frame capture end interrupt. */
118 * ceu_bus_fmt - describe a 8-bits yuyv format the sensor can produce
122 * @fmt_order_swap: swapped CEU_CAMCR.DTARY ordering of input components
124 * @swapped: does Cr appear before Cb?
132 bool swapped; member
138 * ceu_buffer - Link vb2 buffer to the list of available buffers.
151 * ceu_subdev - Wraps v4l2 sub-device and provides async subdevice.
157 /* per-subdevice mbus configuration options */
168 * ceu_device - CEU device instance
198 /* mlock - lock access to interface reset and vb2 queue */
201 /* lock - lock access to capture buffer queue and active buffer */
204 /* base - CEU memory base address */
213 /* --- CEU memory output formats --- */
216 * ceu_fmt - describe a memory output format supported by CEU interface.
227 * ceu_format_list - List of supported memory output formats
230 * formats are available thanks to CEU re-ordering and sub-sampling
274 if (fmt->fourcc == fourcc) in get_ceu_fmt_from_fourcc()
282 switch (pix->pixelformat) { in ceu_fmt_mplane()
298 /* --- CEU HW operations --- */
302 iowrite32(data, priv->base + reg_offs); in ceu_write()
307 return ioread32(priv->base + reg_offs); in ceu_read()
311 * ceu_soft_reset() - Software reset the CEU interface.
314 * Returns 0 for success, -EIO for error.
329 dev_err(ceudev->dev, "soft reset time out\n"); in ceu_soft_reset()
330 return -EIO; in ceu_soft_reset()
339 /* If we get here, CEU has not reset properly. */ in ceu_soft_reset()
340 return -EIO; in ceu_soft_reset()
343 /* --- CEU Capture Operations --- */
346 * ceu_hw_config() - Configure CEU interface registers.
351 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_hw_config()
352 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_hw_config()
353 struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; in ceu_hw_config()
354 unsigned int mbus_flags = ceu_sd->mbus_flags; in ceu_hw_config()
363 capwr = (pix->height << 16) | pix->width * mbus_fmt->bpp / 8; in ceu_hw_config()
381 * If the memory output planar format is 'swapped' (Cr before Cb) and in ceu_hw_config()
382 * input format is not, use the swapped version of CAMCR.DTARY. in ceu_hw_config()
384 * If the memory output planar format is not 'swapped' (Cb before Cr) in ceu_hw_config()
385 * and input format is, use the swapped version of CAMCR.DTARY. in ceu_hw_config()
392 switch (pix->pixelformat) { in ceu_hw_config()
400 cfzsr = (pix->height << 16) | pix->width; in ceu_hw_config()
401 cdwdr = pix->plane_fmt[0].bytesperline; in ceu_hw_config()
404 /* Non-swapped planar image capture mode. */ in ceu_hw_config()
409 if (mbus_fmt->swapped) in ceu_hw_config()
410 camcr = mbus_fmt->fmt_order_swap; in ceu_hw_config()
412 camcr = mbus_fmt->fmt_order; in ceu_hw_config()
414 cfzsr = (pix->height << 16) | pix->width; in ceu_hw_config()
415 cdwdr = pix->width; in ceu_hw_config()
418 /* Swapped planar image capture mode. */ in ceu_hw_config()
423 if (mbus_fmt->swapped) in ceu_hw_config()
424 camcr = mbus_fmt->fmt_order; in ceu_hw_config()
426 camcr = mbus_fmt->fmt_order_swap; in ceu_hw_config()
428 cfzsr = (pix->height << 16) | pix->width; in ceu_hw_config()
429 cdwdr = pix->width; in ceu_hw_config()
433 return -EINVAL; in ceu_hw_config()
451 /* TODO: 16 bit bus width require re-calculation of cdwdr and cfzsr */ in ceu_hw_config()
460 * ceu_capture() - Trigger start of a capture sequence.
466 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_capture()
470 vb2_dma_contig_plane_dma_addr(&ceudev->active->vb2_buf, 0); in ceu_capture()
473 /* Ignore CbCr plane for non multi-planar image formats. */ in ceu_capture()
476 vb2_dma_contig_plane_dma_addr(&ceudev->active->vb2_buf, in ceu_capture()
483 * one-frame capture mode. in ceu_capture()
499 ceu_write(ceudev, CEU_CETCR, ~ceudev->irq_mask); in ceu_irq()
505 spin_lock(&ceudev->lock); in ceu_irq()
508 vbuf = ceudev->active; in ceu_irq()
510 spin_unlock(&ceudev->lock); in ceu_irq()
516 * and the image of that frame is not captured correctly. in ceu_irq()
519 dev_err(ceudev->dev, "VBP interrupt: abort capture\n"); in ceu_irq()
524 vbuf->vb2_buf.timestamp = ktime_get_ns(); in ceu_irq()
525 vbuf->sequence = ceudev->sequence++; in ceu_irq()
526 vbuf->field = ceudev->field; in ceu_irq()
529 if (!list_empty(&ceudev->capture)) { in ceu_irq()
530 buf = list_first_entry(&ceudev->capture, struct ceu_buffer, in ceu_irq()
532 list_del(&buf->queue); in ceu_irq()
533 ceudev->active = &buf->vb; in ceu_irq()
539 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); in ceu_irq()
541 spin_unlock(&ceudev->lock); in ceu_irq()
547 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR); in ceu_irq()
549 list_for_each_entry(buf, &ceudev->capture, queue) in ceu_irq()
550 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in ceu_irq()
552 spin_unlock(&ceudev->lock); in ceu_irq()
557 /* --- CEU Videobuf2 operations --- */
564 plane->sizeimage = szimage; in ceu_update_plane_sizes()
565 if (plane->bytesperline < bpl || plane->bytesperline > CEU_MAX_BPL) in ceu_update_plane_sizes()
566 plane->bytesperline = bpl; in ceu_update_plane_sizes()
570 * ceu_calc_plane_sizes() - Fill per-plane 'struct v4l2_plane_pix_format'
583 switch (pix->pixelformat) { in ceu_calc_plane_sizes()
588 pix->num_planes = 1; in ceu_calc_plane_sizes()
589 bpl = pix->width * ceu_fmt->bpp / 8; in ceu_calc_plane_sizes()
590 szimage = pix->height * bpl; in ceu_calc_plane_sizes()
591 ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); in ceu_calc_plane_sizes()
596 pix->num_planes = 2; in ceu_calc_plane_sizes()
597 bpl = pix->width; in ceu_calc_plane_sizes()
598 szimage = pix->height * pix->width; in ceu_calc_plane_sizes()
599 ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); in ceu_calc_plane_sizes()
600 ceu_update_plane_sizes(&pix->plane_fmt[1], bpl, szimage / 2); in ceu_calc_plane_sizes()
606 pix->num_planes = 2; in ceu_calc_plane_sizes()
607 bpl = pix->width; in ceu_calc_plane_sizes()
608 szimage = pix->height * pix->width; in ceu_calc_plane_sizes()
609 ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); in ceu_calc_plane_sizes()
610 ceu_update_plane_sizes(&pix->plane_fmt[1], bpl, szimage); in ceu_calc_plane_sizes()
616 * ceu_vb2_setup() - is called to check whether the driver can accept the
625 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_vb2_setup()
630 for (i = 0; i < pix->num_planes; i++) in ceu_vb2_setup()
631 if (sizes[i] < pix->plane_fmt[i].sizeimage) in ceu_vb2_setup()
632 return -EINVAL; in ceu_vb2_setup()
637 /* num_planes not set: called from REQBUFS, just set plane sizes. */ in ceu_vb2_setup()
638 *num_planes = pix->num_planes; in ceu_vb2_setup()
639 for (i = 0; i < pix->num_planes; i++) in ceu_vb2_setup()
640 sizes[i] = pix->plane_fmt[i].sizeimage; in ceu_vb2_setup()
647 struct ceu_device *ceudev = vb2_get_drv_priv(vb->vb2_queue); in ceu_vb2_queue()
652 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_vb2_queue()
653 list_add_tail(&buf->queue, &ceudev->capture); in ceu_vb2_queue()
654 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_vb2_queue()
659 struct ceu_device *ceudev = vb2_get_drv_priv(vb->vb2_queue); in ceu_vb2_prepare()
660 struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; in ceu_vb2_prepare()
663 for (i = 0; i < pix->num_planes; i++) { in ceu_vb2_prepare()
664 if (vb2_plane_size(vb, i) < pix->plane_fmt[i].sizeimage) { in ceu_vb2_prepare()
665 dev_err(ceudev->dev, in ceu_vb2_prepare()
668 pix->plane_fmt[i].sizeimage); in ceu_vb2_prepare()
669 return -EINVAL; in ceu_vb2_prepare()
672 vb2_set_plane_payload(vb, i, pix->plane_fmt[i].sizeimage); in ceu_vb2_prepare()
681 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_start_streaming()
692 if (ret && ret != -ENOIOCTLCMD) { in ceu_start_streaming()
693 dev_dbg(ceudev->dev, in ceu_start_streaming()
698 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_start_streaming()
699 ceudev->sequence = 0; in ceu_start_streaming()
702 buf = list_first_entry(&ceudev->capture, struct ceu_buffer, in ceu_start_streaming()
705 list_del(&buf->queue); in ceu_start_streaming()
706 ceudev->active = &buf->vb; in ceu_start_streaming()
709 ceu_write(ceudev, CEU_CETCR, ~ceudev->irq_mask); in ceu_start_streaming()
714 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_start_streaming()
719 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_start_streaming()
720 list_for_each_entry(buf, &ceudev->capture, queue) in ceu_start_streaming()
721 vb2_buffer_done(&ceudev->active->vb2_buf, in ceu_start_streaming()
723 ceudev->active = NULL; in ceu_start_streaming()
724 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_start_streaming()
732 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_stop_streaming()
738 ceu_read(ceudev, CEU_CETCR) & ceudev->irq_mask); in ceu_stop_streaming()
743 spin_lock_irqsave(&ceudev->lock, irqflags); in ceu_stop_streaming()
744 if (ceudev->active) { in ceu_stop_streaming()
745 vb2_buffer_done(&ceudev->active->vb2_buf, in ceu_stop_streaming()
747 ceudev->active = NULL; in ceu_stop_streaming()
751 list_for_each_entry(buf, &ceudev->capture, queue) in ceu_stop_streaming()
752 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in ceu_stop_streaming()
753 INIT_LIST_HEAD(&ceudev->capture); in ceu_stop_streaming()
755 spin_unlock_irqrestore(&ceudev->lock, irqflags); in ceu_stop_streaming()
768 /* --- CEU image formats handling --- */
771 * __ceu_try_fmt() - test format on CEU and sensor
781 struct ceu_subdev *ceu_sd = ceudev->sd; in __ceu_try_fmt()
782 struct v4l2_pix_format_mplane *pix = &v4l2_fmt->fmt.pix_mp; in __ceu_try_fmt()
783 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in __ceu_try_fmt()
802 mbus_code_old = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
804 switch (pix->pixelformat) { in __ceu_try_fmt()
821 mbus_code = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
825 pix->pixelformat = V4L2_PIX_FMT_NV16; in __ceu_try_fmt()
826 mbus_code = ceu_sd->mbus_fmt.mbus_code; in __ceu_try_fmt()
830 ceu_fmt = get_ceu_fmt_from_fourcc(pix->pixelformat); in __ceu_try_fmt()
832 /* CFSZR requires height and width to be 4-pixel aligned. */ in __ceu_try_fmt()
833 v4l_bound_align_image(&pix->width, 2, CEU_MAX_WIDTH, 4, in __ceu_try_fmt()
834 &pix->height, 4, CEU_MAX_HEIGHT, 4, 0); in __ceu_try_fmt()
846 if (ret == -EINVAL) { in __ceu_try_fmt()
860 /* Calculate per-plane sizes based on image format. */ in __ceu_try_fmt()
870 * ceu_try_fmt() - Wrapper for __ceu_try_fmt; discard configured mbus_fmt
880 * ceu_set_fmt() - Apply the supplied format to both sensor and CEU
884 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_set_fmt()
885 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_set_fmt()
902 v4l2_fill_mbus_format_mplane(&format.format, &v4l2_fmt->fmt.pix_mp); in ceu_set_fmt()
907 ceudev->v4l2_pix = v4l2_fmt->fmt.pix_mp; in ceu_set_fmt()
908 ceudev->field = V4L2_FIELD_NONE; in ceu_set_fmt()
914 * ceu_set_default_fmt() - Apply default NV16 memory output format with VGA
946 ceudev->v4l2_pix = v4l2_fmt.fmt.pix_mp; in ceu_set_default_fmt()
947 ceudev->field = V4L2_FIELD_NONE; in ceu_set_default_fmt()
953 * ceu_init_mbus_fmt() - Query sensor for supported formats and initialize
956 * Find out if sensor can produce a permutation of 8-bits YUYV bus format.
957 * From a single 8-bits YUYV bus format the CEU can produce several memory
959 * - NV[12|21|16|61] through image fetch mode;
960 * - YUYV422 if sensor provides YUYV422
967 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_init_mbus_fmt()
968 struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; in ceu_init_mbus_fmt()
969 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_init_mbus_fmt()
977 /* Find out if sensor can produce any permutation of 8-bits YUYV422. */ in ceu_init_mbus_fmt()
990 * Only support 8-bits YUYV bus formats at the moment; in ceu_init_mbus_fmt()
1002 return -ENXIO; in ceu_init_mbus_fmt()
1007 * well as for data synch fetch mode (YUYV - YVYU etc. ). in ceu_init_mbus_fmt()
1009 mbus_fmt->mbus_code = sd_mbus_fmt.code; in ceu_init_mbus_fmt()
1010 mbus_fmt->bps = 8; in ceu_init_mbus_fmt()
1015 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YUYV; in ceu_init_mbus_fmt()
1016 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YVYU; in ceu_init_mbus_fmt()
1017 mbus_fmt->swapped = false; in ceu_init_mbus_fmt()
1018 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1022 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YVYU; in ceu_init_mbus_fmt()
1023 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YUYV; in ceu_init_mbus_fmt()
1024 mbus_fmt->swapped = true; in ceu_init_mbus_fmt()
1025 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1029 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_UYVY; in ceu_init_mbus_fmt()
1030 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_VYUY; in ceu_init_mbus_fmt()
1031 mbus_fmt->swapped = false; in ceu_init_mbus_fmt()
1032 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1036 mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_VYUY; in ceu_init_mbus_fmt()
1037 mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_UYVY; in ceu_init_mbus_fmt()
1038 mbus_fmt->swapped = true; in ceu_init_mbus_fmt()
1039 mbus_fmt->bpp = 16; in ceu_init_mbus_fmt()
1046 /* --- Runtime PM Handlers --- */
1049 * ceu_runtime_resume() - soft-reset the interface and turn sensor power on.
1054 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_runtime_resume()
1064 * ceu_runtime_suspend() - disable capture and interrupts and soft-reset.
1070 struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; in ceu_runtime_suspend()
1080 /* --- File Operations --- */
1091 mutex_lock(&ceudev->mlock); in ceu_open()
1092 /* Causes soft-reset and sensor power on on first open */ in ceu_open()
1093 ret = pm_runtime_resume_and_get(ceudev->dev); in ceu_open()
1094 mutex_unlock(&ceudev->mlock); in ceu_open()
1105 mutex_lock(&ceudev->mlock); in ceu_release()
1106 /* Causes soft-reset and sensor power down on last close */ in ceu_release()
1107 pm_runtime_put(ceudev->dev); in ceu_release()
1108 mutex_unlock(&ceudev->mlock); in ceu_release()
1122 /* --- Video Device IOCTLs --- */
1129 strscpy(cap->card, "Renesas CEU", sizeof(cap->card)); in ceu_querycap()
1130 strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); in ceu_querycap()
1131 snprintf(cap->bus_info, sizeof(cap->bus_info), in ceu_querycap()
1132 "platform:renesas-ceu-%s", dev_name(ceudev->dev)); in ceu_querycap()
1142 if (f->index >= ARRAY_SIZE(ceu_fmt_list)) in ceu_enum_fmt_vid_cap()
1143 return -EINVAL; in ceu_enum_fmt_vid_cap()
1145 fmt = &ceu_fmt_list[f->index]; in ceu_enum_fmt_vid_cap()
1146 f->pixelformat = fmt->fourcc; in ceu_enum_fmt_vid_cap()
1164 if (vb2_is_streaming(&ceudev->vb2_vq)) in ceu_s_fmt_vid_cap()
1165 return -EBUSY; in ceu_s_fmt_vid_cap()
1175 f->fmt.pix_mp = ceudev->v4l2_pix; in ceu_g_fmt_vid_cap()
1185 if (inp->index >= ceudev->num_sd) in ceu_enum_input()
1186 return -EINVAL; in ceu_enum_input()
1188 inp->type = V4L2_INPUT_TYPE_CAMERA; in ceu_enum_input()
1189 inp->std = 0; in ceu_enum_input()
1190 snprintf(inp->name, sizeof(inp->name), "Camera %u", inp->index); in ceu_enum_input()
1199 *i = ceudev->sd_index; in ceu_g_input()
1210 if (i >= ceudev->num_sd) in ceu_s_input()
1211 return -EINVAL; in ceu_s_input()
1213 if (vb2_is_streaming(&ceudev->vb2_vq)) in ceu_s_input()
1214 return -EBUSY; in ceu_s_input()
1216 if (i == ceudev->sd_index) in ceu_s_input()
1219 ceu_sd_old = ceudev->sd; in ceu_s_input()
1220 ceudev->sd = ceudev->subdevs[i]; in ceu_s_input()
1228 ceudev->sd = ceu_sd_old; in ceu_s_input()
1229 return -EINVAL; in ceu_s_input()
1234 ceudev->sd = ceu_sd_old; in ceu_s_input()
1235 return -EINVAL; in ceu_s_input()
1239 v4l2_subdev_call(ceu_sd_old->v4l2_sd, core, s_power, 0); in ceu_s_input()
1240 v4l2_subdev_call(ceudev->sd->v4l2_sd, core, s_power, 1); in ceu_s_input()
1242 ceudev->sd_index = i; in ceu_s_input()
1251 return v4l2_g_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); in ceu_g_parm()
1258 return v4l2_s_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); in ceu_s_parm()
1265 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_enum_framesizes()
1267 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_enum_framesizes()
1271 .code = ceu_sd->mbus_fmt.mbus_code, in ceu_enum_framesizes()
1272 .index = fsize->index, in ceu_enum_framesizes()
1277 ceu_fmt = get_ceu_fmt_from_fourcc(fsize->pixel_format); in ceu_enum_framesizes()
1279 return -EINVAL; in ceu_enum_framesizes()
1286 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in ceu_enum_framesizes()
1287 fsize->discrete.width = CEU_W_MAX(fse.max_width); in ceu_enum_framesizes()
1288 fsize->discrete.height = CEU_H_MAX(fse.max_height); in ceu_enum_framesizes()
1297 struct ceu_subdev *ceu_sd = ceudev->sd; in ceu_enum_frameintervals()
1299 struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; in ceu_enum_frameintervals()
1303 .code = ceu_sd->mbus_fmt.mbus_code, in ceu_enum_frameintervals()
1304 .index = fival->index, in ceu_enum_frameintervals()
1305 .width = fival->width, in ceu_enum_frameintervals()
1306 .height = fival->height, in ceu_enum_frameintervals()
1311 ceu_fmt = get_ceu_fmt_from_fourcc(fival->pixel_format); in ceu_enum_frameintervals()
1313 return -EINVAL; in ceu_enum_frameintervals()
1320 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; in ceu_enum_frameintervals()
1321 fival->discrete = fie.interval; in ceu_enum_frameintervals()
1359 * ceu_vdev_release() - release CEU video device memory when last reference
1373 struct v4l2_device *v4l2_dev = notifier->v4l2_dev; in ceu_notify_bound()
1377 ceu_sd->v4l2_sd = v4l2_sd; in ceu_notify_bound()
1378 ceudev->num_sd++; in ceu_notify_bound()
1385 struct v4l2_device *v4l2_dev = notifier->v4l2_dev; in ceu_notify_complete()
1387 struct video_device *vdev = &ceudev->vdev; in ceu_notify_complete()
1388 struct vb2_queue *q = &ceudev->vb2_vq; in ceu_notify_complete()
1393 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in ceu_notify_complete()
1394 q->io_modes = VB2_MMAP | VB2_DMABUF; in ceu_notify_complete()
1395 q->drv_priv = ceudev; in ceu_notify_complete()
1396 q->ops = &ceu_vb2_ops; in ceu_notify_complete()
1397 q->mem_ops = &vb2_dma_contig_memops; in ceu_notify_complete()
1398 q->buf_struct_size = sizeof(struct ceu_buffer); in ceu_notify_complete()
1399 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in ceu_notify_complete()
1400 q->min_queued_buffers = 2; in ceu_notify_complete()
1401 q->lock = &ceudev->mlock; in ceu_notify_complete()
1402 q->dev = ceudev->v4l2_dev.dev; in ceu_notify_complete()
1412 if (!ceudev->sd) { in ceu_notify_complete()
1413 ceudev->sd = ceudev->subdevs[0]; in ceu_notify_complete()
1414 ceudev->sd_index = 0; in ceu_notify_complete()
1417 v4l2_sd = ceudev->sd->v4l2_sd; in ceu_notify_complete()
1428 strscpy(vdev->name, DRIVER_NAME, sizeof(vdev->name)); in ceu_notify_complete()
1429 vdev->v4l2_dev = v4l2_dev; in ceu_notify_complete()
1430 vdev->lock = &ceudev->mlock; in ceu_notify_complete()
1431 vdev->queue = &ceudev->vb2_vq; in ceu_notify_complete()
1432 vdev->ctrl_handler = v4l2_sd->ctrl_handler; in ceu_notify_complete()
1433 vdev->fops = &ceu_fops; in ceu_notify_complete()
1434 vdev->ioctl_ops = &ceu_ioctl_ops; in ceu_notify_complete()
1435 vdev->release = ceu_vdev_release; in ceu_notify_complete()
1436 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | in ceu_notify_complete()
1440 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in ceu_notify_complete()
1442 v4l2_err(vdev->v4l2_dev, in ceu_notify_complete()
1456 * ceu_init_async_subdevs() - Initialize CEU subdevices and async_subdevs in
1460 * Returns 0 for success, -ENOMEM for failure.
1465 ceudev->subdevs = devm_kcalloc(ceudev->dev, n_sd, in ceu_init_async_subdevs()
1466 sizeof(*ceudev->subdevs), GFP_KERNEL); in ceu_init_async_subdevs()
1467 if (!ceudev->subdevs) in ceu_init_async_subdevs()
1468 return -ENOMEM; in ceu_init_async_subdevs()
1470 ceudev->sd = NULL; in ceu_init_async_subdevs()
1471 ceudev->sd_index = 0; in ceu_init_async_subdevs()
1472 ceudev->num_sd = 0; in ceu_init_async_subdevs()
1478 * ceu_parse_platform_data() - Initialize async_subdevices using platform
1489 if (pdata->num_subdevs == 0) in ceu_parse_platform_data()
1490 return -ENODEV; in ceu_parse_platform_data()
1492 ret = ceu_init_async_subdevs(ceudev, pdata->num_subdevs); in ceu_parse_platform_data()
1496 for (i = 0; i < pdata->num_subdevs; i++) { in ceu_parse_platform_data()
1499 async_sd = &pdata->subdevs[i]; in ceu_parse_platform_data()
1500 ceu_sd = v4l2_async_nf_add_i2c(&ceudev->notifier, in ceu_parse_platform_data()
1501 async_sd->i2c_adapter_id, in ceu_parse_platform_data()
1502 async_sd->i2c_address, in ceu_parse_platform_data()
1505 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_parse_platform_data()
1508 ceu_sd->mbus_flags = async_sd->flags; in ceu_parse_platform_data()
1509 ceudev->subdevs[i] = ceu_sd; in ceu_parse_platform_data()
1512 return pdata->num_subdevs; in ceu_parse_platform_data()
1516 * ceu_parse_dt() - Initialize async_subdevs parsing device tree graph.
1520 struct device_node *of = ceudev->dev->of_node; in ceu_parse_dt()
1529 return -ENODEV; in ceu_parse_dt()
1549 dev_err(ceudev->dev, in ceu_parse_dt()
1551 ret = -ENODEV; in ceu_parse_dt()
1557 dev_err(ceudev->dev, in ceu_parse_dt()
1563 ceu_sd = v4l2_async_nf_add_fwnode_remote(&ceudev->notifier, in ceu_parse_dt()
1570 ceu_sd->mbus_flags = fw_ep.bus.parallel.flags; in ceu_parse_dt()
1571 ceudev->subdevs[i] = ceu_sd; in ceu_parse_dt()
1579 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_parse_dt()
1585 * struct ceu_data - Platform specific CEU data
1603 { .compatible = "renesas,r7s72100-ceu", .data = &ceu_data_rz },
1604 { .compatible = "renesas,r8a7740-ceu", .data = &ceu_data_rz },
1612 struct device *dev = &pdev->dev; in ceu_probe()
1621 return -ENOMEM; in ceu_probe()
1624 ceudev->dev = dev; in ceu_probe()
1626 INIT_LIST_HEAD(&ceudev->capture); in ceu_probe()
1627 spin_lock_init(&ceudev->lock); in ceu_probe()
1628 mutex_init(&ceudev->mlock); in ceu_probe()
1630 ceudev->base = devm_platform_ioremap_resource(pdev, 0); in ceu_probe()
1631 if (IS_ERR(ceudev->base)) { in ceu_probe()
1632 ret = PTR_ERR(ceudev->base); in ceu_probe()
1644 dev_err(&pdev->dev, "Unable to request CEU interrupt.\n"); in ceu_probe()
1650 ret = v4l2_device_register(dev, &ceudev->v4l2_dev); in ceu_probe()
1654 v4l2_async_nf_init(&ceudev->notifier, &ceudev->v4l2_dev); in ceu_probe()
1656 if (IS_ENABLED(CONFIG_OF) && dev->of_node) { in ceu_probe()
1659 } else if (dev->platform_data) { in ceu_probe()
1663 dev->platform_data); in ceu_probe()
1665 num_subdevs = -EINVAL; in ceu_probe()
1672 ceudev->irq_mask = ceu_data->irq_mask; in ceu_probe()
1674 ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; in ceu_probe()
1675 ceudev->notifier.ops = &ceu_notify_ops; in ceu_probe()
1676 ret = v4l2_async_nf_register(&ceudev->notifier); in ceu_probe()
1685 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_probe()
1687 v4l2_device_unregister(&ceudev->v4l2_dev); in ceu_probe()
1700 pm_runtime_disable(ceudev->dev); in ceu_remove()
1702 v4l2_async_nf_unregister(&ceudev->notifier); in ceu_remove()
1704 v4l2_async_nf_cleanup(&ceudev->notifier); in ceu_remove()
1706 v4l2_device_unregister(&ceudev->v4l2_dev); in ceu_remove()
1708 video_unregister_device(&ceudev->vdev); in ceu_remove()