Lines Matching full:unicam
3 * BCM283x / BCM271x Unicam Capture Driver
21 * This driver directly controls the Unicam peripheral - there is no
22 * involvement with the VideoCore firmware. Unicam receives CSI-2 or CCP2 data
61 #include "bcm2835-unicam-regs.h"
63 #define UNICAM_MODULE_NAME "unicam"
66 * Unicam must request a minimum of 250Mhz from the VPU clock.
71 /* Unicam has an internal DMA alignment constraint of 16 bytes for each line. */
123 * struct unicam_format_info - Unicam media bus format information
175 * Dummy buffer intended to be used by unicam
249 struct unicam_device *unicam = in unicam_release() local
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()
256 kfree(unicam); in unicam_release()
259 static struct unicam_device *unicam_get(struct unicam_device *unicam) in unicam_get() argument
261 kref_get(&unicam->kref); in unicam_get()
263 return unicam; in unicam_get()
266 static void unicam_put(struct unicam_device *unicam) in unicam_put() argument
268 kref_put(&unicam->kref, unicam_release); in unicam_put()
556 static void unicam_calc_image_size_bpl(struct unicam_device *unicam, in unicam_calc_image_size_bpl() argument
581 static void unicam_calc_meta_size_bpl(struct unicam_device *unicam, in unicam_calc_meta_size_bpl() argument
599 static inline void unicam_clk_write(struct unicam_device *unicam, u32 val) in unicam_clk_write() argument
602 writel(val | 0x5a000000, unicam->clk_gate_base); in unicam_clk_write()
605 static inline u32 unicam_reg_read(struct unicam_device *unicam, u32 offset) in unicam_reg_read() argument
607 return readl(unicam->base + offset); in unicam_reg_read()
610 static inline void unicam_reg_write(struct unicam_device *unicam, u32 offset, u32 val) in unicam_reg_write() argument
612 writel(val, unicam->base + offset); in unicam_reg_write()
629 static inline void unicam_reg_write_field(struct unicam_device *unicam, u32 offset, in unicam_reg_write_field() argument
632 u32 val = unicam_reg_read(unicam, offset); in unicam_reg_write_field()
635 unicam_reg_write(unicam, offset, val); in unicam_reg_write_field()
652 static unsigned int unicam_get_lines_done(struct unicam_device *unicam) in unicam_get_lines_done() argument
654 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_get_lines_done()
662 cur_addr = unicam_reg_read(unicam, UNICAM_IBWP); in unicam_get_lines_done()
697 static void unicam_queue_event_sof(struct unicam_device *unicam) in unicam_queue_event_sof() argument
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()
710 struct unicam_device *unicam = dev; in unicam_isr() local
712 unsigned int sequence = unicam->sequence; in unicam_isr()
718 sta = unicam_reg_read(unicam, UNICAM_STA); in unicam_isr()
720 unicam_reg_write(unicam, UNICAM_STA, sta); in unicam_isr()
722 ista = unicam_reg_read(unicam, UNICAM_ISTA); in unicam_isr()
724 unicam_reg_write(unicam, UNICAM_ISTA, ista); 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()
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()
786 dev_dbg(unicam->v4l2_dev.dev, in unicam_isr()
797 unicam_queue_event_sof(unicam); 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()
819 if (unicam_reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) { in unicam_isr()
821 unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC); in unicam_isr()
822 unicam_reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM); in unicam_isr()
827 static void unicam_set_packing_config(struct unicam_device *unicam, in unicam_set_packing_config() argument
830 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_set_packing_config()
846 unicam_reg_write(unicam, UNICAM_IPIPE, val); in unicam_set_packing_config()
849 static void unicam_cfg_image_id(struct unicam_device *unicam, u8 vc, u8 dt) in unicam_cfg_image_id() argument
851 if (unicam->bus_type == V4L2_MBUS_CSI2_DPHY) { in unicam_cfg_image_id()
853 unicam_reg_write(unicam, UNICAM_IDI0, (vc << 6) | dt); in unicam_cfg_image_id()
856 unicam_reg_write(unicam, UNICAM_IDI0, 0x80 | dt); in unicam_cfg_image_id()
860 static void unicam_enable_ed(struct unicam_device *unicam) in unicam_enable_ed() argument
862 u32 val = unicam_reg_read(unicam, UNICAM_DCS); in unicam_enable_ed()
868 unicam_reg_write(unicam, UNICAM_DCS, val); in unicam_enable_ed()
871 static int unicam_get_image_vc_dt(struct unicam_device *unicam, in unicam_get_image_vc_dt() argument
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()
907 static void unicam_start_rx(struct unicam_device *unicam, in unicam_start_rx() argument
910 struct unicam_node *node = &unicam->node[UNICAM_IMAGE_NODE]; in unicam_start_rx()
936 val = 0x155 & GENMASK(unicam->pipe.num_data_lanes * 2 + 1, 0); in unicam_start_rx()
937 unicam_clk_write(unicam, val); in unicam_start_rx()
940 unicam_reg_write(unicam, UNICAM_CTRL, UNICAM_MEM); in unicam_start_rx()
946 unicam_reg_write(unicam, UNICAM_ANA, val); in unicam_start_rx()
950 unicam_reg_write_field(unicam, UNICAM_ANA, 0, UNICAM_AR); in unicam_start_rx()
953 unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_CPR); in unicam_start_rx()
954 unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPR); in unicam_start_rx()
956 unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPE); in unicam_start_rx()
959 val = unicam_reg_read(unicam, UNICAM_CTRL); 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()
970 unicam_reg_write(unicam, UNICAM_CTRL, val); in unicam_start_rx()
972 unicam_reg_write(unicam, UNICAM_IHWIN, 0); in unicam_start_rx()
973 unicam_reg_write(unicam, UNICAM_IVWIN, 0); in unicam_start_rx()
976 val = unicam_reg_read(unicam, UNICAM_PRI); in unicam_start_rx()
983 unicam_reg_write(unicam, UNICAM_PRI, val); in unicam_start_rx()
985 unicam_reg_write_field(unicam, UNICAM_ANA, 0, UNICAM_DDL); in unicam_start_rx()
991 unicam_reg_write(unicam, UNICAM_ICTL, val); in unicam_start_rx()
992 unicam_reg_write(unicam, UNICAM_STA, UNICAM_STA_MASK_ALL); in unicam_start_rx()
993 unicam_reg_write(unicam, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL); in unicam_start_rx()
996 unicam_reg_write_field(unicam, UNICAM_CLT, 2, UNICAM_CLT1_MASK); in unicam_start_rx()
998 unicam_reg_write_field(unicam, UNICAM_CLT, 6, UNICAM_CLT2_MASK); in unicam_start_rx()
1000 unicam_reg_write_field(unicam, UNICAM_DLT, 2, UNICAM_DLT1_MASK); in unicam_start_rx()
1002 unicam_reg_write_field(unicam, UNICAM_DLT, 6, UNICAM_DLT2_MASK); in unicam_start_rx()
1004 unicam_reg_write_field(unicam, UNICAM_DLT, 0, UNICAM_DLT3_MASK); in unicam_start_rx()
1006 unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_SOE); in unicam_start_rx()
1015 unicam_reg_write(unicam, UNICAM_CMP0, val); 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()
1033 unicam_reg_write(unicam, UNICAM_CLK, val); 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()
1055 unicam_reg_write(unicam, UNICAM_DAT0, val); in unicam_start_rx()
1057 if (unicam->pipe.num_data_lanes == 1) in unicam_start_rx()
1059 unicam_reg_write(unicam, UNICAM_DAT1, val); 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()
1068 unicam_reg_write(unicam, UNICAM_DAT2, val); in unicam_start_rx()
1070 if (unicam->pipe.num_data_lanes == 3) in unicam_start_rx()
1072 unicam_reg_write(unicam, UNICAM_DAT3, val); in unicam_start_rx()
1075 unicam_reg_write(unicam, UNICAM_IBLS, in unicam_start_rx()
1078 unicam_set_packing_config(unicam, fmtinfo); in unicam_start_rx()
1080 ret = unicam_get_image_vc_dt(unicam, state, &vc, &dt); in unicam_start_rx()
1090 unicam_cfg_image_id(unicam, vc, dt); in unicam_start_rx()
1092 val = unicam_reg_read(unicam, UNICAM_MISC); in unicam_start_rx()
1095 unicam_reg_write(unicam, UNICAM_MISC, val); in unicam_start_rx()
1098 unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_CPE); in unicam_start_rx()
1101 unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_LIP_MASK); in unicam_start_rx()
1107 unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC); in unicam_start_rx()
1110 static void unicam_start_metadata(struct unicam_device *unicam) in unicam_start_metadata() argument
1112 struct unicam_node *node = &unicam->node[UNICAM_METADATA_NODE]; in unicam_start_metadata()
1114 unicam_enable_ed(unicam); in unicam_start_metadata()
1116 unicam_reg_write_field(unicam, UNICAM_DCS, 1, UNICAM_LDP); in unicam_start_metadata()
1119 static void unicam_disable(struct unicam_device *unicam) in unicam_disable() argument
1122 unicam_reg_write_field(unicam, UNICAM_ANA, 1, UNICAM_DDL); in unicam_disable()
1125 unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_SOE); in unicam_disable()
1128 unicam_reg_write(unicam, UNICAM_DAT0, 0); in unicam_disable()
1129 unicam_reg_write(unicam, UNICAM_DAT1, 0); in unicam_disable()
1131 if (unicam->max_data_lanes > 2) { in unicam_disable()
1132 unicam_reg_write(unicam, UNICAM_DAT2, 0); in unicam_disable()
1133 unicam_reg_write(unicam, UNICAM_DAT3, 0); in unicam_disable()
1137 unicam_reg_write_field(unicam, UNICAM_CTRL, 1, UNICAM_CPR); in unicam_disable()
1139 unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPR); in unicam_disable()
1142 unicam_reg_write_field(unicam, UNICAM_CTRL, 0, UNICAM_CPE); in unicam_disable()
1145 unicam_reg_write(unicam, UNICAM_DCS, 0); in unicam_disable()
1148 unicam_clk_write(unicam, 0); in unicam_disable()
1318 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_subdev_set_format() local
1325 unicam->subdev.enabled_streams) in unicam_subdev_set_format()
1393 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_subdev_set_routing() local
1395 if (which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->subdev.enabled_streams) in unicam_subdev_set_routing()
1405 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_sd_enable_streams() local
1409 if (!unicam->subdev.enabled_streams) { in unicam_sd_enable_streams()
1410 /* Configure and start Unicam. */ 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()
1414 unicam_start_metadata(unicam); in unicam_sd_enable_streams()
1416 unicam_start_rx(unicam, state); 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()
1441 struct unicam_device *unicam = sd_to_unicam_device(sd); in unicam_sd_disable_streams() local
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()
1457 unicam_disable(unicam); in unicam_sd_disable_streams()
1485 static int unicam_subdev_init(struct unicam_device *unicam) in unicam_subdev_init() argument
1487 struct v4l2_subdev *sd = &unicam->subdev.sd; in unicam_subdev_init()
1492 v4l2_set_subdevdata(sd, unicam); in unicam_subdev_init()
1496 sd->dev = unicam->dev; 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()
1535 static void unicam_subdev_cleanup(struct unicam_device *unicam) in unicam_subdev_cleanup() argument
1537 v4l2_subdev_cleanup(&unicam->subdev.sd); in unicam_subdev_cleanup()
1538 media_entity_cleanup(&unicam->subdev.sd.entity); in unicam_subdev_cleanup()
1611 static int unicam_num_data_lanes(struct unicam_device *unicam) in unicam_num_data_lanes() argument
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()
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()
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()
1653 struct unicam_device *unicam = node->dev; in unicam_start_streaming() local
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()
1685 unicam->pipe.nodes |= BIT(UNICAM_IMAGE_NODE); 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()
1697 ret = unicam_num_data_lanes(unicam); 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()
1719 * Unicam DMA engines are not generic, they have been designed to 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()
1770 struct unicam_device *unicam = node->dev; in unicam_stop_streaming() local
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()
2030 struct unicam_device *unicam = node->dev; in unicam_log_status() local
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()
2039 dev_info(unicam->dev, "V4L2 format: %08x\n", in unicam_log_status()
2041 reg = unicam_reg_read(unicam, UNICAM_IPIPE); 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()
2047 unicam_reg_read(unicam, UNICAM_IBLS)); in unicam_log_status()
2048 dev_info(unicam->dev, "Detected resolution: %ux%u\n", in unicam_log_status()
2049 unicam_reg_read(unicam, UNICAM_IHSTA), in unicam_log_status()
2050 unicam_reg_read(unicam, UNICAM_IVSTA)); in unicam_log_status()
2051 dev_info(unicam->dev, "Write pointer: %08x\n", in unicam_log_status()
2052 unicam_reg_read(unicam, UNICAM_IBWP)); in unicam_log_status()
2098 /* unicam capture driver file operations */
2217 static int unicam_register_node(struct unicam_device *unicam, in unicam_register_node() argument
2223 struct unicam_node *node = &unicam->node[type]; in unicam_register_node()
2228 node->dev = unicam_get(unicam); in unicam_register_node()
2244 q->lock = &unicam->lock; 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()
2258 vdev->v4l2_dev = &unicam->v4l2_dev; in unicam_register_node()
2261 vdev->lock = &unicam->lock; in unicam_register_node()
2282 node->dummy_buf_cpu_addr = dma_alloc_coherent(unicam->dev, in unicam_register_node()
2287 dev_err(unicam->dev, "Unable to allocate dummy buffer.\n"); in unicam_register_node()
2296 dev_err(unicam->dev, "Unable to register video device %s\n", in unicam_register_node()
2303 ret = media_create_pad_link(&unicam->subdev.sd.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()
2329 unicam_put(unicam); in unicam_register_node()
2333 static void unicam_unregister_nodes(struct unicam_device *unicam) in unicam_unregister_nodes() argument
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()
2346 dma_free_coherent(unicam->dev, node->dummy_buf.size, in unicam_unregister_nodes()
2358 struct unicam_device *unicam = dev_get_drvdata(dev); in unicam_runtime_resume() local
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()
2398 struct unicam_device *unicam = dev_get_drvdata(dev); in unicam_runtime_suspend() local
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()
2422 struct unicam_device *unicam = notifier_to_unicam_device(notifier); in unicam_async_bound() local
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()
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()
2449 struct unicam_device *unicam = notifier_to_unicam_device(notifier); in unicam_async_complete() local
2452 ret = unicam_register_node(unicam, UNICAM_IMAGE_NODE); in unicam_async_complete()
2454 dev_err(unicam->dev, "Unable to register image video device.\n"); in unicam_async_complete()
2458 ret = unicam_register_node(unicam, UNICAM_METADATA_NODE); 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()
2473 unicam_unregister_nodes(unicam); in unicam_async_complete()
2474 unicam_put(unicam); in unicam_async_complete()
2484 static int unicam_async_nf_init(struct unicam_device *unicam) in unicam_async_nf_init() argument
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()
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()
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()
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()
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()
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()
2587 static int unicam_media_init(struct unicam_device *unicam) in unicam_media_init() argument
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()
2616 v4l2_device_unregister(&unicam->v4l2_dev); in unicam_media_init()
2618 media_device_cleanup(&unicam->mdev); in unicam_media_init()
2624 struct unicam_device *unicam; in unicam_probe() local
2627 unicam = kzalloc(sizeof(*unicam), GFP_KERNEL); in unicam_probe()
2628 if (!unicam) 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()
2635 platform_set_drvdata(pdev, unicam); 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()
2668 "unicam_capture0", unicam); in unicam_probe()
2677 ret = unicam_media_init(unicam); in unicam_probe()
2681 ret = unicam_subdev_init(unicam); in unicam_probe()
2685 ret = unicam_async_nf_init(unicam); in unicam_probe()
2692 unicam_subdev_cleanup(unicam); in unicam_probe()
2694 media_device_unregister(&unicam->mdev); in unicam_probe()
2698 unicam_put(unicam); in unicam_probe()
2705 struct unicam_device *unicam = platform_get_drvdata(pdev); in unicam_remove() local
2707 unicam_unregister_nodes(unicam); in unicam_remove()
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()
2712 unicam_subdev_cleanup(unicam); in unicam_remove()
2714 unicam_put(unicam); in unicam_remove()
2720 { .compatible = "brcm,bcm2835-unicam", },
2738 MODULE_DESCRIPTION("BCM2835 Unicam driver");