forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c
....@@ -13,12 +13,12 @@
1313 #include <linux/module.h>
1414 #include <linux/of.h>
1515 #include <linux/of_graph.h>
16
+#include <linux/of_platform.h>
1617 #include <linux/platform_device.h>
1718 #include <linux/reset.h>
1819 #include <linux/rk-camera-module.h>
1920 #include <media/v4l2-ioctl.h>
2021 #include "mipi-csi2.h"
21
-#include <linux/rkcif-config.h>
2222 #include <linux/regulator/consumer.h>
2323
2424 static int csi2_debug;
....@@ -141,53 +141,61 @@
141141 break;
142142 default:
143143 v4l2_warn(&csi2->sd, "lane num is invalid\n");
144
- csi2->bus.num_data_lanes = 0;
144
+ csi2->bus.num_data_lanes = 4;
145145 break;
146146 }
147147
148148 }
149149
150
-static void csi2_hw_do_reset(struct csi2_dev *csi2)
150
+static void csi2_hw_do_reset(struct csi2_hw *csi2_hw)
151151 {
152
- reset_control_assert(csi2->rsts_bulk);
152
+
153
+ if (!csi2_hw->rsts_bulk)
154
+ return;
155
+
156
+ reset_control_assert(csi2_hw->rsts_bulk);
153157
154158 udelay(5);
155159
156
- reset_control_deassert(csi2->rsts_bulk);
160
+ reset_control_deassert(csi2_hw->rsts_bulk);
157161 }
158162
159
-static int csi2_enable_clks(struct csi2_dev *csi2)
163
+static int csi2_enable_clks(struct csi2_hw *csi2_hw)
160164 {
161165 int ret = 0;
162166
163
- ret = clk_bulk_prepare_enable(csi2->clks_num, csi2->clks_bulk);
167
+ if (!csi2_hw->clks_bulk)
168
+ return -EINVAL;
169
+
170
+ ret = clk_bulk_prepare_enable(csi2_hw->clks_num, csi2_hw->clks_bulk);
164171 if (ret)
165
- dev_err(csi2->dev, "failed to enable clks\n");
172
+ dev_err(csi2_hw->dev, "failed to enable clks\n");
166173
167174 return ret;
168175 }
169176
170
-static void csi2_disable_clks(struct csi2_dev *csi2)
177
+static void csi2_disable_clks(struct csi2_hw *csi2_hw)
171178 {
172
- clk_bulk_disable_unprepare(csi2->clks_num, csi2->clks_bulk);
179
+ if (!csi2_hw->clks_bulk)
180
+ return;
181
+ clk_bulk_disable_unprepare(csi2_hw->clks_num, csi2_hw->clks_bulk);
173182 }
174183
175
-static void csi2_disable(struct csi2_dev *csi2)
184
+static void csi2_disable(struct csi2_hw *csi2_hw)
176185 {
177
- void __iomem *base = csi2->base;
178
-
179
- write_csihost_reg(base, CSIHOST_RESETN, 0);
180
- write_csihost_reg(base, CSIHOST_MSK1, 0xffffffff);
181
- write_csihost_reg(base, CSIHOST_MSK2, 0xffffffff);
186
+ write_csihost_reg(csi2_hw->base, CSIHOST_RESETN, 0);
187
+ write_csihost_reg(csi2_hw->base, CSIHOST_MSK1, 0xffffffff);
188
+ write_csihost_reg(csi2_hw->base, CSIHOST_MSK2, 0xffffffff);
182189 }
183190
184191 static int csi2_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
185192 struct v4l2_mbus_config *mbus);
186193
187
-static void csi2_enable(struct csi2_dev *csi2,
194
+static void csi2_enable(struct csi2_hw *csi2_hw,
188195 enum host_type_t host_type)
189196 {
190
- void __iomem *base = csi2->base;
197
+ void __iomem *base = csi2_hw->base;
198
+ struct csi2_dev *csi2 = csi2_hw->csi2;
191199 int lanes = csi2->bus.num_data_lanes;
192200 struct v4l2_mbus_config mbus;
193201 u32 val = 0;
....@@ -225,15 +233,9 @@
225233 {
226234 enum host_type_t host_type;
227235 int ret, i;
236
+ int csi_idx = 0;
228237
229238 atomic_set(&csi2->frm_sync_seq, 0);
230
-
231
- csi2_hw_do_reset(csi2);
232
- ret = csi2_enable_clks(csi2);
233
- if (ret) {
234
- v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__);
235
- return ret;
236
- }
237239
238240 csi2_update_sensor_info(csi2);
239241
....@@ -242,7 +244,18 @@
242244 else
243245 host_type = RK_CSI_RXHOST;
244246
245
- csi2_enable(csi2, host_type);
247
+ for (i = 0; i < csi2->csi_info.csi_num; i++) {
248
+ csi_idx = csi2->csi_info.csi_idx[i];
249
+ csi2_hw_do_reset(csi2->csi2_hw[csi_idx]);
250
+ ret = csi2_enable_clks(csi2->csi2_hw[csi_idx]);
251
+ if (ret) {
252
+ v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__);
253
+ return ret;
254
+ }
255
+ enable_irq(csi2->csi2_hw[csi_idx]->irq1);
256
+ enable_irq(csi2->csi2_hw[csi_idx]->irq2);
257
+ csi2_enable(csi2->csi2_hw[csi_idx], host_type);
258
+ }
246259
247260 pr_debug("stream sd: %s\n", csi2->src_sd->name);
248261 ret = v4l2_subdev_call(csi2->src_sd, video, s_stream, 1);
....@@ -256,20 +269,33 @@
256269 return 0;
257270
258271 err_assert_reset:
259
- csi2_disable(csi2);
260
- csi2_disable_clks(csi2);
272
+ for (i = 0; i < csi2->csi_info.csi_num; i++) {
273
+ csi_idx = csi2->csi_info.csi_idx[i];
274
+ disable_irq(csi2->csi2_hw[csi_idx]->irq1);
275
+ disable_irq(csi2->csi2_hw[csi_idx]->irq2);
276
+ csi2_disable(csi2->csi2_hw[csi_idx]);
277
+ csi2_disable_clks(csi2->csi2_hw[csi_idx]);
278
+ }
261279
262280 return ret;
263281 }
264282
265283 static void csi2_stop(struct csi2_dev *csi2)
266284 {
285
+ int i = 0;
286
+ int csi_idx = 0;
287
+
267288 /* stop upstream */
268289 v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
269290
270
- csi2_disable(csi2);
271
- csi2_hw_do_reset(csi2);
272
- csi2_disable_clks(csi2);
291
+ for (i = 0; i < csi2->csi_info.csi_num; i++) {
292
+ csi_idx = csi2->csi_info.csi_idx[i];
293
+ disable_irq(csi2->csi2_hw[csi_idx]->irq1);
294
+ disable_irq(csi2->csi2_hw[csi_idx]->irq2);
295
+ csi2_disable(csi2->csi2_hw[csi_idx]);
296
+ csi2_hw_do_reset(csi2->csi2_hw[csi_idx]);
297
+ csi2_disable_clks(csi2->csi2_hw[csi_idx]);
298
+ }
273299 }
274300
275301 /*
....@@ -379,7 +405,7 @@
379405 csi2->crop.left = 0;
380406 csi2->crop.width = RKCIF_DEFAULT_WIDTH;
381407 csi2->crop.height = RKCIF_DEFAULT_HEIGHT;
382
- csi2->csi_idx = 0;
408
+ csi2->bus.num_data_lanes = 4;
383409
384410 return media_entity_pads_init(&sd->entity, num_pads, csi2->pad);
385411 }
....@@ -567,11 +593,19 @@
567593 static long rkcif_csi2_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
568594 {
569595 struct csi2_dev *csi2 = sd_to_dev(sd);
596
+ struct v4l2_subdev *sensor = get_remote_sensor(sd);
570597 long ret = 0;
598
+ int i = 0;
571599
572600 switch (cmd) {
573601 case RKCIF_CMD_SET_CSI_IDX:
574
- csi2->csi_idx = *((u32 *)arg);
602
+ csi2->csi_info = *((struct rkcif_csi_info *)arg);
603
+ for (i = 0; i < csi2->csi_info.csi_num; i++)
604
+ csi2->csi2_hw[csi2->csi_info.csi_idx[i]]->csi2 = csi2;
605
+ if (csi2->match_data->chip_id > CHIP_RV1126_CSI2)
606
+ ret = v4l2_subdev_call(sensor, core, ioctl,
607
+ RKCIF_CMD_SET_CSI_IDX,
608
+ arg);
575609 break;
576610 default:
577611 ret = -ENOIOCTLCMD;
....@@ -586,15 +620,15 @@
586620 unsigned int cmd, unsigned long arg)
587621 {
588622 void __user *up = compat_ptr(arg);
589
- u32 csi_idx = 0;
623
+ struct rkcif_csi_info csi_info;
590624 long ret;
591625
592626 switch (cmd) {
593627 case RKCIF_CMD_SET_CSI_IDX:
594
- if (copy_from_user(&csi_idx, up, sizeof(u32)))
628
+ if (copy_from_user(&csi_info, up, sizeof(struct rkcif_csi_info)))
595629 return -EFAULT;
596630
597
- ret = rkcif_csi2_ioctl(sd, cmd, &csi_idx);
631
+ ret = rkcif_csi2_ioctl(sd, cmd, &csi_info);
598632 break;
599633 default:
600634 ret = -ENOIOCTLCMD;
....@@ -637,15 +671,10 @@
637671 struct v4l2_fwnode_endpoint *vep,
638672 struct v4l2_async_subdev *asd)
639673 {
640
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
641
- struct csi2_dev *csi2 = sd_to_dev(sd);
642
-
643674 if (vep->base.port != 0) {
644675 dev_err(dev, "The csi host node needs to parse port 0\n");
645676 return -EINVAL;
646677 }
647
-
648
- csi2->bus = vep->bus.mipi_csi2;
649678
650679 return 0;
651680 }
....@@ -749,7 +778,8 @@
749778 static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
750779 {
751780 struct device *dev = ctx;
752
- struct csi2_dev *csi2 = sd_to_dev(dev_get_drvdata(dev));
781
+ struct csi2_hw *csi2_hw = dev_get_drvdata(dev);
782
+ struct csi2_dev *csi2 = NULL;
753783 struct csi2_err_stats *err_list = NULL;
754784 unsigned long err_stat = 0;
755785 u32 val;
....@@ -758,7 +788,17 @@
758788 char vc_info[CSI_VCINFO_LEN] = {0};
759789 bool is_add_cnt = false;
760790
761
- val = read_csihost_reg(csi2->base, CSIHOST_ERR1);
791
+ if (!csi2_hw) {
792
+ disable_irq_nosync(irq);
793
+ return IRQ_HANDLED;
794
+ }
795
+
796
+ csi2 = csi2_hw->csi2;
797
+ if (!csi2) {
798
+ disable_irq_nosync(irq);
799
+ return IRQ_HANDLED;
800
+ }
801
+ val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR1);
762802 if (val) {
763803 if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
764804 err_list = &csi2->err_list[RK_CSI2_ERR_SOTSYN];
....@@ -767,7 +807,7 @@
767807 if (err_list->cnt > 3 &&
768808 csi2->err_list[RK_CSI2_ERR_ALL].cnt <= err_list->cnt) {
769809 csi2->is_check_sot_sync = false;
770
- write_csihost_reg(csi2->base, CSIHOST_MSK1, 0xf);
810
+ write_csihost_reg(csi2_hw->base, CSIHOST_MSK1, 0xf);
771811 }
772812 if (csi2->is_check_sot_sync) {
773813 csi2_find_err_vc(val & 0xf, vc_info);
....@@ -832,7 +872,7 @@
832872 csi2_err_strncat(err_str, cur_str);
833873 }
834874
835
- pr_err("%s ERR1:0x%x %s\n", csi2->dev_name, val, err_str);
875
+ pr_err("%s ERR1:0x%x %s\n", csi2_hw->dev_name, val, err_str);
836876
837877 if (is_add_cnt) {
838878 csi2->err_list[RK_CSI2_ERR_ALL].cnt++;
....@@ -841,7 +881,7 @@
841881
842882 atomic_notifier_call_chain(&g_csi_host_chain,
843883 err_stat,
844
- &csi2->csi_idx);
884
+ &csi2->csi_info.csi_idx[csi2->csi_info.csi_num - 1]);
845885 }
846886
847887 }
....@@ -852,13 +892,18 @@
852892 static irqreturn_t rk_csirx_irq2_handler(int irq, void *ctx)
853893 {
854894 struct device *dev = ctx;
855
- struct csi2_dev *csi2 = sd_to_dev(dev_get_drvdata(dev));
895
+ struct csi2_hw *csi2_hw = dev_get_drvdata(dev);
856896 u32 val;
857897 char cur_str[CSI_ERRSTR_LEN] = {0};
858898 char err_str[CSI_ERRSTR_LEN] = {0};
859899 char vc_info[CSI_VCINFO_LEN] = {0};
860900
861
- val = read_csihost_reg(csi2->base, CSIHOST_ERR2);
901
+ if (!csi2_hw) {
902
+ disable_irq_nosync(irq);
903
+ return IRQ_HANDLED;
904
+ }
905
+
906
+ val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR2);
862907 if (val) {
863908 if (val & CSIHOST_ERR2_PHYERR_ESC) {
864909 csi2_find_err_vc(val & 0xf, vc_info);
....@@ -885,7 +930,7 @@
885930 csi2_err_strncat(err_str, cur_str);
886931 }
887932
888
- pr_err("%s ERR2:0x%x %s\n", csi2->dev_name, val, err_str);
933
+ pr_err("%s ERR2:0x%x %s\n", csi2_hw->dev_name, val, err_str);
889934 }
890935
891936 return IRQ_HANDLED;
....@@ -924,31 +969,43 @@
924969 static const struct csi2_match_data rk1808_csi2_match_data = {
925970 .chip_id = CHIP_RK1808_CSI2,
926971 .num_pads = CSI2_NUM_PADS,
972
+ .num_hw = 1,
927973 };
928974
929975 static const struct csi2_match_data rk3288_csi2_match_data = {
930976 .chip_id = CHIP_RK3288_CSI2,
931977 .num_pads = CSI2_NUM_PADS_SINGLE_LINK,
978
+ .num_hw = 1,
932979 };
933980
934981 static const struct csi2_match_data rv1126_csi2_match_data = {
935982 .chip_id = CHIP_RV1126_CSI2,
936983 .num_pads = CSI2_NUM_PADS,
984
+ .num_hw = 1,
937985 };
938986
939987 static const struct csi2_match_data rk3568_csi2_match_data = {
940988 .chip_id = CHIP_RK3568_CSI2,
941989 .num_pads = CSI2_NUM_PADS,
990
+ .num_hw = 1,
942991 };
943992
944993 static const struct csi2_match_data rk3588_csi2_match_data = {
945994 .chip_id = CHIP_RK3588_CSI2,
946995 .num_pads = CSI2_NUM_PADS_MAX,
996
+ .num_hw = 6,
997
+};
998
+
999
+static const struct csi2_match_data rv1106_csi2_match_data = {
1000
+ .chip_id = CHIP_RV1106_CSI2,
1001
+ .num_pads = CSI2_NUM_PADS_MAX,
1002
+ .num_hw = 2,
9471003 };
9481004
9491005 static const struct csi2_match_data rk3562_csi2_match_data = {
9501006 .chip_id = CHIP_RK3562_CSI2,
9511007 .num_pads = CSI2_NUM_PADS_MAX,
1008
+ .num_hw = 4,
9521009 };
9531010
9541011 static const struct of_device_id csi2_dt_ids[] = {
....@@ -973,6 +1030,10 @@
9731030 .data = &rk3588_csi2_match_data,
9741031 },
9751032 {
1033
+ .compatible = "rockchip,rv1106-mipi-csi2",
1034
+ .data = &rv1106_csi2_match_data,
1035
+ },
1036
+ {
9761037 .compatible = "rockchip,rk3562-mipi-csi2",
9771038 .data = &rk3562_csi2_match_data,
9781039 },
....@@ -980,15 +1041,48 @@
9801041 };
9811042 MODULE_DEVICE_TABLE(of, csi2_dt_ids);
9821043
1044
+static int csi2_attach_hw(struct csi2_dev *csi2)
1045
+{
1046
+ struct device_node *np;
1047
+ struct platform_device *pdev;
1048
+ struct csi2_hw *hw;
1049
+ int i = 0;
1050
+
1051
+ for (i = 0; i < csi2->match_data->num_hw; i++) {
1052
+ np = of_parse_phandle(csi2->dev->of_node, "rockchip,hw", i);
1053
+ if (!np || !of_device_is_available(np)) {
1054
+ dev_err(csi2->dev, "failed to get csi2 hw node\n");
1055
+ return -ENODEV;
1056
+ }
1057
+
1058
+ pdev = of_find_device_by_node(np);
1059
+ of_node_put(np);
1060
+ if (!pdev) {
1061
+ dev_err(csi2->dev, "failed to get csi2 hw from node\n");
1062
+ return -ENODEV;
1063
+ }
1064
+
1065
+ hw = platform_get_drvdata(pdev);
1066
+ if (!hw) {
1067
+ dev_err(csi2->dev, "failed attach csi2 hw\n");
1068
+ return -EINVAL;
1069
+ }
1070
+
1071
+ hw->csi2 = csi2;
1072
+ csi2->csi2_hw[i] = hw;
1073
+ }
1074
+ dev_info(csi2->dev, "attach to csi2 hw node\n");
1075
+
1076
+ return 0;
1077
+}
1078
+
9831079 static int csi2_probe(struct platform_device *pdev)
9841080 {
9851081 const struct of_device_id *match;
986
- struct device *dev = &pdev->dev;
9871082 struct device_node *node = pdev->dev.of_node;
9881083 struct csi2_dev *csi2 = NULL;
989
- struct resource *res;
9901084 const struct csi2_match_data *data;
991
- int ret, irq;
1085
+ int ret;
9921086
9931087 match = of_match_node(csi2_dt_ids, node);
9941088 if (IS_ERR(match))
....@@ -1014,63 +1108,11 @@
10141108 v4l2_err(&csi2->sd, "failed to copy name\n");
10151109 platform_set_drvdata(pdev, &csi2->sd);
10161110
1017
- csi2->clks_num = devm_clk_bulk_get_all(dev, &csi2->clks_bulk);
1018
- if (csi2->clks_num < 0) {
1019
- csi2->clks_num = 0;
1020
- dev_err(dev, "failed to get csi2 clks\n");
1111
+ ret = csi2_attach_hw(csi2);
1112
+ if (ret) {
1113
+ v4l2_err(&csi2->sd, "must enable all mipi csi2 hw node\n");
1114
+ return -EINVAL;
10211115 }
1022
-
1023
- csi2->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
1024
- if (IS_ERR(csi2->rsts_bulk)) {
1025
- if (PTR_ERR(csi2->rsts_bulk) != -EPROBE_DEFER)
1026
- dev_err(dev, "failed to get csi2 reset\n");
1027
- csi2->rsts_bulk = NULL;
1028
- }
1029
-
1030
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1031
- csi2->base = devm_ioremap_resource(&pdev->dev, res);
1032
- if (IS_ERR(csi2->base)) {
1033
- resource_size_t offset = res->start;
1034
- resource_size_t size = resource_size(res);
1035
-
1036
- dev_warn(&pdev->dev, "avoid secondary mipi resource check!\n");
1037
-
1038
- csi2->base = devm_ioremap(&pdev->dev, offset, size);
1039
- if (IS_ERR(csi2->base)) {
1040
- dev_err(&pdev->dev, "Failed to ioremap resource\n");
1041
-
1042
- return PTR_ERR(csi2->base);
1043
- }
1044
- }
1045
-
1046
- irq = platform_get_irq_byname(pdev, "csi-intr1");
1047
- if (irq > 0) {
1048
- ret = devm_request_irq(&pdev->dev, irq,
1049
- rk_csirx_irq1_handler, 0,
1050
- dev_driver_string(&pdev->dev),
1051
- &pdev->dev);
1052
- if (ret < 0)
1053
- v4l2_err(&csi2->sd, "request csi-intr1 irq failed: %d\n",
1054
- ret);
1055
- csi2->irq1 = irq;
1056
- } else {
1057
- v4l2_err(&csi2->sd, "No found irq csi-intr1\n");
1058
- }
1059
-
1060
- irq = platform_get_irq_byname(pdev, "csi-intr2");
1061
- if (irq > 0) {
1062
- ret = devm_request_irq(&pdev->dev, irq,
1063
- rk_csirx_irq2_handler, 0,
1064
- dev_driver_string(&pdev->dev),
1065
- &pdev->dev);
1066
- if (ret < 0)
1067
- v4l2_err(&csi2->sd, "request csi-intr2 failed: %d\n",
1068
- ret);
1069
- csi2->irq2 = irq;
1070
- } else {
1071
- v4l2_err(&csi2->sd, "No found irq csi-intr2\n");
1072
- }
1073
-
10741116 mutex_init(&csi2->lock);
10751117
10761118 ret = csi2_media_init(&csi2->sd);
....@@ -1115,11 +1157,185 @@
11151157 return platform_driver_register(&csi2_driver);
11161158 }
11171159
1118
-void __exit rkcif_csi2_plat_drv_exit(void)
1160
+void rkcif_csi2_plat_drv_exit(void)
11191161 {
11201162 platform_driver_unregister(&csi2_driver);
11211163 }
11221164
1165
+static const struct csi2_hw_match_data rk1808_csi2_hw_match_data = {
1166
+ .chip_id = CHIP_RK1808_CSI2,
1167
+};
1168
+
1169
+static const struct csi2_hw_match_data rk3288_csi2_hw_match_data = {
1170
+ .chip_id = CHIP_RK3288_CSI2,
1171
+};
1172
+
1173
+static const struct csi2_hw_match_data rv1126_csi2_hw_match_data = {
1174
+ .chip_id = CHIP_RV1126_CSI2,
1175
+};
1176
+
1177
+static const struct csi2_hw_match_data rk3568_csi2_hw_match_data = {
1178
+ .chip_id = CHIP_RK3568_CSI2,
1179
+};
1180
+
1181
+static const struct csi2_hw_match_data rk3588_csi2_hw_match_data = {
1182
+ .chip_id = CHIP_RK3588_CSI2,
1183
+};
1184
+
1185
+static const struct csi2_hw_match_data rv1106_csi2_hw_match_data = {
1186
+ .chip_id = CHIP_RV1106_CSI2,
1187
+};
1188
+
1189
+static const struct csi2_hw_match_data rk3562_csi2_hw_match_data = {
1190
+ .chip_id = CHIP_RK3562_CSI2,
1191
+};
1192
+
1193
+static const struct of_device_id csi2_hw_ids[] = {
1194
+ {
1195
+ .compatible = "rockchip,rk1808-mipi-csi2-hw",
1196
+ .data = &rk1808_csi2_hw_match_data,
1197
+ },
1198
+ {
1199
+ .compatible = "rockchip,rk3288-mipi-csi2-hw",
1200
+ .data = &rk3288_csi2_hw_match_data,
1201
+ },
1202
+ {
1203
+ .compatible = "rockchip,rk3568-mipi-csi2-hw",
1204
+ .data = &rk3568_csi2_hw_match_data,
1205
+ },
1206
+ {
1207
+ .compatible = "rockchip,rv1126-mipi-csi2-hw",
1208
+ .data = &rv1126_csi2_hw_match_data,
1209
+ },
1210
+ {
1211
+ .compatible = "rockchip,rk3588-mipi-csi2-hw",
1212
+ .data = &rk3588_csi2_hw_match_data,
1213
+ },
1214
+ {
1215
+ .compatible = "rockchip,rv1106-mipi-csi2-hw",
1216
+ .data = &rv1106_csi2_hw_match_data,
1217
+ },
1218
+ {
1219
+ .compatible = "rockchip,rk3562-mipi-csi2-hw",
1220
+ .data = &rk3588_csi2_hw_match_data,
1221
+ },
1222
+ { /* sentinel */ }
1223
+};
1224
+MODULE_DEVICE_TABLE(of, csi2_hw_ids);
1225
+
1226
+static int csi2_hw_probe(struct platform_device *pdev)
1227
+{
1228
+ const struct of_device_id *match;
1229
+ struct device *dev = &pdev->dev;
1230
+ struct device_node *node = pdev->dev.of_node;
1231
+ struct csi2_hw *csi2_hw = NULL;
1232
+ struct resource *res;
1233
+ const struct csi2_hw_match_data *data;
1234
+ int ret, irq;
1235
+
1236
+ dev_info(&pdev->dev, "enter mipi csi2 hw probe!\n");
1237
+ match = of_match_node(csi2_hw_ids, node);
1238
+ if (IS_ERR(match))
1239
+ return PTR_ERR(match);
1240
+ data = match->data;
1241
+
1242
+ csi2_hw = devm_kzalloc(&pdev->dev, sizeof(*csi2_hw), GFP_KERNEL);
1243
+ if (!csi2_hw)
1244
+ return -ENOMEM;
1245
+
1246
+ csi2_hw->dev = &pdev->dev;
1247
+ csi2_hw->match_data = data;
1248
+
1249
+ csi2_hw->dev_name = node->name;
1250
+
1251
+ csi2_hw->clks_num = devm_clk_bulk_get_all(dev, &csi2_hw->clks_bulk);
1252
+ if (csi2_hw->clks_num < 0) {
1253
+ csi2_hw->clks_num = 0;
1254
+ dev_err(dev, "failed to get csi2 clks\n");
1255
+ }
1256
+
1257
+ csi2_hw->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
1258
+ if (IS_ERR(csi2_hw->rsts_bulk)) {
1259
+ if (PTR_ERR(csi2_hw->rsts_bulk) != -EPROBE_DEFER)
1260
+ dev_err(dev, "failed to get csi2 reset\n");
1261
+ csi2_hw->rsts_bulk = NULL;
1262
+ }
1263
+
1264
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1265
+ csi2_hw->base = devm_ioremap_resource(&pdev->dev, res);
1266
+ if (IS_ERR(csi2_hw->base)) {
1267
+ resource_size_t offset = res->start;
1268
+ resource_size_t size = resource_size(res);
1269
+
1270
+ dev_warn(&pdev->dev, "avoid secondary mipi resource check!\n");
1271
+
1272
+ csi2_hw->base = devm_ioremap(&pdev->dev, offset, size);
1273
+ if (IS_ERR(csi2_hw->base)) {
1274
+ dev_err(&pdev->dev, "Failed to ioremap resource\n");
1275
+
1276
+ return PTR_ERR(csi2_hw->base);
1277
+ }
1278
+ }
1279
+
1280
+ irq = platform_get_irq_byname(pdev, "csi-intr1");
1281
+ if (irq > 0) {
1282
+ irq_set_status_flags(irq, IRQ_NOAUTOEN);
1283
+ ret = devm_request_irq(&pdev->dev, irq,
1284
+ rk_csirx_irq1_handler, 0,
1285
+ dev_driver_string(&pdev->dev),
1286
+ &pdev->dev);
1287
+ if (ret < 0)
1288
+ dev_err(&pdev->dev, "request csi-intr1 irq failed: %d\n",
1289
+ ret);
1290
+ csi2_hw->irq1 = irq;
1291
+ } else {
1292
+ dev_err(&pdev->dev, "No found irq csi-intr1\n");
1293
+ }
1294
+
1295
+ irq = platform_get_irq_byname(pdev, "csi-intr2");
1296
+ if (irq > 0) {
1297
+ irq_set_status_flags(irq, IRQ_NOAUTOEN);
1298
+ ret = devm_request_irq(&pdev->dev, irq,
1299
+ rk_csirx_irq2_handler, 0,
1300
+ dev_driver_string(&pdev->dev),
1301
+ &pdev->dev);
1302
+ if (ret < 0)
1303
+ dev_err(&pdev->dev, "request csi-intr2 failed: %d\n",
1304
+ ret);
1305
+ csi2_hw->irq2 = irq;
1306
+ } else {
1307
+ dev_err(&pdev->dev, "No found irq csi-intr2\n");
1308
+ }
1309
+ platform_set_drvdata(pdev, csi2_hw);
1310
+ dev_info(&pdev->dev, "probe success, v4l2_dev:%s!\n", csi2_hw->dev_name);
1311
+
1312
+ return 0;
1313
+}
1314
+
1315
+static int csi2_hw_remove(struct platform_device *pdev)
1316
+{
1317
+ return 0;
1318
+}
1319
+
1320
+static struct platform_driver csi2_hw_driver = {
1321
+ .driver = {
1322
+ .name = DEVICE_NAME_HW,
1323
+ .of_match_table = csi2_hw_ids,
1324
+ },
1325
+ .probe = csi2_hw_probe,
1326
+ .remove = csi2_hw_remove,
1327
+};
1328
+
1329
+int rkcif_csi2_hw_plat_drv_init(void)
1330
+{
1331
+ return platform_driver_register(&csi2_hw_driver);
1332
+}
1333
+
1334
+void rkcif_csi2_hw_plat_drv_exit(void)
1335
+{
1336
+ platform_driver_unregister(&csi2_hw_driver);
1337
+}
1338
+
11231339 MODULE_DESCRIPTION("Rockchip MIPI CSI2 driver");
11241340 MODULE_AUTHOR("Macrofly.xu <xuhf@rock-chips.com>");
11251341 MODULE_LICENSE("GPL");