1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2021 StarFive Technology Co., Ltd.
5 #include <linux/completion.h>
6 #include <linux/delay.h>
7 #include <linux/dmaengine.h>
8 #include <linux/init.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/of_reserved_mem.h>
15 #include <linux/of_graph.h>
16 #include <linux/of_address.h>
17 #include <linux/pinctrl/consumer.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_runtime.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/uaccess.h>
23 #include <linux/mfd/syscon.h>
25 #include <linux/videodev2.h>
27 #include <media/media-device.h>
28 #include <media/v4l2-async.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-mc.h>
31 #include <media/v4l2-fwnode.h>
32 #include <linux/debugfs.h>
37 unsigned int stdbg_level = ST_DEBUG;
38 unsigned int stdbg_mask = 0x7F;
40 unsigned int stdbg_level = ST_ERR;
41 unsigned int stdbg_mask = 0x7F;
43 EXPORT_SYMBOL_GPL(stdbg_level);
44 EXPORT_SYMBOL_GPL(stdbg_mask);
46 static const struct reg_name mem_reg_name[] = {
57 static struct clk_bulk_data stfcamss_clocks[] = {
58 { .id = "clk_apb_func" },
60 { .id = "clk_sys_clk" },
61 { .id = "clk_wrapper_clk_c" },
62 { .id = "clk_dvp_inv" },
63 { .id = "clk_axiwr" },
64 { .id = "clk_mipi_rx0_pxl" },
65 { .id = "clk_pixel_clk_if0" },
66 { .id = "clk_pixel_clk_if1" },
67 { .id = "clk_pixel_clk_if2" },
68 { .id = "clk_pixel_clk_if3" },
69 { .id = "clk_m31dphy_cfgclk_in" },
70 { .id = "clk_m31dphy_refclk_in" },
71 { .id = "clk_m31dphy_txclkesc_lan0" },
72 { .id = "clk_ispcore_2x" },
73 { .id = "clk_isp_axi" },
74 { .id = "clk_noc_bus_clk_isp_axi" },
77 static struct reset_control_bulk_data stfcamss_resets[] = {
78 { .id = "rst_wrapper_p" },
79 { .id = "rst_wrapper_c" },
81 { .id = "rst_sys_clk" },
82 { .id = "rst_axird" },
83 { .id = "rst_axiwr" },
84 { .id = "rst_pixel_clk_if0" },
85 { .id = "rst_pixel_clk_if1" },
86 { .id = "rst_pixel_clk_if2" },
87 { .id = "rst_pixel_clk_if3" },
88 { .id = "rst_m31dphy_hw" },
89 { .id = "rst_m31dphy_b09_always_on" },
90 { .id = "rst_isp_top_n" },
91 { .id = "rst_isp_top_axi" },
94 int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
96 struct device *dev = &pdev->dev;
101 for (i = 0; i < ARRAY_SIZE(mem_reg_name); i++) {
102 name = (char *)(&mem_reg_name[i]);
103 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
108 if (!strcmp(name, "csi2rx")) {
109 vin->csi2rx_base = devm_ioremap_resource(dev, res);
110 if (IS_ERR(vin->csi2rx_base))
111 return PTR_ERR(vin->csi2rx_base);
112 } else if (!strcmp(name, "vclk")) {
113 vin->clkgen_base = ioremap(res->start, resource_size(res));
114 if (!vin->clkgen_base)
116 } else if (!strcmp(name, "vrst")) {
117 vin->rstgen_base = devm_ioremap_resource(dev, res);
118 if (IS_ERR(vin->rstgen_base))
119 return PTR_ERR(vin->rstgen_base);
120 } else if (!strcmp(name, "sctrl")) {
121 vin->sysctrl_base = devm_ioremap_resource(dev, res);
122 if (IS_ERR(vin->sysctrl_base))
123 return PTR_ERR(vin->sysctrl_base);
124 } else if (!strcmp(name, "isp")) {
125 vin->isp_base = devm_ioremap_resource(dev, res);
126 if (IS_ERR(vin->isp_base))
127 return PTR_ERR(vin->isp_base);
128 } else if (!strcmp(name, "trst")) {
129 vin->vin_top_rstgen_base = devm_ioremap_resource(dev, res);
130 if (IS_ERR(vin->vin_top_rstgen_base))
131 return PTR_ERR(vin->vin_top_rstgen_base);
132 } else if (!strcmp(name, "pmu")) {
133 vin->pmu_test = ioremap(res->start, resource_size(res));
136 } else if (!strcmp(name, "syscrg")) {
137 vin->sys_crg = ioremap(res->start, resource_size(res));
141 st_err(ST_CAMSS, "Could not match resource name\n");
148 int vin_parse_dt(struct device *dev, struct stf_vin_dev *vin)
151 struct device_node *np = dev->of_node;
159 struct media_entity *stfcamss_find_sensor(struct media_entity *entity)
161 struct media_pad *pad;
167 pad = &entity->pads[0];
168 if (!(pad->flags & MEDIA_PAD_FL_SINK))
171 pad = media_entity_remote_pad(pad);
172 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
175 entity = pad->entity;
177 if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
182 static int stfcamss_of_parse_endpoint_node(struct device *dev,
183 struct device_node *node,
184 struct stfcamss_async_subdev *csd)
186 struct v4l2_fwnode_endpoint vep = { { 0 } };
187 struct v4l2_fwnode_bus_parallel *parallel_bus = &vep.bus.parallel;
188 struct v4l2_fwnode_bus_mipi_csi2 *csi2_bus = &vep.bus.mipi_csi2;
189 struct dvp_cfg *dvp = &csd->interface.dvp;
190 struct csi2phy_cfg *csiphy = &csd->interface.csiphy;
192 v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
193 st_debug(ST_CAMSS, "%s: vep.base.port = 0x%x, id = 0x%x\n",
194 __func__, vep.base.port, vep.base.id);
196 csd->port = vep.base.port;
198 case DVP_SENSOR_PORT_NUMBER:
199 st_debug(ST_CAMSS, "%s, flags = 0x%x\n", __func__,
200 parallel_bus->flags);
201 dvp->flags = parallel_bus->flags;
202 dvp->bus_width = parallel_bus->bus_width;
203 dvp->data_shift = parallel_bus->data_shift;
205 case CSI2RX_SENSOR_PORT_NUMBER:
206 st_debug(ST_CAMSS, "%s, CSI2 flags = 0x%x\n",
207 __func__, parallel_bus->flags);
208 csiphy->flags = csi2_bus->flags;
209 memcpy(csiphy->data_lanes,
210 csi2_bus->data_lanes, csi2_bus->num_data_lanes);
211 csiphy->clock_lane = csi2_bus->clock_lane;
212 csiphy->num_data_lanes = csi2_bus->num_data_lanes;
213 memcpy(csiphy->lane_polarities,
214 csi2_bus->lane_polarities,
215 csi2_bus->num_data_lanes + 1);
224 static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
226 struct device *dev = stfcamss->dev;
227 struct device_node *node = NULL;
228 struct device_node *remote = NULL;
229 int ret, num_subdevs = 0;
231 for_each_endpoint_of_node(dev->of_node, node) {
232 struct stfcamss_async_subdev *csd;
234 if (!of_device_is_available(node))
237 remote = of_graph_get_remote_port_parent(node);
239 st_err(ST_CAMSS, "Cannot get remote parent\n");
244 csd = v4l2_async_notifier_add_fwnode_subdev(
245 &stfcamss->notifier, of_fwnode_handle(remote),
246 struct stfcamss_async_subdev);
253 ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
267 static int stfcamss_init_subdevices(struct stfcamss *stfcamss)
271 ret = stf_dvp_subdev_init(stfcamss);
274 "Failed to init stf_dvp sub-device: %d\n",
279 ret = stf_csiphy_subdev_init(stfcamss);
282 "Failed to init stf_csiphy sub-device: %d\n",
287 ret = stf_csi_subdev_init(stfcamss);
290 "Failed to init stf_csi sub-device: %d\n",
295 ret = stf_isp_subdev_init(stfcamss);
298 "Failed to init stf_isp sub-device: %d\n",
303 ret = stf_vin_subdev_init(stfcamss);
306 "Failed to init stf_vin sub-device: %d\n",
313 static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
316 struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
317 struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
318 struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
319 struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
320 struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
322 ret = stf_dvp_register(dvp_dev, &stfcamss->v4l2_dev);
325 "Failed to register stf dvp%d entity: %d\n",
330 ret = stf_csiphy_register(csiphy_dev, &stfcamss->v4l2_dev);
333 "Failed to register stf csiphy%d entity: %d\n",
338 ret = stf_csi_register(csi_dev, &stfcamss->v4l2_dev);
341 "Failed to register stf csi%d entity: %d\n",
346 ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
349 "Failed to register stf isp%d entity: %d\n",
354 ret = stf_vin_register(vin_dev, &stfcamss->v4l2_dev);
357 "Failed to register vin entity: %d\n",
362 ret = media_create_pad_link(
363 &dvp_dev->subdev.entity,
365 &vin_dev->line[VIN_LINE_WR].subdev.entity,
370 "Failed to link %s->vin entities: %d\n",
371 dvp_dev->subdev.entity.name,
376 ret = media_create_pad_link(
377 &csi_dev->subdev.entity,
379 &vin_dev->line[VIN_LINE_WR].subdev.entity,
384 "Failed to link %s->vin entities: %d\n",
385 csi_dev->subdev.entity.name,
390 ret = media_create_pad_link(
391 &csiphy_dev->subdev.entity,
393 &csi_dev->subdev.entity,
395 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
398 "Failed to link %s->%s entities: %d\n",
399 csiphy_dev->subdev.entity.name,
400 csi_dev->subdev.entity.name,
405 ret = media_create_pad_link(
406 &isp_dev->subdev.entity,
408 &vin_dev->line[VIN_LINE_ISP].subdev.entity,
413 "Failed to link %s->%s entities: %d\n",
414 isp_dev->subdev.entity.name,
415 vin_dev->line[VIN_LINE_ISP]
421 ret = media_create_pad_link(
422 &isp_dev->subdev.entity,
424 &vin_dev->line[VIN_LINE_ISP_SS0].subdev.entity,
429 "Failed to link %s->%s entities: %d\n",
430 isp_dev->subdev.entity.name,
431 vin_dev->line[VIN_LINE_ISP_SS0]
437 ret = media_create_pad_link(
438 &isp_dev->subdev.entity,
440 &vin_dev->line[VIN_LINE_ISP_SS1].subdev.entity,
445 "Failed to link %s->%s entities: %d\n",
446 isp_dev->subdev.entity.name,
447 vin_dev->line[VIN_LINE_ISP_SS1]
453 #ifndef STF_CAMSS_SKIP_ITI
454 ret = media_create_pad_link(
455 &isp_dev->subdev.entity,
456 STF_ISP_PAD_SRC_ITIW,
457 &vin_dev->line[VIN_LINE_ISP_ITIW].subdev.entity,
462 "Failed to link %s->%s entities: %d\n",
463 isp_dev->subdev.entity.name,
464 vin_dev->line[VIN_LINE_ISP_ITIW]
470 ret = media_create_pad_link(
471 &isp_dev->subdev.entity,
472 STF_ISP_PAD_SRC_ITIR,
473 &vin_dev->line[VIN_LINE_ISP_ITIR].subdev.entity,
478 "Failed to link %s->%s entities: %d\n",
479 isp_dev->subdev.entity.name,
480 vin_dev->line[VIN_LINE_ISP_ITIR]
487 ret = media_create_pad_link(
488 &isp_dev->subdev.entity,
490 &vin_dev->line[VIN_LINE_ISP_RAW].subdev.entity,
495 "Failed to link %s->%s entities: %d\n",
496 isp_dev->subdev.entity.name,
497 vin_dev->line[VIN_LINE_ISP_RAW]
503 ret = media_create_pad_link(
504 &isp_dev->subdev.entity,
505 STF_ISP_PAD_SRC_SCD_Y,
506 &vin_dev->line[VIN_LINE_ISP_SCD_Y].subdev.entity,
511 "Failed to link %s->%s entities: %d\n",
512 isp_dev->subdev.entity.name,
513 vin_dev->line[VIN_LINE_ISP_SCD_Y]
519 ret = media_create_pad_link(
520 &dvp_dev->subdev.entity,
522 &isp_dev->subdev.entity,
527 "Failed to link %s->%s entities: %d\n",
528 dvp_dev->subdev.entity.name,
529 isp_dev->subdev.entity.name,
534 ret = media_create_pad_link(
535 &csi_dev->subdev.entity,
537 &isp_dev->subdev.entity,
542 "Failed to link %s->%s entities: %d\n",
543 csi_dev->subdev.entity.name,
544 isp_dev->subdev.entity.name,
552 stf_vin_unregister(stfcamss->vin_dev);
554 stf_isp_unregister(stfcamss->isp_dev);
556 stf_csi_unregister(stfcamss->csi_dev);
558 stf_csiphy_unregister(stfcamss->csiphy_dev);
560 stf_dvp_unregister(stfcamss->dvp_dev);
565 static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
567 stf_dvp_unregister(stfcamss->dvp_dev);
568 stf_csiphy_unregister(stfcamss->csiphy_dev);
569 stf_csi_unregister(stfcamss->csi_dev);
570 stf_isp_unregister(stfcamss->isp_dev);
571 stf_vin_unregister(stfcamss->vin_dev);
574 static int stfcamss_register_mediadevice_subdevnodes(
575 struct v4l2_async_notifier *async,
576 struct v4l2_subdev *sd)
578 struct stfcamss *stfcamss =
579 container_of(async, struct stfcamss, notifier);
583 struct media_entity *sensor = &sd->entity;
584 struct media_entity *input = sd->host_priv;
587 for (i = 0; i < sensor->num_pads; i++) {
588 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
591 if (i == sensor->num_pads) {
593 "No source pad in external entity\n");
597 ret = media_create_pad_link(sensor, i,
599 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
602 "Failed to link %s->%s entities: %d\n",
603 sensor->name, input->name, ret);
608 ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
612 if (stfcamss->media_dev.devnode)
615 st_debug(ST_CAMSS, "stfcamss register media device\n");
616 return media_device_register(&stfcamss->media_dev);
619 static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
620 struct v4l2_subdev *subdev,
621 struct v4l2_async_subdev *asd)
623 struct stfcamss *stfcamss =
624 container_of(async, struct stfcamss, notifier);
625 struct stfcamss_async_subdev *csd =
626 container_of(asd, struct stfcamss_async_subdev, asd);
627 enum port_num port = csd->port;
628 struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
629 struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
632 case DVP_SENSOR_PORT_NUMBER:
633 dvp_dev->dvp = &csd->interface.dvp;
634 subdev->host_priv = &dvp_dev->subdev.entity;
636 case CSI2RX_SENSOR_PORT_NUMBER:
637 csiphy_dev->csiphy = &csd->interface.csiphy;
638 subdev->host_priv = &csiphy_dev->subdev.entity;
644 stfcamss_register_mediadevice_subdevnodes(async, subdev);
650 static int stfcamss_subdev_notifier_complete(
651 struct v4l2_async_notifier *async)
653 struct stfcamss *stfcamss =
654 container_of(async, struct stfcamss, notifier);
655 struct v4l2_device *v4l2_dev = &stfcamss->v4l2_dev;
656 struct v4l2_subdev *sd;
659 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
661 struct media_entity *sensor = &sd->entity;
662 struct media_entity *input = sd->host_priv;
665 for (i = 0; i < sensor->num_pads; i++) {
666 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
669 if (i == sensor->num_pads) {
671 "No source pad in external entity\n");
675 ret = media_create_pad_link(sensor, i,
677 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
680 "Failed to link %s->%s entities: %d\n",
681 sensor->name, input->name, ret);
687 ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
691 return media_device_register(&stfcamss->media_dev);
695 static const struct v4l2_async_notifier_operations
696 stfcamss_subdev_notifier_ops = {
697 .bound = stfcamss_subdev_notifier_bound,
700 static const struct media_device_ops stfcamss_media_ops = {
701 .link_notify = v4l2_pipeline_link_notify,
704 #ifdef CONFIG_DEBUG_FS
714 static enum module_id id_num = ISP_MODULE;
716 void dump_clk_reg(void __iomem *reg_base)
720 st_info(ST_CAMSS, "DUMP Clk register:\n");
721 for (i = 0; i <= CLK_C_ISP_CTRL; i += 4)
722 print_reg(ST_CAMSS, reg_base, i);
725 static ssize_t vin_debug_read(struct file *file, char __user *user_buf,
726 size_t count, loff_t *ppos)
728 struct device *dev = file->private_data;
729 void __iomem *reg_base;
730 struct stfcamss *stfcamss = dev_get_drvdata(dev);
731 struct stf_vin_dev *vin = stfcamss->vin;
732 struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
733 struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
734 struct stf_csi_dev *csi0_dev = stfcamss->csi_dev;
740 mutex_lock(&vin_dev->power_lock);
741 if (vin_dev->power_count > 0) {
742 reg_base = vin->sysctrl_base;
743 dump_vin_reg(reg_base);
745 mutex_unlock(&vin_dev->power_lock);
748 mutex_lock(&isp_dev->stream_lock);
749 if (isp_dev->stream_count > 0) {
750 reg_base = vin->isp_base;
751 dump_isp_reg(reg_base);
753 mutex_unlock(&isp_dev->stream_lock);
756 mutex_lock(&csi0_dev->stream_lock);
757 if (csi0_dev->stream_count > 0) {
758 reg_base = vin->csi2rx_base;
759 dump_csi_reg(reg_base);
761 mutex_unlock(&csi0_dev->stream_lock);
764 mutex_lock(&vin_dev->power_lock);
765 if (vin_dev->power_count > 0) {
766 reg_base = vin->clkgen_base;
767 dump_clk_reg(reg_base);
769 mutex_unlock(&vin_dev->power_lock);
778 static void set_reg_val(struct stfcamss *stfcamss, int id, u32 offset, u32 val)
780 struct stf_vin_dev *vin = stfcamss->vin;
781 struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
782 struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
783 struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
784 void __iomem *reg_base;
790 mutex_lock(&vin_dev->power_lock);
791 if (vin_dev->power_count > 0) {
792 reg_base = vin->sysctrl_base;
793 print_reg(ST_VIN, reg_base, offset);
794 reg_write(reg_base, offset, val);
795 print_reg(ST_VIN, reg_base, offset);
797 mutex_unlock(&vin_dev->power_lock);
800 mutex_lock(&isp_dev->stream_lock);
801 if (isp_dev->stream_count > 0) {
802 reg_base = vin->isp_base;
803 print_reg(ST_ISP, reg_base, offset);
804 reg_write(reg_base, offset, val);
805 print_reg(ST_ISP, reg_base, offset);
807 mutex_unlock(&isp_dev->stream_lock);
810 mutex_lock(&csi_dev->stream_lock);
811 if (csi_dev->stream_count > 0) {
812 reg_base = vin->csi2rx_base;
813 print_reg(ST_CSI, reg_base, offset);
814 reg_write(reg_base, offset, val);
815 print_reg(ST_CSI, reg_base, offset);
817 mutex_unlock(&csi_dev->stream_lock);
820 mutex_lock(&vin_dev->power_lock);
821 if (vin_dev->power_count > 0) {
822 reg_base = vin->clkgen_base;
823 print_reg(ST_CAMSS, reg_base, offset);
824 reg_write(reg_base, offset, val);
825 print_reg(ST_CAMSS, reg_base, offset);
827 mutex_unlock(&vin_dev->power_lock);
835 static u32 atoi(const char *s)
841 if ((*s == '0') && (*(s+1) == 'x')) {
857 else if (islower(ch))
871 static ssize_t vin_debug_write(struct file *file, const char __user *user_buf,
872 size_t count, loff_t *ppos)
874 struct device *dev = file->private_data;
875 struct stfcamss *stfcamss = dev_get_drvdata(dev);
879 static const char *delims = " \t\r";
883 buf = memdup_user_nul(user_buf, min_t(size_t, PAGE_SIZE, count));
887 st_debug(ST_CAMSS, "dup buf: %s, len: %lu, count: %lu\n", p, strlen(p), count);
890 line = strsep(&p, "\n");
891 if (!*line || *line == '#')
893 token = strsep(&line, delims);
896 id_num = atoi(token);
897 token = strsep(&line, delims);
900 offset = atoi(token);
901 token = strsep(&line, delims);
906 set_reg_val(stfcamss, id_num, offset, val);
909 st_info(ST_CAMSS, "id_num = %d, offset = 0x%x, 0x%x\n", id_num, offset, val);
913 static const struct file_operations vin_debug_fops = {
915 .read = vin_debug_read,
916 .write = vin_debug_write,
918 #endif /* CONFIG_DEBUG_FS */
921 static int stfcamss_probe(struct platform_device *pdev)
923 struct stfcamss *stfcamss;
924 struct stf_vin_dev *vin;
925 struct device *dev = &pdev->dev;
926 struct of_phandle_args args;
927 int ret = 0, num_subdevs;
929 dev_info(dev, "stfcamss probe enter!\n");
931 stfcamss = devm_kzalloc(dev, sizeof(struct stfcamss), GFP_KERNEL);
935 stfcamss->dvp_dev = devm_kzalloc(dev,
936 sizeof(*stfcamss->dvp_dev), GFP_KERNEL);
937 if (!stfcamss->dvp_dev) {
942 stfcamss->csiphy_dev = devm_kzalloc(dev,
943 sizeof(*stfcamss->csiphy_dev),
945 if (!stfcamss->csiphy_dev) {
950 stfcamss->csi_dev = devm_kzalloc(dev,
951 sizeof(*stfcamss->csi_dev),
953 if (!stfcamss->csi_dev) {
958 stfcamss->isp_dev = devm_kzalloc(dev,
959 sizeof(*stfcamss->isp_dev),
961 if (!stfcamss->isp_dev) {
966 stfcamss->vin_dev = devm_kzalloc(dev,
967 sizeof(*stfcamss->vin_dev),
969 if (!stfcamss->vin_dev) {
974 stfcamss->vin = devm_kzalloc(dev,
975 sizeof(struct stf_vin_dev),
977 if (!stfcamss->vin) {
984 vin->irq = platform_get_irq(pdev, 0);
986 st_err(ST_CAMSS, "Could not get irq\n");
990 vin->isp_irq = platform_get_irq(pdev, 1);
991 if (vin->isp_irq <= 0) {
992 st_err(ST_CAMSS, "Could not get isp irq\n");
996 vin->isp_csi_irq = platform_get_irq(pdev, 2);
997 if (vin->isp_csi_irq <= 0) {
998 st_err(ST_CAMSS, "Could not get isp csi irq\n");
1002 vin->isp_scd_irq = platform_get_irq(pdev, 3);
1003 if (vin->isp_scd_irq <= 0) {
1004 st_err(ST_CAMSS, "Could not get isp scd irq\n");
1008 vin->isp_irq_csiline = platform_get_irq(pdev, 4);
1009 if (vin->isp_irq_csiline <= 0) {
1010 st_err(ST_CAMSS, "Could not get isp irq csiline\n");
1014 stfcamss->nclks = ARRAY_SIZE(stfcamss_clocks);
1015 stfcamss->sys_clk = stfcamss_clocks;
1017 ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
1019 st_err(ST_CAMSS, "Failed to get clk controls\n");
1023 stfcamss->nrsts = ARRAY_SIZE(stfcamss_resets);
1024 stfcamss->sys_rst = stfcamss_resets;
1026 ret = devm_reset_control_bulk_get_exclusive(dev, stfcamss->nrsts,
1029 st_err(ST_CAMSS, "Failed to get reset controls\n");
1033 ret = of_parse_phandle_with_fixed_args(dev->of_node,
1034 "starfive,aon-syscon", 1, 0, &args);
1036 st_err(ST_CAMSS, "Failed to parse starfive,aon-syscon\n");
1040 stfcamss->stf_aon_syscon = syscon_node_to_regmap(args.np);
1041 of_node_put(args.np);
1042 if (IS_ERR(stfcamss->stf_aon_syscon))
1043 return PTR_ERR(stfcamss->stf_aon_syscon);
1045 stfcamss->aon_gp_reg = args.args[0];
1047 ret = stfcamss_get_mem_res(pdev, vin);
1049 st_err(ST_CAMSS, "Could not map registers\n");
1053 ret = vin_parse_dt(dev, vin);
1058 stfcamss->dev = dev;
1059 platform_set_drvdata(pdev, stfcamss);
1061 v4l2_async_notifier_init(&stfcamss->notifier);
1063 num_subdevs = stfcamss_of_parse_ports(stfcamss);
1064 if (num_subdevs < 0) {
1069 ret = stfcamss_init_subdevices(stfcamss);
1071 st_err(ST_CAMSS, "Failed to init subdevice: %d\n", ret);
1075 stfcamss->media_dev.dev = stfcamss->dev;
1076 strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
1077 sizeof(stfcamss->media_dev.model));
1078 strscpy(stfcamss->media_dev.serial, "0123456789ABCDEF",
1079 sizeof(stfcamss->media_dev.serial));
1080 snprintf(stfcamss->media_dev.bus_info, sizeof(stfcamss->media_dev.bus_info),
1081 "%s:%s", dev_bus_name(dev), pdev->name);
1082 stfcamss->media_dev.hw_revision = 0x01;
1083 stfcamss->media_dev.ops = &stfcamss_media_ops;
1084 media_device_init(&stfcamss->media_dev);
1086 stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
1088 ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
1090 st_err(ST_CAMSS, "Failed to register V4L2 device: %d\n", ret);
1091 goto err_cam_noti_med;
1094 ret = stfcamss_register_subdevices(stfcamss);
1096 st_err(ST_CAMSS, "Failed to register subdevice: %d\n", ret);
1097 goto err_cam_noti_med_vreg;
1101 stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
1102 ret = v4l2_async_notifier_register(&stfcamss->v4l2_dev,
1103 &stfcamss->notifier);
1106 "Failed to register async subdev nodes: %d\n",
1108 goto err_cam_noti_med_vreg_sub;
1111 ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
1114 "Failed to register subdev nodes: %d\n",
1116 goto err_cam_noti_med_vreg_sub;
1119 ret = media_device_register(&stfcamss->media_dev);
1121 st_err(ST_CAMSS, "Failed to register media device: %d\n",
1123 goto err_cam_noti_med_vreg_sub_medreg;
1127 #ifdef CONFIG_DEBUG_FS
1128 stfcamss->debugfs_entry = debugfs_create_dir("stfcamss", NULL);
1129 stfcamss->vin_debugfs = debugfs_create_file("stf_vin",
1130 0644, stfcamss->debugfs_entry,
1131 (void *)dev, &vin_debug_fops);
1132 debugfs_create_u32("dbg_level",
1133 0644, stfcamss->debugfs_entry,
1135 debugfs_create_u32("dbg_mask",
1136 0644, stfcamss->debugfs_entry,
1139 dev_info(dev, "stfcamss probe success!\n");
1143 #ifdef CONFIG_DEBUG_FS
1144 debugfs_remove(stfcamss->vin_debugfs);
1145 debugfs_remove_recursive(stfcamss->debugfs_entry);
1146 stfcamss->debugfs_entry = NULL;
1149 err_cam_noti_med_vreg_sub_medreg:
1150 err_cam_noti_med_vreg_sub:
1151 stfcamss_unregister_subdevices(stfcamss);
1152 err_cam_noti_med_vreg:
1153 v4l2_device_unregister(&stfcamss->v4l2_dev);
1155 media_device_cleanup(&stfcamss->media_dev);
1157 v4l2_async_notifier_cleanup(&stfcamss->notifier);
1163 static int stfcamss_remove(struct platform_device *pdev)
1165 struct stfcamss *stfcamss = platform_get_drvdata(pdev);
1167 dev_info(&pdev->dev, "remove done\n");
1169 #ifdef CONFIG_DEBUG_FS
1170 debugfs_remove(stfcamss->vin_debugfs);
1171 debugfs_remove_recursive(stfcamss->debugfs_entry);
1172 stfcamss->debugfs_entry = NULL;
1175 stfcamss_unregister_subdevices(stfcamss);
1176 v4l2_device_unregister(&stfcamss->v4l2_dev);
1177 media_device_cleanup(&stfcamss->media_dev);
1184 static const struct of_device_id stfcamss_of_match[] = {
1185 { .compatible = "starfive,jh7110-vin" },
1189 MODULE_DEVICE_TABLE(of, stfcamss_of_match);
1191 static struct platform_driver stfcamss_driver = {
1192 .probe = stfcamss_probe,
1193 .remove = stfcamss_remove,
1196 .of_match_table = of_match_ptr(stfcamss_of_match),
1200 static int __init stfcamss_init(void)
1202 return platform_driver_register(&stfcamss_driver);
1205 static void __exit stfcamss_cleanup(void)
1207 platform_driver_unregister(&stfcamss_driver);
1210 module_init(stfcamss_init);
1211 //fs_initcall(stfcamss_init);
1212 module_exit(stfcamss_cleanup);
1214 MODULE_LICENSE("GPL");