Lines Matching +full:capture +full:- +full:sd +full:- +full:lines

1 // SPDX-License-Identifier: GPL-2.0-only
3 * BCM283x / BCM271x Unicam Capture Driver
5 * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
6 * Copyright (C) 2024 - Ideas on Board
18 * There are two camera drivers in the kernel for BCM283x - this one and
19 * bcm2835-camera (currently in staging).
21 * This driver directly controls the Unicam peripheral - there is no
22 * involvement with the VideoCore firmware. Unicam receives CSI-2 or CCP2 data
37 #include <linux/dma-mapping.h>
49 #include <media/mipi-csi2.h>
50 #include <media/v4l2-async.h>
51 #include <media/v4l2-common.h>
52 #include <media/v4l2-dev.h>
53 #include <media/v4l2-device.h>
54 #include <media/v4l2-event.h>
55 #include <media/v4l2-ioctl.h>
56 #include <media/v4l2-fwnode.h>
57 #include <media/v4l2-mc.h>
58 #include <media/v4l2-subdev.h>
59 #include <media/videobuf2-dma-contig.h>
61 #include "bcm2835-unicam-regs.h"
81 #define UNICAM_IMAGE_MAX_BPL ((1U << 16) - UNICAM_IMAGE_BPL_ALIGNMENT)
123 * struct unicam_format_info - Unicam media bus format information
163 /* Buffer queue used in video-buf */
212 struct v4l2_subdev sd; member
243 sd_to_unicam_device(struct v4l2_subdev *sd) in sd_to_unicam_device() argument
245 return container_of(sd, struct unicam_device, subdev.sd); in sd_to_unicam_device()
253 if (unicam->mdev.dev) in unicam_release()
254 media_device_cleanup(&unicam->mdev); in unicam_release()
256 mutex_destroy(&unicam->lock); in unicam_release()
262 kref_get(&unicam->kref); in unicam_get()
269 kref_put(&unicam->kref, unicam_release); in unicam_put()
272 /* -----------------------------------------------------------------------------
284 return node->video_dev.device_caps & V4L2_CAP_META_CAPTURE; in is_metadata_node()
289 return node->video_dev.device_caps & V4L2_CAP_VIDEO_CAPTURE; in is_image_node()
292 /* -----------------------------------------------------------------------------
564 v4l_bound_align_image(&pix->width, UNICAM_IMAGE_MIN_WIDTH, in unicam_calc_image_size_bpl()
566 &pix->height, UNICAM_IMAGE_MIN_HEIGHT, in unicam_calc_image_size_bpl()
570 if (pix->pixelformat == fmtinfo->unpacked_fourcc) in unicam_calc_image_size_bpl()
571 min_bpl = pix->width * 2; in unicam_calc_image_size_bpl()
573 min_bpl = pix->width * fmtinfo->depth / 8; in unicam_calc_image_size_bpl()
576 pix->bytesperline = ALIGN(pix->bytesperline, UNICAM_IMAGE_BPL_ALIGNMENT); in unicam_calc_image_size_bpl()
577 pix->bytesperline = clamp_t(unsigned int, pix->bytesperline, min_bpl, in unicam_calc_image_size_bpl()
580 pix->sizeimage = pix->height * pix->bytesperline; in unicam_calc_image_size_bpl()
587 v4l_bound_align_image(&meta->width, UNICAM_META_MIN_WIDTH, in unicam_calc_meta_size_bpl()
589 &meta->height, UNICAM_META_MIN_HEIGHT, in unicam_calc_meta_size_bpl()
592 meta->bytesperline = ALIGN(meta->width * fmtinfo->depth / 8, in unicam_calc_meta_size_bpl()
594 meta->buffersize = meta->height * meta->bytesperline; in unicam_calc_meta_size_bpl()
597 /* -----------------------------------------------------------------------------
604 writel(val | 0x5a000000, unicam->clk_gate_base); in unicam_clk_write()
609 return readl(unicam->base + offset); in unicam_reg_read()
614 writel(val, unicam->base + offset); in unicam_reg_write()
649 dma_addr_t endaddr = buf->dma_addr + in unicam_wr_dma_addr()
650 (buf != &node->dummy_buf ? buf->size : 0); in unicam_wr_dma_addr()
652 if (node->id == UNICAM_IMAGE_NODE) { in unicam_wr_dma_addr()
653 unicam_reg_write(node->dev, UNICAM_IBSA0, buf->dma_addr); in unicam_wr_dma_addr()
654 unicam_reg_write(node->dev, UNICAM_IBEA0, endaddr); in unicam_wr_dma_addr()
656 unicam_reg_write(node->dev, UNICAM_DBSA0, buf->dma_addr); in unicam_wr_dma_addr()
657 unicam_reg_write(node->dev, UNICAM_DBEA0, endaddr); in unicam_wr_dma_addr()
663 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_get_lines_done()
664 unsigned int stride = node->fmt.fmt.pix.bytesperline; in unicam_get_lines_done()
665 struct unicam_buffer *frm = node->cur_frm; in unicam_get_lines_done()
672 return (unsigned int)(cur_addr - frm->dma_addr) / stride; in unicam_get_lines_done()
679 buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); in unicam_schedule_next_buffer()
680 node->next_frm = buf; in unicam_schedule_next_buffer()
681 list_del(&buf->list); in unicam_schedule_next_buffer()
690 dev_dbg(node->dev->dev, "Scheduling dummy buffer for node %d\n", node_id); in unicam_schedule_dummy_buffer()
692 unicam_wr_dma_addr(node, &node->dummy_buf); in unicam_schedule_dummy_buffer()
694 node->next_frm = NULL; in unicam_schedule_dummy_buffer()
700 node->cur_frm->vb.field = node->fmt.fmt.pix.field; in unicam_process_buffer_complete()
701 node->cur_frm->vb.sequence = sequence; in unicam_process_buffer_complete()
703 vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); in unicam_process_buffer_complete()
708 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_queue_event_sof()
711 .u.frame_sync.frame_sequence = unicam->sequence, in unicam_queue_event_sof()
714 v4l2_event_queue(&node->video_dev, &event); in unicam_queue_event_sof()
721 unsigned int sequence = unicam->sequence; in unicam_isr()
735 dev_dbg(unicam->dev, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d\n", in unicam_isr()
742 * Look for either the Frame End interrupt or the Packet Capture status in unicam_isr()
754 bool inc_seq = unicam->frame_started; in unicam_isr()
762 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_isr()
763 struct unicam_node *node = &unicam->node[i]; in unicam_isr()
765 if (!vb2_start_streaming_called(&node->buffer_queue)) in unicam_isr()
775 if (node->cur_frm && node->cur_frm != node->next_frm) { in unicam_isr()
779 node->cur_frm = node->next_frm; in unicam_isr()
790 unicam->sequence++; in unicam_isr()
791 unicam->frame_started = false; in unicam_isr()
801 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_isr()
802 struct unicam_node *node = &unicam->node[i]; in unicam_isr()
804 if (!vb2_start_streaming_called(&node->buffer_queue)) in unicam_isr()
807 if (node->cur_frm) in unicam_isr()
808 node->cur_frm->vb.vb2_buf.timestamp = ts; in unicam_isr()
810 dev_dbg(unicam->v4l2_dev.dev, in unicam_isr()
822 unicam->frame_started = true; in unicam_isr()
831 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_isr()
832 struct unicam_node *node = &unicam->node[i]; in unicam_isr()
834 if (!vb2_start_streaming_called(&node->buffer_queue)) in unicam_isr()
837 spin_lock(&node->dma_queue_lock); in unicam_isr()
838 if (!list_empty(&node->dma_queue) && !node->next_frm) in unicam_isr()
840 spin_unlock(&node->dma_queue_lock); in unicam_isr()
850 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_set_packing_config()
854 if (node->fmt.fmt.pix.pixelformat == fmtinfo->fourcc) { in unicam_set_packing_config()
858 unpack = fmtinfo->unpack; in unicam_set_packing_config()
871 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_cfg_image_id()
899 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, in unicam_get_image_vc_dt()
905 ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_frame_desc, in unicam_get_image_vc_dt()
906 unicam->sensor.pad->index, &fd); in unicam_get_image_vc_dt()
910 /* Only CSI-2 supports DTs. */ in unicam_get_image_vc_dt()
912 return -EINVAL; in unicam_get_image_vc_dt()
917 if (fde->stream == stream) { in unicam_get_image_vc_dt()
918 *vc = fde->bus.csi2.vc; in unicam_get_image_vc_dt()
919 *dt = fde->bus.csi2.dt; in unicam_get_image_vc_dt()
924 return -EINVAL; in unicam_get_image_vc_dt()
930 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_start_rx()
939 fmtinfo = unicam_find_format_by_code(fmt->code, in unicam_start_rx()
947 * [9:8] - DAT3 in unicam_start_rx()
948 * [7:6] - DAT2 in unicam_start_rx()
949 * [5:4] - DAT1 in unicam_start_rx()
950 * [3:2] - DAT0 in unicam_start_rx()
951 * [1:0] - CLK in unicam_start_rx()
956 val = 0x155 & GENMASK(unicam->pipe.num_data_lanes * 2 + 1, 0); in unicam_start_rx()
980 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_start_rx()
985 unicam_set_field(&val, unicam->bus_flags, UNICAM_DCM_MASK); in unicam_start_rx()
1008 line_int_freq = max(fmt->height >> 2, 128); in unicam_start_rx()
1027 /* Packet compare setup - required to avoid missing frame ends */ in unicam_start_rx()
1038 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_start_rx()
1042 if (!(unicam->bus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) { in unicam_start_rx()
1060 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_start_rx()
1064 if (!(unicam->bus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) { in unicam_start_rx()
1076 if (unicam->pipe.num_data_lanes == 1) in unicam_start_rx()
1080 if (unicam->max_data_lanes > 2) { in unicam_start_rx()
1085 if (unicam->pipe.num_data_lanes == 2) in unicam_start_rx()
1089 if (unicam->pipe.num_data_lanes == 3) in unicam_start_rx()
1095 node->fmt.fmt.pix.bytesperline); in unicam_start_rx()
1096 unicam_wr_dma_addr(node, node->cur_frm); in unicam_start_rx()
1106 dt = fmtinfo->csi_dt; in unicam_start_rx()
1131 struct unicam_node *node = &unicam->node[UNICAM_METADATA_NODE]; in unicam_start_metadata()
1134 unicam_wr_dma_addr(node, node->cur_frm); in unicam_start_metadata()
1150 if (unicam->max_data_lanes > 2) { in unicam_disable()
1170 /* -----------------------------------------------------------------------------
1174 static int __unicam_subdev_set_routing(struct v4l2_subdev *sd, in __unicam_subdev_set_routing() argument
1181 ret = v4l2_subdev_routing_validate(sd, routing, in __unicam_subdev_set_routing()
1186 ret = v4l2_subdev_set_routing(sd, state, routing); in __unicam_subdev_set_routing()
1190 for_each_active_route(&state->routing, route) { in __unicam_subdev_set_routing()
1194 if (route->source_pad == UNICAM_SD_PAD_SOURCE_IMAGE) in __unicam_subdev_set_routing()
1199 fmt = v4l2_subdev_state_get_format(state, route->sink_pad, in __unicam_subdev_set_routing()
1200 route->sink_stream); in __unicam_subdev_set_routing()
1202 fmt = v4l2_subdev_state_get_format(state, route->source_pad, in __unicam_subdev_set_routing()
1203 route->source_stream); in __unicam_subdev_set_routing()
1210 static int unicam_subdev_init_state(struct v4l2_subdev *sd, in unicam_subdev_init_state() argument
1230 return __unicam_subdev_set_routing(sd, state, &routing); in unicam_subdev_init_state()
1233 static int unicam_subdev_enum_mbus_code(struct v4l2_subdev *sd, in unicam_subdev_enum_mbus_code() argument
1240 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, in unicam_subdev_enum_mbus_code()
1241 code->pad, code->stream, in unicam_subdev_enum_mbus_code()
1246 if (unicam_sd_pad_is_source(code->pad)) { in unicam_subdev_enum_mbus_code()
1252 return -EINVAL; in unicam_subdev_enum_mbus_code()
1254 if (code->index > 0) in unicam_subdev_enum_mbus_code()
1255 return -EINVAL; in unicam_subdev_enum_mbus_code()
1257 code->code = fmt->code; in unicam_subdev_enum_mbus_code()
1270 if (code->index >= num_formats) in unicam_subdev_enum_mbus_code()
1271 return -EINVAL; in unicam_subdev_enum_mbus_code()
1273 code->code = formats[code->index].code; in unicam_subdev_enum_mbus_code()
1279 static int unicam_subdev_enum_frame_size(struct v4l2_subdev *sd, in unicam_subdev_enum_frame_size() argument
1286 if (fse->index > 0) in unicam_subdev_enum_frame_size()
1287 return -EINVAL; in unicam_subdev_enum_frame_size()
1289 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, fse->pad, in unicam_subdev_enum_frame_size()
1290 fse->stream, &pad, in unicam_subdev_enum_frame_size()
1295 if (unicam_sd_pad_is_source(fse->pad)) { in unicam_subdev_enum_frame_size()
1301 return -EINVAL; in unicam_subdev_enum_frame_size()
1303 if (fse->code != fmt->code) in unicam_subdev_enum_frame_size()
1304 return -EINVAL; in unicam_subdev_enum_frame_size()
1306 fse->min_width = fmt->width; in unicam_subdev_enum_frame_size()
1307 fse->max_width = fmt->width; in unicam_subdev_enum_frame_size()
1308 fse->min_height = fmt->height; in unicam_subdev_enum_frame_size()
1309 fse->max_height = fmt->height; in unicam_subdev_enum_frame_size()
1313 fmtinfo = unicam_find_format_by_code(fse->code, pad); in unicam_subdev_enum_frame_size()
1315 return -EINVAL; in unicam_subdev_enum_frame_size()
1318 fse->min_width = UNICAM_IMAGE_MIN_WIDTH; in unicam_subdev_enum_frame_size()
1319 fse->max_width = UNICAM_IMAGE_MAX_WIDTH; in unicam_subdev_enum_frame_size()
1320 fse->min_height = UNICAM_IMAGE_MIN_HEIGHT; in unicam_subdev_enum_frame_size()
1321 fse->max_height = UNICAM_IMAGE_MAX_HEIGHT; in unicam_subdev_enum_frame_size()
1323 fse->min_width = UNICAM_META_MIN_WIDTH; in unicam_subdev_enum_frame_size()
1324 fse->max_width = UNICAM_META_MAX_WIDTH; in unicam_subdev_enum_frame_size()
1325 fse->min_height = UNICAM_META_MIN_HEIGHT; in unicam_subdev_enum_frame_size()
1326 fse->max_height = UNICAM_META_MAX_HEIGHT; in unicam_subdev_enum_frame_size()
1333 static int unicam_subdev_set_format(struct v4l2_subdev *sd, in unicam_subdev_set_format() argument
1337 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_subdev_set_format()
1343 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && in unicam_subdev_set_format()
1344 unicam->subdev.enabled_streams) in unicam_subdev_set_format()
1345 return -EBUSY; in unicam_subdev_set_format()
1348 if (unicam_sd_pad_is_source(format->pad)) in unicam_subdev_set_format()
1349 return v4l2_subdev_get_fmt(sd, state, format); in unicam_subdev_set_format()
1356 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, in unicam_subdev_set_format()
1357 format->pad, format->stream, in unicam_subdev_set_format()
1362 fmtinfo = unicam_find_format_by_code(format->format.code, source_pad); in unicam_subdev_set_format()
1366 format->format.code = fmtinfo->code; in unicam_subdev_set_format()
1370 format->format.width = clamp_t(unsigned int, in unicam_subdev_set_format()
1371 format->format.width, in unicam_subdev_set_format()
1374 format->format.height = clamp_t(unsigned int, in unicam_subdev_set_format()
1375 format->format.height, in unicam_subdev_set_format()
1378 format->format.field = V4L2_FIELD_NONE; in unicam_subdev_set_format()
1380 format->format.width = clamp_t(unsigned int, in unicam_subdev_set_format()
1381 format->format.width, in unicam_subdev_set_format()
1384 format->format.height = clamp_t(unsigned int, in unicam_subdev_set_format()
1385 format->format.height, in unicam_subdev_set_format()
1388 format->format.field = V4L2_FIELD_NONE; in unicam_subdev_set_format()
1391 format->format.colorspace = 0; in unicam_subdev_set_format()
1392 format->format.ycbcr_enc = 0; in unicam_subdev_set_format()
1393 format->format.quantization = 0; in unicam_subdev_set_format()
1394 format->format.xfer_func = 0; in unicam_subdev_set_format()
1397 sink_format = v4l2_subdev_state_get_format(state, format->pad, in unicam_subdev_set_format()
1398 format->stream); in unicam_subdev_set_format()
1401 *sink_format = format->format; in unicam_subdev_set_format()
1402 *source_format = format->format; in unicam_subdev_set_format()
1407 static int unicam_subdev_set_routing(struct v4l2_subdev *sd, in unicam_subdev_set_routing() argument
1412 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_subdev_set_routing()
1414 if (which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->subdev.enabled_streams) in unicam_subdev_set_routing()
1415 return -EBUSY; in unicam_subdev_set_routing()
1417 return __unicam_subdev_set_routing(sd, state, routing); in unicam_subdev_set_routing()
1420 static int unicam_sd_enable_streams(struct v4l2_subdev *sd, in unicam_sd_enable_streams() argument
1424 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_sd_enable_streams()
1428 if (!unicam->subdev.enabled_streams) { in unicam_sd_enable_streams()
1430 unicam->sequence = 0; in unicam_sd_enable_streams()
1432 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) in unicam_sd_enable_streams()
1435 unicam->frame_started = false; in unicam_sd_enable_streams()
1439 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0, in unicam_sd_enable_streams()
1444 ret = v4l2_subdev_enable_streams(unicam->sensor.subdev, in unicam_sd_enable_streams()
1445 unicam->sensor.pad->index, in unicam_sd_enable_streams()
1448 dev_err(unicam->dev, "stream on failed in subdev\n"); in unicam_sd_enable_streams()
1452 unicam->subdev.enabled_streams |= BIT(other_stream); in unicam_sd_enable_streams()
1457 static int unicam_sd_disable_streams(struct v4l2_subdev *sd, in unicam_sd_disable_streams() argument
1461 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_sd_disable_streams()
1465 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0, in unicam_sd_disable_streams()
1470 v4l2_subdev_disable_streams(unicam->sensor.subdev, in unicam_sd_disable_streams()
1471 unicam->sensor.pad->index, in unicam_sd_disable_streams()
1474 unicam->subdev.enabled_streams &= ~BIT(other_stream); in unicam_sd_disable_streams()
1476 if (!unicam->subdev.enabled_streams) in unicam_sd_disable_streams()
1507 struct v4l2_subdev *sd = &unicam->subdev.sd; in unicam_subdev_init() local
1510 v4l2_subdev_init(sd, &unicam_subdev_ops); in unicam_subdev_init()
1511 sd->internal_ops = &unicam_subdev_internal_ops; in unicam_subdev_init()
1512 v4l2_set_subdevdata(sd, unicam); in unicam_subdev_init()
1514 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in unicam_subdev_init()
1515 sd->entity.ops = &unicam_subdev_media_ops; in unicam_subdev_init()
1516 sd->dev = unicam->dev; in unicam_subdev_init()
1517 sd->owner = THIS_MODULE; in unicam_subdev_init()
1518 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; in unicam_subdev_init()
1520 strscpy(sd->name, "unicam", sizeof(sd->name)); in unicam_subdev_init()
1522 unicam->subdev.pads[UNICAM_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in unicam_subdev_init()
1523 unicam->subdev.pads[UNICAM_SD_PAD_SOURCE_IMAGE].flags = MEDIA_PAD_FL_SOURCE; in unicam_subdev_init()
1524 unicam->subdev.pads[UNICAM_SD_PAD_SOURCE_METADATA].flags = MEDIA_PAD_FL_SOURCE; in unicam_subdev_init()
1526 ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(unicam->subdev.pads), in unicam_subdev_init()
1527 unicam->subdev.pads); in unicam_subdev_init()
1529 dev_err(unicam->dev, "Failed to initialize media entity: %d\n", in unicam_subdev_init()
1534 ret = v4l2_subdev_init_finalize(sd); in unicam_subdev_init()
1536 dev_err(unicam->dev, "Failed to initialize subdev: %d\n", ret); in unicam_subdev_init()
1540 ret = v4l2_device_register_subdev(&unicam->v4l2_dev, sd); in unicam_subdev_init()
1542 dev_err(unicam->dev, "Failed to register subdev: %d\n", ret); in unicam_subdev_init()
1549 v4l2_subdev_cleanup(sd); in unicam_subdev_init()
1551 media_entity_cleanup(&sd->entity); in unicam_subdev_init()
1557 v4l2_subdev_cleanup(&unicam->subdev.sd); in unicam_subdev_cleanup()
1558 media_entity_cleanup(&unicam->subdev.sd.entity); in unicam_subdev_cleanup()
1561 /* -----------------------------------------------------------------------------
1570 u32 size = is_image_node(node) ? node->fmt.fmt.pix.sizeimage in unicam_queue_setup()
1571 : node->fmt.fmt.meta.buffersize; in unicam_queue_setup()
1575 dev_dbg(node->dev->dev, "sizes[0] %i < size %u\n", in unicam_queue_setup()
1577 return -EINVAL; in unicam_queue_setup()
1590 struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); in unicam_buffer_prepare()
1592 u32 size = is_image_node(node) ? node->fmt.fmt.pix.sizeimage in unicam_buffer_prepare()
1593 : node->fmt.fmt.meta.buffersize; in unicam_buffer_prepare()
1596 dev_dbg(node->dev->dev, in unicam_buffer_prepare()
1599 return -EINVAL; in unicam_buffer_prepare()
1602 buf->dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); in unicam_buffer_prepare()
1603 buf->size = size; in unicam_buffer_prepare()
1605 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); in unicam_buffer_prepare()
1615 list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) { in unicam_return_buffers()
1616 list_del(&buf->list); in unicam_return_buffers()
1617 vb2_buffer_done(&buf->vb.vb2_buf, state); in unicam_return_buffers()
1620 if (node->cur_frm) in unicam_return_buffers()
1621 vb2_buffer_done(&node->cur_frm->vb.vb2_buf, in unicam_return_buffers()
1623 if (node->next_frm && node->cur_frm != node->next_frm) in unicam_return_buffers()
1624 vb2_buffer_done(&node->next_frm->vb.vb2_buf, in unicam_return_buffers()
1627 node->cur_frm = NULL; in unicam_return_buffers()
1628 node->next_frm = NULL; in unicam_return_buffers()
1637 if (unicam->bus_type != V4L2_MBUS_CSI2_DPHY) in unicam_num_data_lanes()
1638 return unicam->max_data_lanes; in unicam_num_data_lanes()
1640 ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_mbus_config, in unicam_num_data_lanes()
1641 unicam->sensor.pad->index, &mbus_config); in unicam_num_data_lanes()
1642 if (ret == -ENOIOCTLCMD) in unicam_num_data_lanes()
1643 return unicam->max_data_lanes; in unicam_num_data_lanes()
1646 dev_err(unicam->dev, "Failed to get mbus config: %d\n", ret); in unicam_num_data_lanes()
1653 dev_err(unicam->dev, in unicam_num_data_lanes()
1655 unicam->sensor.subdev->name, num_data_lanes); in unicam_num_data_lanes()
1656 return -EINVAL; in unicam_num_data_lanes()
1659 if (num_data_lanes > unicam->max_data_lanes) { in unicam_num_data_lanes()
1660 dev_err(unicam->dev, in unicam_num_data_lanes()
1662 unicam->sensor.subdev->name, num_data_lanes, in unicam_num_data_lanes()
1663 unicam->max_data_lanes); in unicam_num_data_lanes()
1664 return -EINVAL; in unicam_num_data_lanes()
1673 struct unicam_device *unicam = node->dev; in unicam_start_streaming()
1680 dev_dbg(unicam->dev, "Starting stream on %s device\n", in unicam_start_streaming()
1687 ret = video_device_pipeline_start(&node->video_dev, &unicam->pipe.pipe); in unicam_start_streaming()
1689 dev_dbg(unicam->dev, "Failed to start media pipeline: %d\n", ret); in unicam_start_streaming()
1697 if (unicam->pipe.pipe.start_count == 1) { in unicam_start_streaming()
1698 unicam->pipe.nodes = 0; in unicam_start_streaming()
1700 media_pipeline_for_each_pad(&unicam->pipe.pipe, &iter, pad) { in unicam_start_streaming()
1701 if (pad->entity != &unicam->subdev.sd.entity) in unicam_start_streaming()
1704 if (pad->index == UNICAM_SD_PAD_SOURCE_IMAGE) in unicam_start_streaming()
1705 unicam->pipe.nodes |= BIT(UNICAM_IMAGE_NODE); in unicam_start_streaming()
1706 else if (pad->index == UNICAM_SD_PAD_SOURCE_METADATA) in unicam_start_streaming()
1707 unicam->pipe.nodes |= BIT(UNICAM_METADATA_NODE); in unicam_start_streaming()
1710 if (!(unicam->pipe.nodes & BIT(UNICAM_IMAGE_NODE))) { in unicam_start_streaming()
1711 dev_dbg(unicam->dev, in unicam_start_streaming()
1713 ret = -EPIPE; in unicam_start_streaming()
1721 unicam->pipe.num_data_lanes = ret; in unicam_start_streaming()
1723 dev_dbg(unicam->dev, "Running with %u data lanes, nodes %u\n", in unicam_start_streaming()
1724 unicam->pipe.num_data_lanes, unicam->pipe.nodes); in unicam_start_streaming()
1728 spin_lock_irqsave(&node->dma_queue_lock, flags); in unicam_start_streaming()
1729 buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); in unicam_start_streaming()
1730 node->cur_frm = buf; in unicam_start_streaming()
1731 node->next_frm = buf; in unicam_start_streaming()
1732 list_del(&buf->list); in unicam_start_streaming()
1733 spin_unlock_irqrestore(&node->dma_queue_lock, flags); in unicam_start_streaming()
1740 * capture image data and embedded data from the same camera sensor. in unicam_start_streaming()
1742 * capture, it requires proper synchronization of the streams at start in unicam_start_streaming()
1745 if (unicam->pipe.pipe.start_count < hweight32(unicam->pipe.nodes)) in unicam_start_streaming()
1748 ret = pm_runtime_resume_and_get(unicam->dev); in unicam_start_streaming()
1750 dev_err(unicam->dev, "PM runtime resume failed: %d\n", ret); in unicam_start_streaming()
1755 ret = v4l2_subdev_enable_streams(&unicam->subdev.sd, in unicam_start_streaming()
1759 dev_err(unicam->dev, "stream on failed in subdev\n"); in unicam_start_streaming()
1763 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) { in unicam_start_streaming()
1764 ret = v4l2_subdev_enable_streams(&unicam->subdev.sd, in unicam_start_streaming()
1768 dev_err(unicam->dev, "stream on failed in subdev\n"); in unicam_start_streaming()
1776 v4l2_subdev_disable_streams(&unicam->subdev.sd, in unicam_start_streaming()
1779 pm_runtime_put_sync(unicam->dev); in unicam_start_streaming()
1781 video_device_pipeline_stop(&node->video_dev); in unicam_start_streaming()
1790 struct unicam_device *unicam = node->dev; in unicam_stop_streaming()
1793 if (unicam->pipe.pipe.start_count == hweight32(unicam->pipe.nodes)) { in unicam_stop_streaming()
1794 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) in unicam_stop_streaming()
1795 v4l2_subdev_disable_streams(&unicam->subdev.sd, in unicam_stop_streaming()
1799 v4l2_subdev_disable_streams(&unicam->subdev.sd, in unicam_stop_streaming()
1803 pm_runtime_put(unicam->dev); in unicam_stop_streaming()
1806 video_device_pipeline_stop(&node->video_dev); in unicam_stop_streaming()
1814 struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); in unicam_buffer_queue()
1817 spin_lock_irq(&node->dma_queue_lock); in unicam_buffer_queue()
1818 list_add_tail(&buf->list, &node->dma_queue); in unicam_buffer_queue()
1819 spin_unlock_irq(&node->dma_queue_lock); in unicam_buffer_queue()
1830 /* -----------------------------------------------------------------------------
1837 strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); in unicam_querycap()
1838 strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); in unicam_querycap()
1840 cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE; in unicam_querycap()
1852 if (f->mbus_code && unicam_image_formats[i].code != f->mbus_code) in unicam_enum_fmt_vid()
1855 if (index == f->index) { in unicam_enum_fmt_vid()
1856 f->pixelformat = unicam_image_formats[i].fourcc; in unicam_enum_fmt_vid()
1865 if (index == f->index) { in unicam_enum_fmt_vid()
1866 f->pixelformat = unicam_image_formats[i].unpacked_fourcc; in unicam_enum_fmt_vid()
1873 return -EINVAL; in unicam_enum_fmt_vid()
1881 *f = node->fmt; in unicam_g_fmt_vid()
1895 fmtinfo = unicam_find_format_by_fourcc(pix->pixelformat, in __unicam_try_fmt_vid()
1899 pix->pixelformat = fmtinfo->fourcc; in __unicam_try_fmt_vid()
1902 unicam_calc_image_size_bpl(node->dev, fmtinfo, pix); in __unicam_try_fmt_vid()
1904 if (pix->field == V4L2_FIELD_ANY) in __unicam_try_fmt_vid()
1905 pix->field = V4L2_FIELD_NONE; in __unicam_try_fmt_vid()
1913 __unicam_try_fmt_vid(node, &f->fmt.pix); in unicam_try_fmt_vid()
1922 if (vb2_is_busy(&node->buffer_queue)) in unicam_s_fmt_vid()
1923 return -EBUSY; in unicam_s_fmt_vid()
1925 __unicam_try_fmt_vid(node, &f->fmt.pix); in unicam_s_fmt_vid()
1926 node->fmt = *f; in unicam_s_fmt_vid()
1937 if (f->mbus_code && unicam_meta_formats[i].code != f->mbus_code) in unicam_enum_fmt_meta()
1940 if (index == f->index) { in unicam_enum_fmt_meta()
1941 f->pixelformat = unicam_meta_formats[i].fourcc; in unicam_enum_fmt_meta()
1942 f->type = V4L2_BUF_TYPE_META_CAPTURE; in unicam_enum_fmt_meta()
1943 f->flags = V4L2_FMT_FLAG_META_LINE_BASED; in unicam_enum_fmt_meta()
1950 return -EINVAL; in unicam_enum_fmt_meta()
1958 f->fmt.meta = node->fmt.fmt.meta; in unicam_g_fmt_meta()
1972 fmtinfo = unicam_find_format_by_fourcc(meta->dataformat, in __unicam_try_fmt_meta()
1976 meta->dataformat = fmtinfo->fourcc; in __unicam_try_fmt_meta()
1979 unicam_calc_meta_size_bpl(node->dev, fmtinfo, meta); in __unicam_try_fmt_meta()
1989 __unicam_try_fmt_meta(node, &f->fmt.meta); in unicam_try_fmt_meta()
1998 if (vb2_is_busy(&node->buffer_queue)) in unicam_s_fmt_meta()
1999 return -EBUSY; in unicam_s_fmt_meta()
2001 __unicam_try_fmt_meta(node, &f->fmt.meta); in unicam_s_fmt_meta()
2002 node->fmt = *f; in unicam_s_fmt_meta()
2011 int ret = -EINVAL; in unicam_enum_framesizes()
2013 if (fsize->index > 0) in unicam_enum_framesizes()
2017 if (!unicam_find_format_by_fourcc(fsize->pixel_format, in unicam_enum_framesizes()
2021 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in unicam_enum_framesizes()
2022 fsize->stepwise.min_width = UNICAM_IMAGE_MIN_WIDTH; in unicam_enum_framesizes()
2023 fsize->stepwise.max_width = UNICAM_IMAGE_MAX_WIDTH; in unicam_enum_framesizes()
2024 fsize->stepwise.step_width = 1; in unicam_enum_framesizes()
2025 fsize->stepwise.min_height = UNICAM_IMAGE_MIN_HEIGHT; in unicam_enum_framesizes()
2026 fsize->stepwise.max_height = UNICAM_IMAGE_MAX_HEIGHT; in unicam_enum_framesizes()
2027 fsize->stepwise.step_height = 1; in unicam_enum_framesizes()
2029 if (!unicam_find_format_by_fourcc(fsize->pixel_format, in unicam_enum_framesizes()
2033 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in unicam_enum_framesizes()
2034 fsize->stepwise.min_width = UNICAM_META_MIN_WIDTH; in unicam_enum_framesizes()
2035 fsize->stepwise.max_width = UNICAM_META_MAX_WIDTH; in unicam_enum_framesizes()
2036 fsize->stepwise.step_width = 1; in unicam_enum_framesizes()
2037 fsize->stepwise.min_height = UNICAM_META_MIN_HEIGHT; in unicam_enum_framesizes()
2038 fsize->stepwise.max_height = UNICAM_META_MAX_HEIGHT; in unicam_enum_framesizes()
2039 fsize->stepwise.step_height = 1; in unicam_enum_framesizes()
2048 struct unicam_device *unicam = node->dev; in unicam_log_status()
2052 v4l2_device_call_all(&unicam->v4l2_dev, 0, core, log_status); in unicam_log_status()
2054 dev_info(unicam->dev, "-----Receiver status-----\n"); in unicam_log_status()
2055 dev_info(unicam->dev, "V4L2 width/height: %ux%u\n", in unicam_log_status()
2056 node->fmt.fmt.pix.width, node->fmt.fmt.pix.height); in unicam_log_status()
2057 dev_info(unicam->dev, "V4L2 format: %08x\n", in unicam_log_status()
2058 node->fmt.fmt.pix.pixelformat); in unicam_log_status()
2060 dev_info(unicam->dev, "Unpacking/packing: %u / %u\n", in unicam_log_status()
2063 dev_info(unicam->dev, "----Live data----\n"); in unicam_log_status()
2064 dev_info(unicam->dev, "Programmed stride: %4u\n", in unicam_log_status()
2066 dev_info(unicam->dev, "Detected resolution: %ux%u\n", in unicam_log_status()
2069 dev_info(unicam->dev, "Write pointer: %08x\n", in unicam_log_status()
2078 switch (sub->type) { in unicam_subscribe_event()
2082 return -EINVAL; in unicam_subscribe_event()
2116 /* unicam capture driver file operations */
2129 media_entity_to_video_device(link->sink->entity); in unicam_video_link_validate()
2130 struct v4l2_subdev *sd = in unicam_video_link_validate() local
2131 media_entity_to_v4l2_subdev(link->source->entity); in unicam_video_link_validate()
2139 state = v4l2_subdev_lock_and_get_active_state(sd); in unicam_video_link_validate()
2143 ret = -EINVAL; in unicam_video_link_validate()
2148 const struct v4l2_pix_format *fmt = &node->fmt.fmt.pix; in unicam_video_link_validate()
2151 fmtinfo = unicam_find_format_by_fourcc(fmt->pixelformat, in unicam_video_link_validate()
2154 ret = -EPIPE; in unicam_video_link_validate()
2158 if (fmtinfo->code != format->code || in unicam_video_link_validate()
2159 fmt->height != format->height || in unicam_video_link_validate()
2160 fmt->width != format->width || in unicam_video_link_validate()
2161 fmt->field != format->field) { in unicam_video_link_validate()
2162 dev_dbg(node->dev->dev, in unicam_video_link_validate()
2164 fmt->width, fmt->height, fmtinfo->code, in unicam_video_link_validate()
2165 v4l2_field_names[fmt->field], in unicam_video_link_validate()
2166 format->width, format->height, format->code, in unicam_video_link_validate()
2167 v4l2_field_names[format->field]); in unicam_video_link_validate()
2168 ret = -EPIPE; in unicam_video_link_validate()
2171 const struct v4l2_meta_format *fmt = &node->fmt.fmt.meta; in unicam_video_link_validate()
2175 fmtinfo = unicam_find_format_by_fourcc(fmt->dataformat, in unicam_video_link_validate()
2178 ret = -EPIPE; in unicam_video_link_validate()
2182 if (fmtinfo->code != format->code || in unicam_video_link_validate()
2183 fmt->height != format->height || in unicam_video_link_validate()
2184 fmt->width != format->width) { in unicam_video_link_validate()
2185 dev_dbg(node->dev->dev, in unicam_video_link_validate()
2187 fmt->width, fmt->height, fmtinfo->code, in unicam_video_link_validate()
2188 format->width, format->height, format->code); in unicam_video_link_validate()
2189 ret = -EPIPE; in unicam_video_link_validate()
2206 unicam_put(node->dev); in unicam_node_release()
2212 struct v4l2_pix_format *fmt = &node->fmt.fmt.pix; in unicam_set_default_format()
2216 node->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in unicam_set_default_format()
2219 fmt->pixelformat = fmtinfo->fourcc; in unicam_set_default_format()
2220 unicam_calc_image_size_bpl(node->dev, fmtinfo, fmt); in unicam_set_default_format()
2222 struct v4l2_meta_format *fmt = &node->fmt.fmt.meta; in unicam_set_default_format()
2226 node->fmt.type = V4L2_BUF_TYPE_META_CAPTURE; in unicam_set_default_format()
2228 fmt->dataformat = fmtinfo->fourcc; in unicam_set_default_format()
2229 fmt->width = unicam_default_meta_format.width; in unicam_set_default_format()
2230 fmt->height = unicam_default_meta_format.height; in unicam_set_default_format()
2231 unicam_calc_meta_size_bpl(node->dev, fmtinfo, fmt); in unicam_set_default_format()
2241 struct unicam_node *node = &unicam->node[type]; in unicam_register_node()
2242 struct video_device *vdev = &node->video_dev; in unicam_register_node()
2243 struct vb2_queue *q = &node->buffer_queue; in unicam_register_node()
2246 node->dev = unicam_get(unicam); in unicam_register_node()
2247 node->id = type; in unicam_register_node()
2249 spin_lock_init(&node->dma_queue_lock); in unicam_register_node()
2251 INIT_LIST_HEAD(&node->dma_queue); in unicam_register_node()
2254 q->type = type == UNICAM_IMAGE_NODE ? V4L2_BUF_TYPE_VIDEO_CAPTURE in unicam_register_node()
2256 q->io_modes = VB2_MMAP | VB2_DMABUF; in unicam_register_node()
2257 q->drv_priv = node; in unicam_register_node()
2258 q->ops = &unicam_video_qops; in unicam_register_node()
2259 q->mem_ops = &vb2_dma_contig_memops; in unicam_register_node()
2260 q->buf_struct_size = sizeof(struct unicam_buffer); in unicam_register_node()
2261 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in unicam_register_node()
2262 q->lock = &unicam->lock; in unicam_register_node()
2263 q->min_queued_buffers = 1; in unicam_register_node()
2264 q->dev = unicam->dev; in unicam_register_node()
2268 dev_err(unicam->dev, "vb2_queue_init() failed\n"); in unicam_register_node()
2273 vdev->release = unicam_node_release; in unicam_register_node()
2274 vdev->fops = &unicam_fops; in unicam_register_node()
2275 vdev->ioctl_ops = &unicam_ioctl_ops; in unicam_register_node()
2276 vdev->v4l2_dev = &unicam->v4l2_dev; in unicam_register_node()
2277 vdev->vfl_dir = VFL_DIR_RX; in unicam_register_node()
2278 vdev->queue = q; in unicam_register_node()
2279 vdev->lock = &unicam->lock; in unicam_register_node()
2280 vdev->device_caps = type == UNICAM_IMAGE_NODE in unicam_register_node()
2282 vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_IO_MC; in unicam_register_node()
2283 vdev->entity.ops = &unicam_video_media_ops; in unicam_register_node()
2285 snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, in unicam_register_node()
2291 vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; in unicam_register_node()
2293 node->pad.flags = MEDIA_PAD_FL_SINK; in unicam_register_node()
2295 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad); in unicam_register_node()
2299 node->dummy_buf.size = UNICAM_DUMMY_BUF_SIZE; in unicam_register_node()
2300 node->dummy_buf_cpu_addr = dma_alloc_coherent(unicam->dev, in unicam_register_node()
2301 node->dummy_buf.size, in unicam_register_node()
2302 &node->dummy_buf.dma_addr, in unicam_register_node()
2304 if (!node->dummy_buf_cpu_addr) { in unicam_register_node()
2305 dev_err(unicam->dev, "Unable to allocate dummy buffer.\n"); in unicam_register_node()
2306 ret = -ENOMEM; in unicam_register_node()
2312 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in unicam_register_node()
2314 dev_err(unicam->dev, "Unable to register video device %s\n", in unicam_register_node()
2315 vdev->name); in unicam_register_node()
2319 node->registered = true; in unicam_register_node()
2321 ret = media_create_pad_link(&unicam->subdev.sd.entity, in unicam_register_node()
2323 &node->video_dev.entity, in unicam_register_node()
2333 dev_err(unicam->dev, "Unable to create pad link for %s\n", in unicam_register_node()
2334 unicam->sensor.subdev->name); in unicam_register_node()
2341 dma_free_coherent(unicam->dev, node->dummy_buf.size, in unicam_register_node()
2342 node->dummy_buf_cpu_addr, in unicam_register_node()
2343 node->dummy_buf.dma_addr); in unicam_register_node()
2345 media_entity_cleanup(&vdev->entity); in unicam_register_node()
2355 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_unregister_nodes()
2356 struct unicam_node *node = &unicam->node[i]; in unicam_unregister_nodes()
2358 if (node->registered) { in unicam_unregister_nodes()
2359 vb2_video_unregister_device(&node->video_dev); in unicam_unregister_nodes()
2360 node->registered = false; in unicam_unregister_nodes()
2363 if (node->dummy_buf_cpu_addr) in unicam_unregister_nodes()
2364 dma_free_coherent(unicam->dev, node->dummy_buf.size, in unicam_unregister_nodes()
2365 node->dummy_buf_cpu_addr, in unicam_unregister_nodes()
2366 node->dummy_buf.dma_addr); in unicam_unregister_nodes()
2370 /* -----------------------------------------------------------------------------
2379 ret = clk_set_min_rate(unicam->vpu_clock, UNICAM_MIN_VPU_CLOCK_RATE); in unicam_runtime_resume()
2381 dev_err(unicam->dev, "failed to set up VPU clock\n"); in unicam_runtime_resume()
2385 ret = clk_prepare_enable(unicam->vpu_clock); in unicam_runtime_resume()
2387 dev_err(unicam->dev, "Failed to enable VPU clock: %d\n", ret); in unicam_runtime_resume()
2391 ret = clk_set_rate(unicam->clock, 100 * 1000 * 1000); in unicam_runtime_resume()
2393 dev_err(unicam->dev, "failed to set up CSI clock\n"); in unicam_runtime_resume()
2397 ret = clk_prepare_enable(unicam->clock); in unicam_runtime_resume()
2399 dev_err(unicam->dev, "Failed to enable CSI clock: %d\n", ret); in unicam_runtime_resume()
2406 clk_disable_unprepare(unicam->vpu_clock); in unicam_runtime_resume()
2408 if (clk_set_min_rate(unicam->vpu_clock, 0)) in unicam_runtime_resume()
2409 dev_err(unicam->dev, "failed to reset the VPU clock\n"); in unicam_runtime_resume()
2418 clk_disable_unprepare(unicam->clock); in unicam_runtime_suspend()
2420 if (clk_set_min_rate(unicam->vpu_clock, 0)) in unicam_runtime_suspend()
2421 dev_err(unicam->dev, "failed to reset the VPU clock\n"); in unicam_runtime_suspend()
2423 clk_disable_unprepare(unicam->vpu_clock); in unicam_runtime_suspend()
2432 /* -----------------------------------------------------------------------------
2441 struct media_pad *sink = &unicam->subdev.pads[UNICAM_SD_PAD_SINK]; in unicam_async_bound()
2445 dev_dbg(unicam->dev, "Using sensor %s for capture\n", in unicam_async_bound()
2446 subdev->name); in unicam_async_bound()
2455 dev_err(unicam->dev, "No connected sensor pad\n"); in unicam_async_bound()
2459 unicam->sensor.subdev = subdev; in unicam_async_bound()
2460 unicam->sensor.pad = source; in unicam_async_bound()
2472 dev_err(unicam->dev, "Unable to register image video device.\n"); in unicam_async_complete()
2478 dev_err(unicam->dev, "Unable to register metadata video device.\n"); in unicam_async_complete()
2482 ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev); in unicam_async_complete()
2484 dev_err(unicam->dev, "Unable to register subdev nodes.\n"); in unicam_async_complete()
2509 ret = of_property_read_u32(unicam->dev->of_node, "brcm,num-data-lanes", in unicam_async_nf_init()
2510 &unicam->max_data_lanes); in unicam_async_nf_init()
2512 dev_err(unicam->dev, "Missing %s DT property\n", in unicam_async_nf_init()
2513 "brcm,num-data-lanes"); in unicam_async_nf_init()
2514 return -EINVAL; in unicam_async_nf_init()
2518 ep_handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(unicam->dev), 0, 0, in unicam_async_nf_init()
2521 dev_err(unicam->dev, "No endpoint found\n"); in unicam_async_nf_init()
2522 return -ENODEV; in unicam_async_nf_init()
2527 dev_err(unicam->dev, "Failed to parse endpoint: %d\n", ret); in unicam_async_nf_init()
2531 unicam->bus_type = ep.bus_type; in unicam_async_nf_init()
2539 dev_err(unicam->dev, "%u data lanes not supported\n", in unicam_async_nf_init()
2541 ret = -EINVAL; in unicam_async_nf_init()
2545 if (num_data_lanes > unicam->max_data_lanes) { in unicam_async_nf_init()
2546 dev_err(unicam->dev, in unicam_async_nf_init()
2548 num_data_lanes, unicam->max_data_lanes); in unicam_async_nf_init()
2549 ret = -EINVAL; in unicam_async_nf_init()
2553 unicam->max_data_lanes = num_data_lanes; in unicam_async_nf_init()
2554 unicam->bus_flags = ep.bus.mipi_csi2.flags; in unicam_async_nf_init()
2559 unicam->max_data_lanes = 1; in unicam_async_nf_init()
2560 unicam->bus_flags = ep.bus.mipi_csi1.strobe; in unicam_async_nf_init()
2565 dev_err(unicam->dev, "Unsupported bus type %u\n", ep.bus_type); in unicam_async_nf_init()
2566 ret = -EINVAL; in unicam_async_nf_init()
2571 v4l2_async_nf_init(&unicam->notifier, &unicam->v4l2_dev); in unicam_async_nf_init()
2573 asc = v4l2_async_nf_add_fwnode_remote(&unicam->notifier, ep_handle, in unicam_async_nf_init()
2580 dev_err(unicam->dev, "Failed to add entry to notifier: %d\n", in unicam_async_nf_init()
2585 unicam->notifier.ops = &unicam_async_ops; in unicam_async_nf_init()
2587 ret = v4l2_async_nf_register(&unicam->notifier); in unicam_async_nf_init()
2589 dev_err(unicam->dev, "Error registering device notifier: %d\n", in unicam_async_nf_init()
2601 /* -----------------------------------------------------------------------------
2609 unicam->mdev.dev = unicam->dev; in unicam_media_init()
2610 strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, in unicam_media_init()
2611 sizeof(unicam->mdev.model)); in unicam_media_init()
2612 unicam->mdev.hw_revision = 0; in unicam_media_init()
2614 media_device_init(&unicam->mdev); in unicam_media_init()
2616 unicam->v4l2_dev.mdev = &unicam->mdev; in unicam_media_init()
2618 ret = v4l2_device_register(unicam->dev, &unicam->v4l2_dev); in unicam_media_init()
2620 dev_err(unicam->dev, "Unable to register v4l2 device\n"); in unicam_media_init()
2624 ret = media_device_register(&unicam->mdev); in unicam_media_init()
2626 dev_err(unicam->dev, in unicam_media_init()
2627 "Unable to register media-controller device\n"); in unicam_media_init()
2634 v4l2_device_unregister(&unicam->v4l2_dev); in unicam_media_init()
2636 media_device_cleanup(&unicam->mdev); in unicam_media_init()
2647 return -ENOMEM; in unicam_probe()
2649 kref_init(&unicam->kref); in unicam_probe()
2650 mutex_init(&unicam->lock); in unicam_probe()
2652 unicam->dev = &pdev->dev; in unicam_probe()
2655 unicam->base = devm_platform_ioremap_resource_byname(pdev, "unicam"); in unicam_probe()
2656 if (IS_ERR(unicam->base)) { in unicam_probe()
2657 ret = PTR_ERR(unicam->base); in unicam_probe()
2661 unicam->clk_gate_base = devm_platform_ioremap_resource_byname(pdev, "cmi"); in unicam_probe()
2662 if (IS_ERR(unicam->clk_gate_base)) { in unicam_probe()
2663 ret = PTR_ERR(unicam->clk_gate_base); in unicam_probe()
2667 unicam->clock = devm_clk_get(&pdev->dev, "lp"); in unicam_probe()
2668 if (IS_ERR(unicam->clock)) { in unicam_probe()
2669 dev_err(unicam->dev, "Failed to get lp clock\n"); in unicam_probe()
2670 ret = PTR_ERR(unicam->clock); in unicam_probe()
2674 unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu"); in unicam_probe()
2675 if (IS_ERR(unicam->vpu_clock)) { in unicam_probe()
2676 dev_err(unicam->dev, "Failed to get vpu clock\n"); in unicam_probe()
2677 ret = PTR_ERR(unicam->vpu_clock); in unicam_probe()
2685 ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, in unicam_probe()
2688 dev_err(&pdev->dev, "Unable to request interrupt\n"); in unicam_probe()
2693 pm_runtime_enable(&pdev->dev); in unicam_probe()
2712 media_device_unregister(&unicam->mdev); in unicam_probe()
2714 pm_runtime_disable(&pdev->dev); in unicam_probe()
2726 v4l2_device_unregister(&unicam->v4l2_dev); in unicam_remove()
2727 media_device_unregister(&unicam->mdev); in unicam_remove()
2728 v4l2_async_nf_unregister(&unicam->notifier); in unicam_remove()
2734 pm_runtime_disable(&pdev->dev); in unicam_remove()
2738 { .compatible = "brcm,bcm2835-unicam", },