Lines Matching +full:bcm2835 +full:- +full:pm

1 // SPDX-License-Identifier: GPL-2.0-only
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 */
252 if (unicam->mdev.dev) in unicam_release()
253 media_device_cleanup(&unicam->mdev); in unicam_release()
255 mutex_destroy(&unicam->lock); in unicam_release()
261 kref_get(&unicam->kref); in unicam_get()
268 kref_put(&unicam->kref, unicam_release); in unicam_put()
271 /* -----------------------------------------------------------------------------
283 return node->video_dev.device_caps & V4L2_CAP_META_CAPTURE; in is_metadata_node()
288 return node->video_dev.device_caps & V4L2_CAP_VIDEO_CAPTURE; in is_image_node()
291 /* -----------------------------------------------------------------------------
562 v4l_bound_align_image(&pix->width, UNICAM_IMAGE_MIN_WIDTH, in unicam_calc_image_size_bpl()
564 &pix->height, UNICAM_IMAGE_MIN_HEIGHT, in unicam_calc_image_size_bpl()
568 if (pix->pixelformat == fmtinfo->unpacked_fourcc) in unicam_calc_image_size_bpl()
569 min_bpl = pix->width * 2; in unicam_calc_image_size_bpl()
571 min_bpl = pix->width * fmtinfo->depth / 8; in unicam_calc_image_size_bpl()
574 pix->bytesperline = ALIGN(pix->bytesperline, UNICAM_IMAGE_BPL_ALIGNMENT); in unicam_calc_image_size_bpl()
575 pix->bytesperline = clamp_t(unsigned int, pix->bytesperline, min_bpl, in unicam_calc_image_size_bpl()
578 pix->sizeimage = pix->height * pix->bytesperline; in unicam_calc_image_size_bpl()
585 v4l_bound_align_image(&meta->width, UNICAM_META_MIN_WIDTH, in unicam_calc_meta_size_bpl()
587 &meta->height, UNICAM_META_MIN_HEIGHT, in unicam_calc_meta_size_bpl()
590 meta->bytesperline = ALIGN(meta->width * fmtinfo->depth / 8, in unicam_calc_meta_size_bpl()
592 meta->buffersize = meta->height * meta->bytesperline; in unicam_calc_meta_size_bpl()
595 /* -----------------------------------------------------------------------------
602 writel(val | 0x5a000000, unicam->clk_gate_base); in unicam_clk_write()
607 return readl(unicam->base + offset); in unicam_reg_read()
612 writel(val, unicam->base + offset); in unicam_reg_write()
641 dma_addr_t endaddr = buf->dma_addr + buf->size; in unicam_wr_dma_addr()
643 if (node->id == UNICAM_IMAGE_NODE) { in unicam_wr_dma_addr()
644 unicam_reg_write(node->dev, UNICAM_IBSA0, buf->dma_addr); in unicam_wr_dma_addr()
645 unicam_reg_write(node->dev, UNICAM_IBEA0, endaddr); in unicam_wr_dma_addr()
647 unicam_reg_write(node->dev, UNICAM_DBSA0, buf->dma_addr); in unicam_wr_dma_addr()
648 unicam_reg_write(node->dev, UNICAM_DBEA0, endaddr); in unicam_wr_dma_addr()
654 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_get_lines_done()
655 unsigned int stride = node->fmt.fmt.pix.bytesperline; in unicam_get_lines_done()
656 struct unicam_buffer *frm = node->cur_frm; in unicam_get_lines_done()
663 return (unsigned int)(cur_addr - frm->dma_addr) / stride; in unicam_get_lines_done()
670 buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); in unicam_schedule_next_buffer()
671 node->next_frm = buf; in unicam_schedule_next_buffer()
672 list_del(&buf->list); in unicam_schedule_next_buffer()
681 dev_dbg(node->dev->dev, "Scheduling dummy buffer for node %d\n", node_id); in unicam_schedule_dummy_buffer()
683 unicam_wr_dma_addr(node, &node->dummy_buf); in unicam_schedule_dummy_buffer()
685 node->next_frm = NULL; in unicam_schedule_dummy_buffer()
691 node->cur_frm->vb.field = node->fmt.fmt.pix.field; in unicam_process_buffer_complete()
692 node->cur_frm->vb.sequence = sequence; in unicam_process_buffer_complete()
694 vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); in unicam_process_buffer_complete()
699 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_queue_event_sof()
702 .u.frame_sync.frame_sequence = unicam->sequence, in unicam_queue_event_sof()
705 v4l2_event_queue(&node->video_dev, &event); in unicam_queue_event_sof()
712 unsigned int sequence = unicam->sequence; in unicam_isr()
726 dev_dbg(unicam->dev, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d\n", in unicam_isr()
751 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_isr()
752 struct unicam_node *node = &unicam->node[i]; in unicam_isr()
754 if (!vb2_start_streaming_called(&node->buffer_queue)) in unicam_isr()
764 if (node->cur_frm && node->cur_frm != node->next_frm) in unicam_isr()
766 node->cur_frm = node->next_frm; in unicam_isr()
768 unicam->sequence++; in unicam_isr()
777 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_isr()
778 struct unicam_node *node = &unicam->node[i]; in unicam_isr()
780 if (!vb2_start_streaming_called(&node->buffer_queue)) in unicam_isr()
783 if (node->cur_frm) in unicam_isr()
784 node->cur_frm->vb.vb2_buf.timestamp = ts; in unicam_isr()
786 dev_dbg(unicam->v4l2_dev.dev, in unicam_isr()
806 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_isr()
807 struct unicam_node *node = &unicam->node[i]; in unicam_isr()
809 if (!vb2_start_streaming_called(&node->buffer_queue)) in unicam_isr()
812 spin_lock(&node->dma_queue_lock); in unicam_isr()
813 if (!list_empty(&node->dma_queue) && !node->next_frm) in unicam_isr()
815 spin_unlock(&node->dma_queue_lock); in unicam_isr()
830 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_set_packing_config()
834 if (node->fmt.fmt.pix.pixelformat == fmtinfo->fourcc) { in unicam_set_packing_config()
838 unpack = fmtinfo->unpack; in unicam_set_packing_config()
851 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_cfg_image_id()
879 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, in unicam_get_image_vc_dt()
885 ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_frame_desc, in unicam_get_image_vc_dt()
886 unicam->sensor.pad->index, &fd); in unicam_get_image_vc_dt()
890 /* Only CSI-2 supports DTs. */ in unicam_get_image_vc_dt()
892 return -EINVAL; in unicam_get_image_vc_dt()
897 if (fde->stream == stream) { in unicam_get_image_vc_dt()
898 *vc = fde->bus.csi2.vc; in unicam_get_image_vc_dt()
899 *dt = fde->bus.csi2.dt; in unicam_get_image_vc_dt()
904 return -EINVAL; in unicam_get_image_vc_dt()
910 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_start_rx()
919 fmtinfo = unicam_find_format_by_code(fmt->code, in unicam_start_rx()
927 * [9:8] - DAT3 in unicam_start_rx()
928 * [7:6] - DAT2 in unicam_start_rx()
929 * [5:4] - DAT1 in unicam_start_rx()
930 * [3:2] - DAT0 in unicam_start_rx()
931 * [1:0] - CLK in unicam_start_rx()
936 val = 0x155 & GENMASK(unicam->pipe.num_data_lanes * 2 + 1, 0); in unicam_start_rx()
960 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_start_rx()
965 unicam_set_field(&val, unicam->bus_flags, UNICAM_DCM_MASK); in unicam_start_rx()
989 line_int_freq = max(fmt->height >> 2, 128); in unicam_start_rx()
1008 /* Packet compare setup - required to avoid missing frame ends */ in unicam_start_rx()
1019 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_start_rx()
1023 if (!(unicam->bus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) { in unicam_start_rx()
1041 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_start_rx()
1045 if (!(unicam->bus_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) { in unicam_start_rx()
1057 if (unicam->pipe.num_data_lanes == 1) in unicam_start_rx()
1061 if (unicam->max_data_lanes > 2) { in unicam_start_rx()
1066 if (unicam->pipe.num_data_lanes == 2) in unicam_start_rx()
1070 if (unicam->pipe.num_data_lanes == 3) in unicam_start_rx()
1076 node->fmt.fmt.pix.bytesperline); in unicam_start_rx()
1077 unicam_wr_dma_addr(node, node->cur_frm); in unicam_start_rx()
1087 dt = fmtinfo->csi_dt; in unicam_start_rx()
1112 struct unicam_node *node = &unicam->node[UNICAM_METADATA_NODE]; in unicam_start_metadata()
1115 unicam_wr_dma_addr(node, node->cur_frm); in unicam_start_metadata()
1131 if (unicam->max_data_lanes > 2) { in unicam_disable()
1151 /* -----------------------------------------------------------------------------
1171 for_each_active_route(&state->routing, route) { in __unicam_subdev_set_routing()
1175 if (route->source_pad == UNICAM_SD_PAD_SOURCE_IMAGE) in __unicam_subdev_set_routing()
1180 fmt = v4l2_subdev_state_get_format(state, route->sink_pad, in __unicam_subdev_set_routing()
1181 route->sink_stream); in __unicam_subdev_set_routing()
1183 fmt = v4l2_subdev_state_get_format(state, route->source_pad, in __unicam_subdev_set_routing()
1184 route->source_stream); in __unicam_subdev_set_routing()
1221 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, in unicam_subdev_enum_mbus_code()
1222 code->pad, code->stream, in unicam_subdev_enum_mbus_code()
1227 if (unicam_sd_pad_is_source(code->pad)) { in unicam_subdev_enum_mbus_code()
1233 return -EINVAL; in unicam_subdev_enum_mbus_code()
1235 if (code->index > 0) in unicam_subdev_enum_mbus_code()
1236 return -EINVAL; in unicam_subdev_enum_mbus_code()
1238 code->code = fmt->code; in unicam_subdev_enum_mbus_code()
1251 if (code->index >= num_formats) in unicam_subdev_enum_mbus_code()
1252 return -EINVAL; in unicam_subdev_enum_mbus_code()
1254 code->code = formats[code->index].code; in unicam_subdev_enum_mbus_code()
1267 if (fse->index > 0) in unicam_subdev_enum_frame_size()
1268 return -EINVAL; in unicam_subdev_enum_frame_size()
1270 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, fse->pad, in unicam_subdev_enum_frame_size()
1271 fse->stream, &pad, in unicam_subdev_enum_frame_size()
1276 if (unicam_sd_pad_is_source(fse->pad)) { in unicam_subdev_enum_frame_size()
1282 return -EINVAL; in unicam_subdev_enum_frame_size()
1284 if (fse->code != fmt->code) in unicam_subdev_enum_frame_size()
1285 return -EINVAL; in unicam_subdev_enum_frame_size()
1287 fse->min_width = fmt->width; in unicam_subdev_enum_frame_size()
1288 fse->max_width = fmt->width; in unicam_subdev_enum_frame_size()
1289 fse->min_height = fmt->height; in unicam_subdev_enum_frame_size()
1290 fse->max_height = fmt->height; in unicam_subdev_enum_frame_size()
1294 fmtinfo = unicam_find_format_by_code(fse->code, pad); in unicam_subdev_enum_frame_size()
1296 return -EINVAL; in unicam_subdev_enum_frame_size()
1299 fse->min_width = UNICAM_IMAGE_MIN_WIDTH; in unicam_subdev_enum_frame_size()
1300 fse->max_width = UNICAM_IMAGE_MAX_WIDTH; in unicam_subdev_enum_frame_size()
1301 fse->min_height = UNICAM_IMAGE_MIN_HEIGHT; in unicam_subdev_enum_frame_size()
1302 fse->max_height = UNICAM_IMAGE_MAX_HEIGHT; in unicam_subdev_enum_frame_size()
1304 fse->min_width = UNICAM_META_MIN_WIDTH; in unicam_subdev_enum_frame_size()
1305 fse->max_width = UNICAM_META_MAX_WIDTH; in unicam_subdev_enum_frame_size()
1306 fse->min_height = UNICAM_META_MIN_HEIGHT; in unicam_subdev_enum_frame_size()
1307 fse->max_height = UNICAM_META_MAX_HEIGHT; in unicam_subdev_enum_frame_size()
1324 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && in unicam_subdev_set_format()
1325 unicam->subdev.enabled_streams) in unicam_subdev_set_format()
1326 return -EBUSY; in unicam_subdev_set_format()
1329 if (unicam_sd_pad_is_source(format->pad)) in unicam_subdev_set_format()
1337 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, in unicam_subdev_set_format()
1338 format->pad, format->stream, in unicam_subdev_set_format()
1343 fmtinfo = unicam_find_format_by_code(format->format.code, source_pad); in unicam_subdev_set_format()
1347 format->format.code = fmtinfo->code; in unicam_subdev_set_format()
1351 format->format.width = clamp_t(unsigned int, in unicam_subdev_set_format()
1352 format->format.width, in unicam_subdev_set_format()
1355 format->format.height = clamp_t(unsigned int, in unicam_subdev_set_format()
1356 format->format.height, in unicam_subdev_set_format()
1359 format->format.field = V4L2_FIELD_NONE; in unicam_subdev_set_format()
1361 format->format.width = clamp_t(unsigned int, in unicam_subdev_set_format()
1362 format->format.width, in unicam_subdev_set_format()
1365 format->format.height = clamp_t(unsigned int, in unicam_subdev_set_format()
1366 format->format.height, in unicam_subdev_set_format()
1369 format->format.field = V4L2_FIELD_NONE; in unicam_subdev_set_format()
1372 format->format.colorspace = 0; in unicam_subdev_set_format()
1373 format->format.ycbcr_enc = 0; in unicam_subdev_set_format()
1374 format->format.quantization = 0; in unicam_subdev_set_format()
1375 format->format.xfer_func = 0; in unicam_subdev_set_format()
1378 sink_format = v4l2_subdev_state_get_format(state, format->pad, in unicam_subdev_set_format()
1379 format->stream); in unicam_subdev_set_format()
1382 *sink_format = format->format; in unicam_subdev_set_format()
1383 *source_format = format->format; in unicam_subdev_set_format()
1395 if (which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->subdev.enabled_streams) in unicam_subdev_set_routing()
1396 return -EBUSY; in unicam_subdev_set_routing()
1409 if (!unicam->subdev.enabled_streams) { in unicam_sd_enable_streams()
1411 unicam->sequence = 0; in unicam_sd_enable_streams()
1413 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) in unicam_sd_enable_streams()
1419 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0, in unicam_sd_enable_streams()
1424 ret = v4l2_subdev_enable_streams(unicam->sensor.subdev, in unicam_sd_enable_streams()
1425 unicam->sensor.pad->index, in unicam_sd_enable_streams()
1428 dev_err(unicam->dev, "stream on failed in subdev\n"); in unicam_sd_enable_streams()
1432 unicam->subdev.enabled_streams |= BIT(other_stream); in unicam_sd_enable_streams()
1445 ret = v4l2_subdev_routing_find_opposite_end(&state->routing, pad, 0, in unicam_sd_disable_streams()
1450 v4l2_subdev_disable_streams(unicam->sensor.subdev, in unicam_sd_disable_streams()
1451 unicam->sensor.pad->index, in unicam_sd_disable_streams()
1454 unicam->subdev.enabled_streams &= ~BIT(other_stream); in unicam_sd_disable_streams()
1456 if (!unicam->subdev.enabled_streams) in unicam_sd_disable_streams()
1487 struct v4l2_subdev *sd = &unicam->subdev.sd; in unicam_subdev_init()
1491 sd->internal_ops = &unicam_subdev_internal_ops; in unicam_subdev_init()
1494 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in unicam_subdev_init()
1495 sd->entity.ops = &unicam_subdev_media_ops; in unicam_subdev_init()
1496 sd->dev = unicam->dev; in unicam_subdev_init()
1497 sd->owner = THIS_MODULE; in unicam_subdev_init()
1498 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; in unicam_subdev_init()
1500 strscpy(sd->name, "unicam", sizeof(sd->name)); in unicam_subdev_init()
1502 unicam->subdev.pads[UNICAM_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in unicam_subdev_init()
1503 unicam->subdev.pads[UNICAM_SD_PAD_SOURCE_IMAGE].flags = MEDIA_PAD_FL_SOURCE; in unicam_subdev_init()
1504 unicam->subdev.pads[UNICAM_SD_PAD_SOURCE_METADATA].flags = MEDIA_PAD_FL_SOURCE; in unicam_subdev_init()
1506 ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(unicam->subdev.pads), in unicam_subdev_init()
1507 unicam->subdev.pads); in unicam_subdev_init()
1509 dev_err(unicam->dev, "Failed to initialize media entity: %d\n", in unicam_subdev_init()
1516 dev_err(unicam->dev, "Failed to initialize subdev: %d\n", ret); in unicam_subdev_init()
1520 ret = v4l2_device_register_subdev(&unicam->v4l2_dev, sd); in unicam_subdev_init()
1522 dev_err(unicam->dev, "Failed to register subdev: %d\n", ret); in unicam_subdev_init()
1531 media_entity_cleanup(&sd->entity); in unicam_subdev_init()
1537 v4l2_subdev_cleanup(&unicam->subdev.sd); in unicam_subdev_cleanup()
1538 media_entity_cleanup(&unicam->subdev.sd.entity); in unicam_subdev_cleanup()
1541 /* -----------------------------------------------------------------------------
1550 u32 size = is_image_node(node) ? node->fmt.fmt.pix.sizeimage in unicam_queue_setup()
1551 : node->fmt.fmt.meta.buffersize; in unicam_queue_setup()
1555 dev_dbg(node->dev->dev, "sizes[0] %i < size %u\n", in unicam_queue_setup()
1557 return -EINVAL; in unicam_queue_setup()
1570 struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); in unicam_buffer_prepare()
1572 u32 size = is_image_node(node) ? node->fmt.fmt.pix.sizeimage in unicam_buffer_prepare()
1573 : node->fmt.fmt.meta.buffersize; in unicam_buffer_prepare()
1576 dev_dbg(node->dev->dev, in unicam_buffer_prepare()
1579 return -EINVAL; in unicam_buffer_prepare()
1582 buf->dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); in unicam_buffer_prepare()
1583 buf->size = size; in unicam_buffer_prepare()
1585 vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); in unicam_buffer_prepare()
1595 list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) { in unicam_return_buffers()
1596 list_del(&buf->list); in unicam_return_buffers()
1597 vb2_buffer_done(&buf->vb.vb2_buf, state); in unicam_return_buffers()
1600 if (node->cur_frm) in unicam_return_buffers()
1601 vb2_buffer_done(&node->cur_frm->vb.vb2_buf, in unicam_return_buffers()
1603 if (node->next_frm && node->cur_frm != node->next_frm) in unicam_return_buffers()
1604 vb2_buffer_done(&node->next_frm->vb.vb2_buf, in unicam_return_buffers()
1607 node->cur_frm = NULL; in unicam_return_buffers()
1608 node->next_frm = NULL; in unicam_return_buffers()
1617 if (unicam->bus_type != V4L2_MBUS_CSI2_DPHY) in unicam_num_data_lanes()
1618 return unicam->max_data_lanes; in unicam_num_data_lanes()
1620 ret = v4l2_subdev_call(unicam->sensor.subdev, pad, get_mbus_config, in unicam_num_data_lanes()
1621 unicam->sensor.pad->index, &mbus_config); in unicam_num_data_lanes()
1622 if (ret == -ENOIOCTLCMD) in unicam_num_data_lanes()
1623 return unicam->max_data_lanes; in unicam_num_data_lanes()
1626 dev_err(unicam->dev, "Failed to get mbus config: %d\n", ret); in unicam_num_data_lanes()
1633 dev_err(unicam->dev, in unicam_num_data_lanes()
1635 unicam->sensor.subdev->name, num_data_lanes); in unicam_num_data_lanes()
1636 return -EINVAL; in unicam_num_data_lanes()
1639 if (num_data_lanes > unicam->max_data_lanes) { in unicam_num_data_lanes()
1640 dev_err(unicam->dev, in unicam_num_data_lanes()
1642 unicam->sensor.subdev->name, num_data_lanes, in unicam_num_data_lanes()
1643 unicam->max_data_lanes); in unicam_num_data_lanes()
1644 return -EINVAL; in unicam_num_data_lanes()
1653 struct unicam_device *unicam = node->dev; in unicam_start_streaming()
1660 dev_dbg(unicam->dev, "Starting stream on %s device\n", in unicam_start_streaming()
1667 ret = video_device_pipeline_start(&node->video_dev, &unicam->pipe.pipe); in unicam_start_streaming()
1669 dev_dbg(unicam->dev, "Failed to start media pipeline: %d\n", ret); in unicam_start_streaming()
1677 if (unicam->pipe.pipe.start_count == 1) { in unicam_start_streaming()
1678 unicam->pipe.nodes = 0; in unicam_start_streaming()
1680 media_pipeline_for_each_pad(&unicam->pipe.pipe, &iter, pad) { in unicam_start_streaming()
1681 if (pad->entity != &unicam->subdev.sd.entity) in unicam_start_streaming()
1684 if (pad->index == UNICAM_SD_PAD_SOURCE_IMAGE) in unicam_start_streaming()
1685 unicam->pipe.nodes |= BIT(UNICAM_IMAGE_NODE); in unicam_start_streaming()
1686 else if (pad->index == UNICAM_SD_PAD_SOURCE_METADATA) in unicam_start_streaming()
1687 unicam->pipe.nodes |= BIT(UNICAM_METADATA_NODE); in unicam_start_streaming()
1690 if (!(unicam->pipe.nodes & BIT(UNICAM_IMAGE_NODE))) { in unicam_start_streaming()
1691 dev_dbg(unicam->dev, in unicam_start_streaming()
1693 ret = -EPIPE; in unicam_start_streaming()
1701 unicam->pipe.num_data_lanes = ret; in unicam_start_streaming()
1703 dev_dbg(unicam->dev, "Running with %u data lanes, nodes %u\n", in unicam_start_streaming()
1704 unicam->pipe.num_data_lanes, unicam->pipe.nodes); in unicam_start_streaming()
1708 spin_lock_irqsave(&node->dma_queue_lock, flags); in unicam_start_streaming()
1709 buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list); in unicam_start_streaming()
1710 node->cur_frm = buf; in unicam_start_streaming()
1711 node->next_frm = buf; in unicam_start_streaming()
1712 list_del(&buf->list); in unicam_start_streaming()
1713 spin_unlock_irqrestore(&node->dma_queue_lock, flags); in unicam_start_streaming()
1725 if (unicam->pipe.pipe.start_count < hweight32(unicam->pipe.nodes)) in unicam_start_streaming()
1728 ret = pm_runtime_resume_and_get(unicam->dev); in unicam_start_streaming()
1730 dev_err(unicam->dev, "PM runtime resume failed: %d\n", ret); in unicam_start_streaming()
1735 ret = v4l2_subdev_enable_streams(&unicam->subdev.sd, in unicam_start_streaming()
1739 dev_err(unicam->dev, "stream on failed in subdev\n"); in unicam_start_streaming()
1743 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) { in unicam_start_streaming()
1744 ret = v4l2_subdev_enable_streams(&unicam->subdev.sd, in unicam_start_streaming()
1748 dev_err(unicam->dev, "stream on failed in subdev\n"); in unicam_start_streaming()
1756 v4l2_subdev_disable_streams(&unicam->subdev.sd, in unicam_start_streaming()
1759 pm_runtime_put_sync(unicam->dev); in unicam_start_streaming()
1761 video_device_pipeline_stop(&node->video_dev); in unicam_start_streaming()
1770 struct unicam_device *unicam = node->dev; in unicam_stop_streaming()
1773 if (unicam->pipe.pipe.start_count == hweight32(unicam->pipe.nodes)) { in unicam_stop_streaming()
1774 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) in unicam_stop_streaming()
1775 v4l2_subdev_disable_streams(&unicam->subdev.sd, in unicam_stop_streaming()
1779 v4l2_subdev_disable_streams(&unicam->subdev.sd, in unicam_stop_streaming()
1783 pm_runtime_put(unicam->dev); in unicam_stop_streaming()
1786 video_device_pipeline_stop(&node->video_dev); in unicam_stop_streaming()
1794 struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); in unicam_buffer_queue()
1797 spin_lock_irq(&node->dma_queue_lock); in unicam_buffer_queue()
1798 list_add_tail(&buf->list, &node->dma_queue); in unicam_buffer_queue()
1799 spin_unlock_irq(&node->dma_queue_lock); in unicam_buffer_queue()
1812 /* -----------------------------------------------------------------------------
1819 strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); in unicam_querycap()
1820 strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); in unicam_querycap()
1822 cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE; in unicam_querycap()
1834 if (f->mbus_code && unicam_image_formats[i].code != f->mbus_code) in unicam_enum_fmt_vid()
1837 if (index == f->index) { in unicam_enum_fmt_vid()
1838 f->pixelformat = unicam_image_formats[i].fourcc; in unicam_enum_fmt_vid()
1847 if (index == f->index) { in unicam_enum_fmt_vid()
1848 f->pixelformat = unicam_image_formats[i].unpacked_fourcc; in unicam_enum_fmt_vid()
1855 return -EINVAL; in unicam_enum_fmt_vid()
1863 *f = node->fmt; in unicam_g_fmt_vid()
1877 fmtinfo = unicam_find_format_by_fourcc(pix->pixelformat, in __unicam_try_fmt_vid()
1881 pix->pixelformat = fmtinfo->fourcc; in __unicam_try_fmt_vid()
1884 unicam_calc_image_size_bpl(node->dev, fmtinfo, pix); in __unicam_try_fmt_vid()
1886 if (pix->field == V4L2_FIELD_ANY) in __unicam_try_fmt_vid()
1887 pix->field = V4L2_FIELD_NONE; in __unicam_try_fmt_vid()
1895 __unicam_try_fmt_vid(node, &f->fmt.pix); in unicam_try_fmt_vid()
1904 if (vb2_is_busy(&node->buffer_queue)) in unicam_s_fmt_vid()
1905 return -EBUSY; in unicam_s_fmt_vid()
1907 __unicam_try_fmt_vid(node, &f->fmt.pix); in unicam_s_fmt_vid()
1908 node->fmt = *f; in unicam_s_fmt_vid()
1919 if (f->mbus_code && unicam_meta_formats[i].code != f->mbus_code) in unicam_enum_fmt_meta()
1922 if (index == f->index) { in unicam_enum_fmt_meta()
1923 f->pixelformat = unicam_meta_formats[i].fourcc; in unicam_enum_fmt_meta()
1924 f->type = V4L2_BUF_TYPE_META_CAPTURE; in unicam_enum_fmt_meta()
1925 f->flags = V4L2_FMT_FLAG_META_LINE_BASED; in unicam_enum_fmt_meta()
1932 return -EINVAL; in unicam_enum_fmt_meta()
1940 f->fmt.meta = node->fmt.fmt.meta; in unicam_g_fmt_meta()
1954 fmtinfo = unicam_find_format_by_fourcc(meta->dataformat, in __unicam_try_fmt_meta()
1958 meta->dataformat = fmtinfo->fourcc; in __unicam_try_fmt_meta()
1961 unicam_calc_meta_size_bpl(node->dev, fmtinfo, meta); in __unicam_try_fmt_meta()
1971 __unicam_try_fmt_meta(node, &f->fmt.meta); in unicam_try_fmt_meta()
1980 if (vb2_is_busy(&node->buffer_queue)) in unicam_s_fmt_meta()
1981 return -EBUSY; in unicam_s_fmt_meta()
1983 __unicam_try_fmt_meta(node, &f->fmt.meta); in unicam_s_fmt_meta()
1984 node->fmt = *f; in unicam_s_fmt_meta()
1993 int ret = -EINVAL; in unicam_enum_framesizes()
1995 if (fsize->index > 0) in unicam_enum_framesizes()
1999 if (!unicam_find_format_by_fourcc(fsize->pixel_format, in unicam_enum_framesizes()
2003 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in unicam_enum_framesizes()
2004 fsize->stepwise.min_width = UNICAM_IMAGE_MIN_WIDTH; in unicam_enum_framesizes()
2005 fsize->stepwise.max_width = UNICAM_IMAGE_MAX_WIDTH; in unicam_enum_framesizes()
2006 fsize->stepwise.step_width = 1; in unicam_enum_framesizes()
2007 fsize->stepwise.min_height = UNICAM_IMAGE_MIN_HEIGHT; in unicam_enum_framesizes()
2008 fsize->stepwise.max_height = UNICAM_IMAGE_MAX_HEIGHT; in unicam_enum_framesizes()
2009 fsize->stepwise.step_height = 1; in unicam_enum_framesizes()
2011 if (!unicam_find_format_by_fourcc(fsize->pixel_format, in unicam_enum_framesizes()
2015 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; in unicam_enum_framesizes()
2016 fsize->stepwise.min_width = UNICAM_META_MIN_WIDTH; in unicam_enum_framesizes()
2017 fsize->stepwise.max_width = UNICAM_META_MAX_WIDTH; in unicam_enum_framesizes()
2018 fsize->stepwise.step_width = 1; in unicam_enum_framesizes()
2019 fsize->stepwise.min_height = UNICAM_META_MIN_HEIGHT; in unicam_enum_framesizes()
2020 fsize->stepwise.max_height = UNICAM_META_MAX_HEIGHT; in unicam_enum_framesizes()
2021 fsize->stepwise.step_height = 1; in unicam_enum_framesizes()
2030 struct unicam_device *unicam = node->dev; in unicam_log_status()
2034 v4l2_device_call_all(&unicam->v4l2_dev, 0, core, log_status); in unicam_log_status()
2036 dev_info(unicam->dev, "-----Receiver status-----\n"); in unicam_log_status()
2037 dev_info(unicam->dev, "V4L2 width/height: %ux%u\n", in unicam_log_status()
2038 node->fmt.fmt.pix.width, node->fmt.fmt.pix.height); in unicam_log_status()
2039 dev_info(unicam->dev, "V4L2 format: %08x\n", in unicam_log_status()
2040 node->fmt.fmt.pix.pixelformat); in unicam_log_status()
2042 dev_info(unicam->dev, "Unpacking/packing: %u / %u\n", in unicam_log_status()
2045 dev_info(unicam->dev, "----Live data----\n"); in unicam_log_status()
2046 dev_info(unicam->dev, "Programmed stride: %4u\n", in unicam_log_status()
2048 dev_info(unicam->dev, "Detected resolution: %ux%u\n", in unicam_log_status()
2051 dev_info(unicam->dev, "Write pointer: %08x\n", in unicam_log_status()
2060 switch (sub->type) { in unicam_subscribe_event()
2064 return -EINVAL; in unicam_subscribe_event()
2111 media_entity_to_video_device(link->sink->entity); in unicam_video_link_validate()
2113 media_entity_to_v4l2_subdev(link->source->entity); in unicam_video_link_validate()
2125 ret = -EINVAL; in unicam_video_link_validate()
2130 const struct v4l2_pix_format *fmt = &node->fmt.fmt.pix; in unicam_video_link_validate()
2133 fmtinfo = unicam_find_format_by_fourcc(fmt->pixelformat, in unicam_video_link_validate()
2136 ret = -EPIPE; in unicam_video_link_validate()
2140 if (fmtinfo->code != format->code || in unicam_video_link_validate()
2141 fmt->height != format->height || in unicam_video_link_validate()
2142 fmt->width != format->width || in unicam_video_link_validate()
2143 fmt->field != format->field) { in unicam_video_link_validate()
2144 dev_dbg(node->dev->dev, in unicam_video_link_validate()
2146 fmt->width, fmt->height, fmtinfo->code, in unicam_video_link_validate()
2147 v4l2_field_names[fmt->field], in unicam_video_link_validate()
2148 format->width, format->height, format->code, in unicam_video_link_validate()
2149 v4l2_field_names[format->field]); in unicam_video_link_validate()
2150 ret = -EPIPE; in unicam_video_link_validate()
2153 const struct v4l2_meta_format *fmt = &node->fmt.fmt.meta; in unicam_video_link_validate()
2157 fmtinfo = unicam_find_format_by_fourcc(fmt->dataformat, in unicam_video_link_validate()
2160 ret = -EPIPE; in unicam_video_link_validate()
2164 if (fmtinfo->code != format->code || in unicam_video_link_validate()
2165 fmt->height != format->height || in unicam_video_link_validate()
2166 fmt->width != format->width) { in unicam_video_link_validate()
2167 dev_dbg(node->dev->dev, in unicam_video_link_validate()
2169 fmt->width, fmt->height, fmtinfo->code, in unicam_video_link_validate()
2170 format->width, format->height, format->code); in unicam_video_link_validate()
2171 ret = -EPIPE; in unicam_video_link_validate()
2188 unicam_put(node->dev); in unicam_node_release()
2194 struct v4l2_pix_format *fmt = &node->fmt.fmt.pix; in unicam_set_default_format()
2198 node->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in unicam_set_default_format()
2201 fmt->pixelformat = fmtinfo->fourcc; in unicam_set_default_format()
2202 unicam_calc_image_size_bpl(node->dev, fmtinfo, fmt); in unicam_set_default_format()
2204 struct v4l2_meta_format *fmt = &node->fmt.fmt.meta; in unicam_set_default_format()
2208 node->fmt.type = V4L2_BUF_TYPE_META_CAPTURE; in unicam_set_default_format()
2210 fmt->dataformat = fmtinfo->fourcc; in unicam_set_default_format()
2211 fmt->width = unicam_default_meta_format.width; in unicam_set_default_format()
2212 fmt->height = unicam_default_meta_format.height; in unicam_set_default_format()
2213 unicam_calc_meta_size_bpl(node->dev, fmtinfo, fmt); in unicam_set_default_format()
2223 struct unicam_node *node = &unicam->node[type]; in unicam_register_node()
2224 struct video_device *vdev = &node->video_dev; in unicam_register_node()
2225 struct vb2_queue *q = &node->buffer_queue; in unicam_register_node()
2228 node->dev = unicam_get(unicam); in unicam_register_node()
2229 node->id = type; in unicam_register_node()
2231 spin_lock_init(&node->dma_queue_lock); in unicam_register_node()
2233 INIT_LIST_HEAD(&node->dma_queue); in unicam_register_node()
2236 q->type = type == UNICAM_IMAGE_NODE ? V4L2_BUF_TYPE_VIDEO_CAPTURE in unicam_register_node()
2238 q->io_modes = VB2_MMAP | VB2_DMABUF; in unicam_register_node()
2239 q->drv_priv = node; in unicam_register_node()
2240 q->ops = &unicam_video_qops; in unicam_register_node()
2241 q->mem_ops = &vb2_dma_contig_memops; in unicam_register_node()
2242 q->buf_struct_size = sizeof(struct unicam_buffer); in unicam_register_node()
2243 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in unicam_register_node()
2244 q->lock = &unicam->lock; in unicam_register_node()
2245 q->min_queued_buffers = 1; in unicam_register_node()
2246 q->dev = unicam->dev; in unicam_register_node()
2250 dev_err(unicam->dev, "vb2_queue_init() failed\n"); in unicam_register_node()
2255 vdev->release = unicam_node_release; in unicam_register_node()
2256 vdev->fops = &unicam_fops; in unicam_register_node()
2257 vdev->ioctl_ops = &unicam_ioctl_ops; in unicam_register_node()
2258 vdev->v4l2_dev = &unicam->v4l2_dev; in unicam_register_node()
2259 vdev->vfl_dir = VFL_DIR_RX; in unicam_register_node()
2260 vdev->queue = q; in unicam_register_node()
2261 vdev->lock = &unicam->lock; in unicam_register_node()
2262 vdev->device_caps = type == UNICAM_IMAGE_NODE in unicam_register_node()
2264 vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_IO_MC; in unicam_register_node()
2265 vdev->entity.ops = &unicam_video_media_ops; in unicam_register_node()
2267 snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, in unicam_register_node()
2273 vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; in unicam_register_node()
2275 node->pad.flags = MEDIA_PAD_FL_SINK; in unicam_register_node()
2277 ret = media_entity_pads_init(&vdev->entity, 1, &node->pad); in unicam_register_node()
2281 node->dummy_buf.size = UNICAM_DUMMY_BUF_SIZE; in unicam_register_node()
2282 node->dummy_buf_cpu_addr = dma_alloc_coherent(unicam->dev, in unicam_register_node()
2283 node->dummy_buf.size, in unicam_register_node()
2284 &node->dummy_buf.dma_addr, in unicam_register_node()
2286 if (!node->dummy_buf_cpu_addr) { in unicam_register_node()
2287 dev_err(unicam->dev, "Unable to allocate dummy buffer.\n"); in unicam_register_node()
2288 ret = -ENOMEM; in unicam_register_node()
2294 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in unicam_register_node()
2296 dev_err(unicam->dev, "Unable to register video device %s\n", in unicam_register_node()
2297 vdev->name); in unicam_register_node()
2301 node->registered = true; in unicam_register_node()
2303 ret = media_create_pad_link(&unicam->subdev.sd.entity, in unicam_register_node()
2305 &node->video_dev.entity, in unicam_register_node()
2315 dev_err(unicam->dev, "Unable to create pad link for %s\n", in unicam_register_node()
2316 unicam->sensor.subdev->name); in unicam_register_node()
2323 dma_free_coherent(unicam->dev, node->dummy_buf.size, in unicam_register_node()
2324 node->dummy_buf_cpu_addr, in unicam_register_node()
2325 node->dummy_buf.dma_addr); in unicam_register_node()
2327 media_entity_cleanup(&vdev->entity); in unicam_register_node()
2337 for (i = 0; i < ARRAY_SIZE(unicam->node); i++) { in unicam_unregister_nodes()
2338 struct unicam_node *node = &unicam->node[i]; in unicam_unregister_nodes()
2340 if (node->registered) { in unicam_unregister_nodes()
2341 vb2_video_unregister_device(&node->video_dev); in unicam_unregister_nodes()
2342 node->registered = false; in unicam_unregister_nodes()
2345 if (node->dummy_buf_cpu_addr) in unicam_unregister_nodes()
2346 dma_free_coherent(unicam->dev, node->dummy_buf.size, in unicam_unregister_nodes()
2347 node->dummy_buf_cpu_addr, in unicam_unregister_nodes()
2348 node->dummy_buf.dma_addr); in unicam_unregister_nodes()
2352 /* -----------------------------------------------------------------------------
2361 ret = clk_set_min_rate(unicam->vpu_clock, UNICAM_MIN_VPU_CLOCK_RATE); in unicam_runtime_resume()
2363 dev_err(unicam->dev, "failed to set up VPU clock\n"); in unicam_runtime_resume()
2367 ret = clk_prepare_enable(unicam->vpu_clock); in unicam_runtime_resume()
2369 dev_err(unicam->dev, "Failed to enable VPU clock: %d\n", ret); in unicam_runtime_resume()
2373 ret = clk_set_rate(unicam->clock, 100 * 1000 * 1000); in unicam_runtime_resume()
2375 dev_err(unicam->dev, "failed to set up CSI clock\n"); in unicam_runtime_resume()
2379 ret = clk_prepare_enable(unicam->clock); in unicam_runtime_resume()
2381 dev_err(unicam->dev, "Failed to enable CSI clock: %d\n", ret); in unicam_runtime_resume()
2388 clk_disable_unprepare(unicam->vpu_clock); in unicam_runtime_resume()
2390 if (clk_set_min_rate(unicam->vpu_clock, 0)) in unicam_runtime_resume()
2391 dev_err(unicam->dev, "failed to reset the VPU clock\n"); in unicam_runtime_resume()
2400 clk_disable_unprepare(unicam->clock); in unicam_runtime_suspend()
2402 if (clk_set_min_rate(unicam->vpu_clock, 0)) in unicam_runtime_suspend()
2403 dev_err(unicam->dev, "failed to reset the VPU clock\n"); in unicam_runtime_suspend()
2405 clk_disable_unprepare(unicam->vpu_clock); in unicam_runtime_suspend()
2414 /* -----------------------------------------------------------------------------
2423 struct media_pad *sink = &unicam->subdev.pads[UNICAM_SD_PAD_SINK]; in unicam_async_bound()
2427 dev_dbg(unicam->dev, "Using sensor %s for capture\n", in unicam_async_bound()
2428 subdev->name); in unicam_async_bound()
2437 dev_err(unicam->dev, "No connected sensor pad\n"); in unicam_async_bound()
2441 unicam->sensor.subdev = subdev; in unicam_async_bound()
2442 unicam->sensor.pad = source; in unicam_async_bound()
2454 dev_err(unicam->dev, "Unable to register image video device.\n"); in unicam_async_complete()
2460 dev_err(unicam->dev, "Unable to register metadata video device.\n"); in unicam_async_complete()
2464 ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev); in unicam_async_complete()
2466 dev_err(unicam->dev, "Unable to register subdev nodes.\n"); in unicam_async_complete()
2491 ret = of_property_read_u32(unicam->dev->of_node, "brcm,num-data-lanes", in unicam_async_nf_init()
2492 &unicam->max_data_lanes); in unicam_async_nf_init()
2494 dev_err(unicam->dev, "Missing %s DT property\n", in unicam_async_nf_init()
2495 "brcm,num-data-lanes"); in unicam_async_nf_init()
2496 return -EINVAL; in unicam_async_nf_init()
2500 ep_handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(unicam->dev), 0, 0, in unicam_async_nf_init()
2503 dev_err(unicam->dev, "No endpoint found\n"); in unicam_async_nf_init()
2504 return -ENODEV; in unicam_async_nf_init()
2509 dev_err(unicam->dev, "Failed to parse endpoint: %d\n", ret); in unicam_async_nf_init()
2513 unicam->bus_type = ep.bus_type; in unicam_async_nf_init()
2521 dev_err(unicam->dev, "%u data lanes not supported\n", in unicam_async_nf_init()
2523 ret = -EINVAL; in unicam_async_nf_init()
2527 if (num_data_lanes > unicam->max_data_lanes) { in unicam_async_nf_init()
2528 dev_err(unicam->dev, in unicam_async_nf_init()
2530 num_data_lanes, unicam->max_data_lanes); in unicam_async_nf_init()
2531 ret = -EINVAL; in unicam_async_nf_init()
2535 unicam->max_data_lanes = num_data_lanes; in unicam_async_nf_init()
2536 unicam->bus_flags = ep.bus.mipi_csi2.flags; in unicam_async_nf_init()
2541 unicam->max_data_lanes = 1; in unicam_async_nf_init()
2542 unicam->bus_flags = ep.bus.mipi_csi1.strobe; in unicam_async_nf_init()
2547 dev_err(unicam->dev, "Unsupported bus type %u\n", ep.bus_type); in unicam_async_nf_init()
2548 ret = -EINVAL; in unicam_async_nf_init()
2553 v4l2_async_nf_init(&unicam->notifier, &unicam->v4l2_dev); in unicam_async_nf_init()
2555 asc = v4l2_async_nf_add_fwnode_remote(&unicam->notifier, ep_handle, in unicam_async_nf_init()
2562 dev_err(unicam->dev, "Failed to add entry to notifier: %d\n", in unicam_async_nf_init()
2567 unicam->notifier.ops = &unicam_async_ops; in unicam_async_nf_init()
2569 ret = v4l2_async_nf_register(&unicam->notifier); in unicam_async_nf_init()
2571 dev_err(unicam->dev, "Error registering device notifier: %d\n", in unicam_async_nf_init()
2583 /* -----------------------------------------------------------------------------
2591 unicam->mdev.dev = unicam->dev; in unicam_media_init()
2592 strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, in unicam_media_init()
2593 sizeof(unicam->mdev.model)); in unicam_media_init()
2594 unicam->mdev.hw_revision = 0; in unicam_media_init()
2596 media_device_init(&unicam->mdev); in unicam_media_init()
2598 unicam->v4l2_dev.mdev = &unicam->mdev; in unicam_media_init()
2600 ret = v4l2_device_register(unicam->dev, &unicam->v4l2_dev); in unicam_media_init()
2602 dev_err(unicam->dev, "Unable to register v4l2 device\n"); in unicam_media_init()
2606 ret = media_device_register(&unicam->mdev); in unicam_media_init()
2608 dev_err(unicam->dev, in unicam_media_init()
2609 "Unable to register media-controller device\n"); in unicam_media_init()
2616 v4l2_device_unregister(&unicam->v4l2_dev); in unicam_media_init()
2618 media_device_cleanup(&unicam->mdev); in unicam_media_init()
2629 return -ENOMEM; in unicam_probe()
2631 kref_init(&unicam->kref); in unicam_probe()
2632 mutex_init(&unicam->lock); in unicam_probe()
2634 unicam->dev = &pdev->dev; in unicam_probe()
2637 unicam->base = devm_platform_ioremap_resource_byname(pdev, "unicam"); in unicam_probe()
2638 if (IS_ERR(unicam->base)) { in unicam_probe()
2639 ret = PTR_ERR(unicam->base); in unicam_probe()
2643 unicam->clk_gate_base = devm_platform_ioremap_resource_byname(pdev, "cmi"); in unicam_probe()
2644 if (IS_ERR(unicam->clk_gate_base)) { in unicam_probe()
2645 ret = PTR_ERR(unicam->clk_gate_base); in unicam_probe()
2649 unicam->clock = devm_clk_get(&pdev->dev, "lp"); in unicam_probe()
2650 if (IS_ERR(unicam->clock)) { in unicam_probe()
2651 dev_err(unicam->dev, "Failed to get lp clock\n"); in unicam_probe()
2652 ret = PTR_ERR(unicam->clock); in unicam_probe()
2656 unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu"); in unicam_probe()
2657 if (IS_ERR(unicam->vpu_clock)) { in unicam_probe()
2658 dev_err(unicam->dev, "Failed to get vpu clock\n"); in unicam_probe()
2659 ret = PTR_ERR(unicam->vpu_clock); in unicam_probe()
2667 ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, in unicam_probe()
2670 dev_err(&pdev->dev, "Unable to request interrupt\n"); in unicam_probe()
2675 pm_runtime_enable(&pdev->dev); in unicam_probe()
2694 media_device_unregister(&unicam->mdev); in unicam_probe()
2696 pm_runtime_disable(&pdev->dev); in unicam_probe()
2708 v4l2_device_unregister(&unicam->v4l2_dev); in unicam_remove()
2709 media_device_unregister(&unicam->mdev); in unicam_remove()
2710 v4l2_async_nf_unregister(&unicam->notifier); in unicam_remove()
2716 pm_runtime_disable(&pdev->dev); in unicam_remove()
2720 { .compatible = "brcm,bcm2835-unicam", },
2730 .pm = pm_ptr(&unicam_pm_ops),
2738 MODULE_DESCRIPTION("BCM2835 Unicam driver");