forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/media/platform/rockchip/cif/mipi-csi2.c
....@@ -13,159 +13,21 @@
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>
18
-#include <media/v4l2-device.h>
19
-#include <media/v4l2-fwnode.h>
20
-#include <media/v4l2-subdev.h>
21
-#include <media/v4l2-event.h>
2219 #include <linux/rk-camera-module.h>
2320 #include <media/v4l2-ioctl.h>
2421 #include "mipi-csi2.h"
22
+#include <linux/regulator/consumer.h>
2523
2624 static int csi2_debug;
2725 module_param_named(debug_csi2, csi2_debug, int, 0644);
2826 MODULE_PARM_DESC(debug_csi2, "Debug level (0-1)");
2927
30
-/*
31
- * there must be 5 pads: 1 input pad from sensor, and
32
- * the 4 virtual channel output pads
33
- */
34
-#define CSI2_SINK_PAD 0
35
-#define CSI2_NUM_SINK_PADS 1
36
-#define CSI2_NUM_SRC_PADS 4
37
-#define CSI2_NUM_PADS 5
38
-#define CSI2_NUM_PADS_SINGLE_LINK 2
39
-#define MAX_CSI2_SENSORS 2
40
-
41
-#define RKCIF_DEFAULT_WIDTH 640
42
-#define RKCIF_DEFAULT_HEIGHT 480
43
-
44
-/*
45
- * The default maximum bit-rate per lane in Mbps, if the
46
- * source subdev does not provide V4L2_CID_LINK_FREQ.
47
- */
48
-#define CSI2_DEFAULT_MAX_MBPS 849
49
-
50
-#define IMX_MEDIA_GRP_ID_CSI2 BIT(8)
51
-#define CSIHOST_MAX_ERRINT_COUNT 10
52
-
53
-/*
54
- * add new chip id in tail in time order
55
- * by increasing to distinguish csi2 host version
56
- */
57
-enum rkcsi2_chip_id {
58
- CHIP_PX30_CSI2,
59
- CHIP_RK1808_CSI2,
60
- CHIP_RK3128_CSI2,
61
- CHIP_RK3288_CSI2,
62
- CHIP_RV1126_CSI2,
63
- CHIP_RK3568_CSI2,
64
-};
65
-
66
-enum csi2_pads {
67
- RK_CSI2_PAD_SINK = 0,
68
- RK_CSI2X_PAD_SOURCE0,
69
- RK_CSI2X_PAD_SOURCE1,
70
- RK_CSI2X_PAD_SOURCE2,
71
- RK_CSI2X_PAD_SOURCE3
72
-};
73
-
74
-enum csi2_err {
75
- RK_CSI2_ERR_SOTSYN = 0x0,
76
- RK_CSI2_ERR_FS_FE_MIS,
77
- RK_CSI2_ERR_FRM_SEQ_ERR,
78
- RK_CSI2_ERR_CRC_ONCE,
79
- RK_CSI2_ERR_CRC,
80
- RK_CSI2_ERR_ALL,
81
- RK_CSI2_ERR_MAX
82
-};
83
-
84
-enum host_type_t {
85
- RK_CSI_RXHOST,
86
- RK_DSI_RXHOST
87
-};
88
-
89
-struct csi2_match_data {
90
- int chip_id;
91
- int num_pads;
92
-};
93
-
94
-struct csi2_sensor {
95
- struct v4l2_subdev *sd;
96
- struct v4l2_mbus_config mbus;
97
- int lanes;
98
-};
99
-
100
-struct csi2_err_stats {
101
- unsigned int cnt;
102
-};
103
-
104
-struct csi2_dev {
105
- struct device *dev;
106
- struct v4l2_subdev sd;
107
- struct media_pad pad[CSI2_NUM_PADS];
108
- struct clk_bulk_data *clks_bulk;
109
- int clks_num;
110
- struct reset_control *rsts_bulk;
111
-
112
- void __iomem *base;
113
- struct v4l2_async_notifier notifier;
114
- struct v4l2_fwnode_bus_mipi_csi2 bus;
115
-
116
- /* lock to protect all members below */
117
- struct mutex lock;
118
-
119
- struct v4l2_mbus_framefmt format_mbus;
120
- struct v4l2_rect crop;
121
- int stream_count;
122
- struct v4l2_subdev *src_sd;
123
- bool sink_linked[CSI2_NUM_SRC_PADS];
124
- struct csi2_sensor sensors[MAX_CSI2_SENSORS];
125
- const struct csi2_match_data *match_data;
126
- int num_sensors;
127
- atomic_t frm_sync_seq;
128
- struct csi2_err_stats err_list[RK_CSI2_ERR_MAX];
129
- int dsi_input_en;
130
-};
131
-
132
-#define DEVICE_NAME "rockchip-mipi-csi2"
133
-
134
-/* CSI Host Registers Define */
135
-#define CSIHOST_N_LANES 0x04
136
-#define CSIHOST_DPHY_SHUTDOWNZ 0x08
137
-#define CSIHOST_PHY_RSTZ 0x0c
138
-#define CSIHOST_RESETN 0x10
139
-#define CSIHOST_PHY_STATE 0x14
140
-#define CSIHOST_ERR1 0x20
141
-#define CSIHOST_ERR2 0x24
142
-#define CSIHOST_MSK1 0x28
143
-#define CSIHOST_MSK2 0x2c
144
-#define CSIHOST_CONTROL 0x40
145
-
146
-#define CSIHOST_ERR1_PHYERR_SPTSYNCHS 0x0000000f
147
-#define CSIHOST_ERR1_ERR_BNDRY_MATCH 0x000000f0
148
-#define CSIHOST_ERR1_ERR_SEQ 0x00000f00
149
-#define CSIHOST_ERR1_ERR_FRM_DATA 0x0000f000
150
-#define CSIHOST_ERR1_ERR_CRC 0x1f000000
151
-
152
-#define CSIHOST_ERR2_PHYERR_ESC 0x0000000f
153
-#define CSIHOST_ERR2_PHYERR_SOTHS 0x000000f0
154
-#define CSIHOST_ERR2_ECC_CORRECTED 0x00000f00
155
-#define CSIHOST_ERR2_ERR_ID 0x0000f000
156
-#define CSIHOST_ERR2_PHYERR_CODEHS 0x01000000
157
-
158
-#define SW_CPHY_EN(x) ((x) << 0)
159
-#define SW_DSI_EN(x) ((x) << 4)
160
-#define SW_DATATYPE_FS(x) ((x) << 8)
161
-#define SW_DATATYPE_FE(x) ((x) << 14)
162
-#define SW_DATATYPE_LS(x) ((x) << 20)
163
-#define SW_DATATYPE_LE(x) ((x) << 26)
164
-
16528 #define write_csihost_reg(base, addr, val) writel(val, (addr) + (base))
16629 #define read_csihost_reg(base, addr) readl((addr) + (base))
16730
168
-static struct csi2_dev *g_csi2_dev;
16931 static ATOMIC_NOTIFIER_HEAD(g_csi_host_chain);
17032
17133 int rkcif_csi2_register_notifier(struct notifier_block *nb)
....@@ -183,7 +45,7 @@
18345 return container_of(sdev, struct csi2_dev, sd);
18446 }
18547
186
-static struct csi2_sensor *sd_to_sensor(struct csi2_dev *csi2,
48
+static struct csi2_sensor_info *sd_to_sensor(struct csi2_dev *csi2,
18749 struct v4l2_subdev *sd)
18850 {
18951 int i;
....@@ -227,6 +89,7 @@
22789 *sensor_sd = NULL;
22890 return;
22991 }
92
+
23093 media_graph_walk_start(&graph, entity);
23194 while ((entity = media_graph_walk_next(&graph))) {
23295 if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
....@@ -234,6 +97,7 @@
23497 }
23598 mutex_unlock(&mdev->graph_mutex);
23699 media_graph_walk_cleanup(&graph);
100
+
237101 if (entity)
238102 *sensor_sd = media_entity_to_v4l2_subdev(entity);
239103 else
....@@ -242,24 +106,25 @@
242106
243107 static void csi2_update_sensor_info(struct csi2_dev *csi2)
244108 {
245
- struct csi2_sensor *sensor = &csi2->sensors[0];
246109 struct v4l2_subdev *terminal_sensor_sd = NULL;
110
+ struct csi2_sensor_info *sensor = &csi2->sensors[0];
247111 struct v4l2_mbus_config mbus;
248112 int ret = 0;
249113
250
- ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config, &mbus);
114
+ ret = v4l2_subdev_call(sensor->sd, pad, get_mbus_config, 0, &mbus);
251115 if (ret) {
252116 v4l2_err(&csi2->sd, "update sensor info failed!\n");
253117 return;
254118 }
255119
256120 get_remote_terminal_sensor(&csi2->sd, &terminal_sensor_sd);
257
- if (terminal_sensor_sd) {
258
- ret = v4l2_subdev_call(terminal_sensor_sd, core, ioctl,
259
- RKMODULE_GET_CSI_DSI_INFO, &csi2->dsi_input_en);
260
- if (ret)
261
- csi2->dsi_input_en = 0;
121
+ ret = v4l2_subdev_call(terminal_sensor_sd, core, ioctl,
122
+ RKMODULE_GET_CSI_DSI_INFO, &csi2->dsi_input_en);
123
+ if (ret) {
124
+ v4l2_dbg(1, csi2_debug, &csi2->sd, "get CSI/DSI sel failed, default csi!\n");
125
+ csi2->dsi_input_en = 0;
262126 }
127
+
263128 csi2->bus.flags = mbus.flags;
264129 switch (csi2->bus.flags & V4L2_MBUS_CSI2_LANES) {
265130 case V4L2_MBUS_CSI2_1_LANE:
....@@ -276,67 +141,89 @@
276141 break;
277142 default:
278143 v4l2_warn(&csi2->sd, "lane num is invalid\n");
279
- csi2->bus.num_data_lanes = 0;
144
+ csi2->bus.num_data_lanes = 4;
280145 break;
281146 }
282147
283148 }
284149
285
-static void csi2_hw_do_reset(struct csi2_dev *csi2)
150
+static void csi2_hw_do_reset(struct csi2_hw *csi2_hw)
286151 {
287
- reset_control_assert(csi2->rsts_bulk);
152
+
153
+ if (!csi2_hw->rsts_bulk)
154
+ return;
155
+
156
+ reset_control_assert(csi2_hw->rsts_bulk);
288157
289158 udelay(5);
290159
291
- reset_control_deassert(csi2->rsts_bulk);
160
+ reset_control_deassert(csi2_hw->rsts_bulk);
292161 }
293162
294
-static int csi2_enable_clks(struct csi2_dev *csi2)
163
+static int csi2_enable_clks(struct csi2_hw *csi2_hw)
295164 {
296165 int ret = 0;
297166
298
- 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);
299171 if (ret)
300
- dev_err(csi2->dev, "failed to enable clks\n");
172
+ dev_err(csi2_hw->dev, "failed to enable clks\n");
301173
302174 return ret;
303175 }
304176
305
-static void csi2_disable_clks(struct csi2_dev *csi2)
177
+static void csi2_disable_clks(struct csi2_hw *csi2_hw)
306178 {
307
- 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);
308182 }
309183
310
-static void csi2_disable(struct csi2_dev *csi2)
184
+static void csi2_disable(struct csi2_hw *csi2_hw)
311185 {
312
- void __iomem *base = csi2->base;
313
-
314
- write_csihost_reg(base, CSIHOST_RESETN, 0);
315
- write_csihost_reg(base, CSIHOST_MSK1, 0xffffffff);
316
- 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);
317189 }
318190
319
-static void csi2_enable(struct csi2_dev *csi2,
191
+static int csi2_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
192
+ struct v4l2_mbus_config *mbus);
193
+
194
+static void csi2_enable(struct csi2_hw *csi2_hw,
320195 enum host_type_t host_type)
321196 {
322
- void __iomem *base = csi2->base;
197
+ void __iomem *base = csi2_hw->base;
198
+ struct csi2_dev *csi2 = csi2_hw->csi2;
323199 int lanes = csi2->bus.num_data_lanes;
200
+ struct v4l2_mbus_config mbus;
201
+ u32 val = 0;
202
+
203
+ csi2_g_mbus_config(&csi2->sd, 0, &mbus);
204
+ if (mbus.type == V4L2_MBUS_CSI2_DPHY)
205
+ val = SW_CPHY_EN(0);
206
+ else if (mbus.type == V4L2_MBUS_CSI2_CPHY)
207
+ val = SW_CPHY_EN(1);
324208
325209 write_csihost_reg(base, CSIHOST_N_LANES, lanes - 1);
326210
327211 if (host_type == RK_DSI_RXHOST) {
328
- write_csihost_reg(base, CSIHOST_CONTROL,
329
- SW_CPHY_EN(0) | SW_DSI_EN(1) |
330
- SW_DATATYPE_FS(0x01) | SW_DATATYPE_FE(0x11) |
331
- SW_DATATYPE_LS(0x21) | SW_DATATYPE_LE(0x31));
212
+ val |= SW_DSI_EN(1) | SW_DATATYPE_FS(0x01) |
213
+ SW_DATATYPE_FE(0x11) | SW_DATATYPE_LS(0x21) |
214
+ SW_DATATYPE_LE(0x31);
215
+ write_csihost_reg(base, CSIHOST_CONTROL, val);
332216 /* Disable some error interrupt when HOST work on DSI RX mode */
333217 write_csihost_reg(base, CSIHOST_MSK1, 0xe00000f0);
334218 write_csihost_reg(base, CSIHOST_MSK2, 0xff00);
335219 } else {
336
- write_csihost_reg(base, CSIHOST_CONTROL,
337
- SW_CPHY_EN(0) | SW_DSI_EN(0));
338
- write_csihost_reg(base, CSIHOST_MSK1, 0);
220
+ val |= SW_DSI_EN(0) | SW_DATATYPE_FS(0x0) |
221
+ SW_DATATYPE_FE(0x01) | SW_DATATYPE_LS(0x02) |
222
+ SW_DATATYPE_LE(0x03);
223
+ write_csihost_reg(base, CSIHOST_CONTROL, val);
224
+ write_csihost_reg(base, CSIHOST_MSK1, 0x0);
339225 write_csihost_reg(base, CSIHOST_MSK2, 0xf000);
226
+ csi2->is_check_sot_sync = true;
340227 }
341228
342229 write_csihost_reg(base, CSIHOST_RESETN, 1);
....@@ -346,15 +233,9 @@
346233 {
347234 enum host_type_t host_type;
348235 int ret, i;
236
+ int csi_idx = 0;
349237
350238 atomic_set(&csi2->frm_sync_seq, 0);
351
-
352
- csi2_hw_do_reset(csi2);
353
- ret = csi2_enable_clks(csi2);
354
- if (ret) {
355
- v4l2_err(&csi2->sd, "%s: enable clks failed\n", __func__);
356
- return ret;
357
- }
358239
359240 csi2_update_sensor_info(csi2);
360241
....@@ -363,7 +244,18 @@
363244 else
364245 host_type = RK_CSI_RXHOST;
365246
366
- 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
+ }
367259
368260 pr_debug("stream sd: %s\n", csi2->src_sd->name);
369261 ret = v4l2_subdev_call(csi2->src_sd, video, s_stream, 1);
....@@ -377,20 +269,33 @@
377269 return 0;
378270
379271 err_assert_reset:
380
- csi2_disable(csi2);
381
- 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
+ }
382279
383280 return ret;
384281 }
385282
386283 static void csi2_stop(struct csi2_dev *csi2)
387284 {
285
+ int i = 0;
286
+ int csi_idx = 0;
287
+
388288 /* stop upstream */
389289 v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
390290
391
- csi2_disable(csi2);
392
- csi2_hw_do_reset(csi2);
393
- 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
+ }
394299 }
395300
396301 /*
....@@ -500,6 +405,7 @@
500405 csi2->crop.left = 0;
501406 csi2->crop.width = RKCIF_DEFAULT_WIDTH;
502407 csi2->crop.height = RKCIF_DEFAULT_HEIGHT;
408
+ csi2->bus.num_data_lanes = 4;
503409
504410 return media_entity_pads_init(&sd->entity, num_pads, csi2->pad);
505411 }
....@@ -556,10 +462,12 @@
556462 switch (sel->target) {
557463 case V4L2_SEL_TGT_CROP_BOUNDS:
558464 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
465
+ sel->pad = 0;
559466 ret = v4l2_subdev_call(sensor, pad, get_selection,
560467 cfg, sel);
561468 if (ret) {
562469 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
470
+ fmt.pad = 0;
563471 ret = v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt);
564472 if (!ret) {
565473 csi2->format_mbus = fmt.format;
....@@ -608,16 +516,16 @@
608516 return ret;
609517 }
610518
611
-static int csi2_g_mbus_config(struct v4l2_subdev *sd,
519
+static int csi2_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
612520 struct v4l2_mbus_config *mbus)
613521 {
614522 struct csi2_dev *csi2 = sd_to_dev(sd);
615523 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
616524 int ret;
617525
618
- ret = v4l2_subdev_call(sensor_sd, video, g_mbus_config, mbus);
526
+ ret = v4l2_subdev_call(sensor_sd, pad, get_mbus_config, 0, mbus);
619527 if (ret) {
620
- mbus->type = V4L2_MBUS_CSI2;
528
+ mbus->type = V4L2_MBUS_CSI2_DPHY;
621529 mbus->flags = csi2->bus.flags;
622530 mbus->flags |= BIT(csi2->bus.num_data_lanes - 1);
623531 }
....@@ -630,50 +538,118 @@
630538 .link_validate = v4l2_subdev_link_validate,
631539 };
632540
633
-void rkcif_csi2_event_inc_sof(void)
541
+void rkcif_csi2_event_reset_pipe(struct csi2_dev *csi2_dev, int reset_src)
634542 {
635
- if (g_csi2_dev) {
543
+ if (csi2_dev) {
636544 struct v4l2_event event = {
637
- .type = V4L2_EVENT_FRAME_SYNC,
638
- .u.frame_sync.frame_sequence =
639
- atomic_inc_return(&g_csi2_dev->frm_sync_seq) - 1,
545
+ .type = V4L2_EVENT_RESET_DEV,
546
+ .reserved[0] = reset_src,
640547 };
641
- v4l2_event_queue(g_csi2_dev->sd.devnode, &event);
548
+ v4l2_event_queue(csi2_dev->sd.devnode, &event);
642549 }
643550 }
644551
645
-u32 rkcif_csi2_get_sof(void)
552
+void rkcif_csi2_event_inc_sof(struct csi2_dev *csi2_dev)
646553 {
647
- if (g_csi2_dev) {
648
- return atomic_read(&g_csi2_dev->frm_sync_seq) - 1;
554
+ if (csi2_dev) {
555
+ struct v4l2_event event = {
556
+ .type = V4L2_EVENT_FRAME_SYNC,
557
+ .u.frame_sync.frame_sequence =
558
+ atomic_inc_return(&csi2_dev->frm_sync_seq) - 1,
559
+ };
560
+ v4l2_event_queue(csi2_dev->sd.devnode, &event);
649561 }
562
+}
563
+
564
+u32 rkcif_csi2_get_sof(struct csi2_dev *csi2_dev)
565
+{
566
+ if (csi2_dev)
567
+ return atomic_read(&csi2_dev->frm_sync_seq) - 1;
650568
651569 return 0;
652570 }
653571
654
-void rkcif_csi2_set_sof(u32 seq)
572
+void rkcif_csi2_set_sof(struct csi2_dev *csi2_dev, u32 seq)
655573 {
656
- if (g_csi2_dev) {
657
- atomic_set(&g_csi2_dev->frm_sync_seq, seq);
658
- }
574
+ if (csi2_dev)
575
+ atomic_set(&csi2_dev->frm_sync_seq, seq);
659576 }
660577
661578 static int rkcif_csi2_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
662579 struct v4l2_event_subscription *sub)
663580 {
664
- if (sub->type != V4L2_EVENT_FRAME_SYNC)
581
+ if (sub->type == V4L2_EVENT_FRAME_SYNC ||
582
+ sub->type == V4L2_EVENT_RESET_DEV)
583
+ return v4l2_event_subscribe(fh, sub, RKCIF_V4L2_EVENT_ELEMS, NULL);
584
+ else
665585 return -EINVAL;
666
-
667
- return v4l2_event_subscribe(fh, sub, 0, NULL);
668586 }
587
+
588
+static int rkcif_csi2_s_power(struct v4l2_subdev *sd, int on)
589
+{
590
+ return 0;
591
+}
592
+
593
+static long rkcif_csi2_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
594
+{
595
+ struct csi2_dev *csi2 = sd_to_dev(sd);
596
+ struct v4l2_subdev *sensor = get_remote_sensor(sd);
597
+ long ret = 0;
598
+ int i = 0;
599
+
600
+ switch (cmd) {
601
+ case RKCIF_CMD_SET_CSI_IDX:
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);
609
+ break;
610
+ default:
611
+ ret = -ENOIOCTLCMD;
612
+ break;
613
+ }
614
+
615
+ return ret;
616
+}
617
+
618
+#ifdef CONFIG_COMPAT
619
+static long rkcif_csi2_compat_ioctl32(struct v4l2_subdev *sd,
620
+ unsigned int cmd, unsigned long arg)
621
+{
622
+ void __user *up = compat_ptr(arg);
623
+ struct rkcif_csi_info csi_info;
624
+ long ret;
625
+
626
+ switch (cmd) {
627
+ case RKCIF_CMD_SET_CSI_IDX:
628
+ if (copy_from_user(&csi_info, up, sizeof(struct rkcif_csi_info)))
629
+ return -EFAULT;
630
+
631
+ ret = rkcif_csi2_ioctl(sd, cmd, &csi_info);
632
+ break;
633
+ default:
634
+ ret = -ENOIOCTLCMD;
635
+ break;
636
+ }
637
+
638
+ return ret;
639
+}
640
+#endif
669641
670642 static const struct v4l2_subdev_core_ops csi2_core_ops = {
671643 .subscribe_event = rkcif_csi2_subscribe_event,
672644 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
645
+ .s_power = rkcif_csi2_s_power,
646
+ .ioctl = rkcif_csi2_ioctl,
647
+#ifdef CONFIG_COMPAT
648
+ .compat_ioctl32 = rkcif_csi2_compat_ioctl32,
649
+#endif
673650 };
674651
675652 static const struct v4l2_subdev_video_ops csi2_video_ops = {
676
- .g_mbus_config = csi2_g_mbus_config,
677653 .s_stream = csi2_s_stream,
678654 };
679655
....@@ -682,6 +658,7 @@
682658 .set_fmt = csi2_get_set_fmt,
683659 .get_selection = csi2_get_selection,
684660 .set_selection = csi2_set_selection,
661
+ .get_mbus_config = csi2_g_mbus_config,
685662 };
686663
687664 static const struct v4l2_subdev_ops csi2_subdev_ops = {
....@@ -694,15 +671,10 @@
694671 struct v4l2_fwnode_endpoint *vep,
695672 struct v4l2_async_subdev *asd)
696673 {
697
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
698
- struct csi2_dev *csi2 = sd_to_dev(sd);
699
-
700674 if (vep->base.port != 0) {
701675 dev_err(dev, "The csi host node needs to parse port 0\n");
702676 return -EINVAL;
703677 }
704
-
705
- csi2->bus = vep->bus.mipi_csi2;
706678
707679 return 0;
708680 }
....@@ -716,7 +688,7 @@
716688 struct csi2_dev *csi2 = container_of(notifier,
717689 struct csi2_dev,
718690 notifier);
719
- struct csi2_sensor *sensor;
691
+ struct csi2_sensor_info *sensor;
720692 struct media_link *link;
721693 unsigned int pad, ret;
722694
....@@ -772,10 +744,10 @@
772744 struct csi2_dev *csi2 = container_of(notifier,
773745 struct csi2_dev,
774746 notifier);
775
- struct csi2_sensor *sensor = sd_to_sensor(csi2, sd);
747
+ struct csi2_sensor_info *sensor = sd_to_sensor(csi2, sd);
776748
777
- sensor->sd = NULL;
778
-
749
+ if (sensor)
750
+ sensor->sd = NULL;
779751 }
780752
781753 static const struct
....@@ -784,65 +756,133 @@
784756 .unbind = csi2_notifier_unbind,
785757 };
786758
759
+static void csi2_find_err_vc(int val, char *vc_info)
760
+{
761
+ int i;
762
+ char cur_str[CSI_VCINFO_LEN] = {0};
763
+
764
+ memset(vc_info, 0, sizeof(*vc_info));
765
+ for (i = 0; i < 4; i++) {
766
+ if ((val >> i) & 0x1) {
767
+ snprintf(cur_str, CSI_VCINFO_LEN, " %d", i);
768
+ if (strlen(vc_info) + strlen(cur_str) < CSI_VCINFO_LEN)
769
+ strncat(vc_info, cur_str, strlen(cur_str));
770
+ }
771
+ }
772
+}
773
+
774
+#define csi2_err_strncat(dst_str, src_str) {\
775
+ if (strlen(dst_str) + strlen(src_str) < CSI_ERRSTR_LEN)\
776
+ strncat(dst_str, src_str, strlen(src_str)); }
777
+
787778 static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
788779 {
789780 struct device *dev = ctx;
790
- 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;
791783 struct csi2_err_stats *err_list = NULL;
792784 unsigned long err_stat = 0;
793785 u32 val;
786
+ char err_str[CSI_ERRSTR_LEN] = {0};
787
+ char cur_str[CSI_ERRSTR_LEN] = {0};
788
+ char vc_info[CSI_VCINFO_LEN] = {0};
789
+ bool is_add_cnt = false;
794790
795
- 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);
796802 if (val) {
797
- write_csihost_reg(csi2->base,
798
- CSIHOST_ERR1, 0x0);
799
-
800803 if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
801804 err_list = &csi2->err_list[RK_CSI2_ERR_SOTSYN];
802805 err_list->cnt++;
803
- v4l2_err(&csi2->sd,
804
- "ERR1: start of transmission error(no synchronization achieved), reg: 0x%x,cnt:%d\n",
805
- val, err_list->cnt);
806
+ if (csi2->match_data->chip_id == CHIP_RK3588_CSI2) {
807
+ if (err_list->cnt > 3 &&
808
+ csi2->err_list[RK_CSI2_ERR_ALL].cnt <= err_list->cnt) {
809
+ csi2->is_check_sot_sync = false;
810
+ write_csihost_reg(csi2_hw->base, CSIHOST_MSK1, 0xf);
811
+ }
812
+ if (csi2->is_check_sot_sync) {
813
+ csi2_find_err_vc(val & 0xf, vc_info);
814
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot sync,lane:%s) ", vc_info);
815
+ csi2_err_strncat(err_str, cur_str);
816
+ }
817
+ } else {
818
+ csi2_find_err_vc(val & 0xf, vc_info);
819
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot sync,lane:%s) ", vc_info);
820
+ csi2_err_strncat(err_str, cur_str);
821
+ is_add_cnt = true;
822
+ }
806823 }
807824
808825 if (val & CSIHOST_ERR1_ERR_BNDRY_MATCH) {
809826 err_list = &csi2->err_list[RK_CSI2_ERR_FS_FE_MIS];
810827 err_list->cnt++;
811
- v4l2_err(&csi2->sd,
812
- "ERR1: error matching frame start with frame end, reg: 0x%x,cnt:%d\n",
813
- val, err_list->cnt);
828
+ csi2_find_err_vc((val >> 4) & 0xf, vc_info);
829
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(fs/fe mis,vc:%s) ", vc_info);
830
+ csi2_err_strncat(err_str, cur_str);
831
+ if (csi2->match_data->chip_id < CHIP_RK3588_CSI2)
832
+ is_add_cnt = true;
814833 }
815834
816835 if (val & CSIHOST_ERR1_ERR_SEQ) {
817836 err_list = &csi2->err_list[RK_CSI2_ERR_FRM_SEQ_ERR];
818837 err_list->cnt++;
819
- v4l2_err(&csi2->sd,
820
- "ERR1: incorrect frame sequence detected, reg: 0x%x,cnt:%d\n",
821
- val, err_list->cnt);
838
+ csi2_find_err_vc((val >> 8) & 0xf, vc_info);
839
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(f_seq,vc:%s) ", vc_info);
840
+ csi2_err_strncat(err_str, cur_str);
822841 }
823842
824843 if (val & CSIHOST_ERR1_ERR_FRM_DATA) {
825844 err_list = &csi2->err_list[RK_CSI2_ERR_CRC_ONCE];
845
+ is_add_cnt = true;
826846 err_list->cnt++;
827
- v4l2_dbg(1, csi2_debug, &csi2->sd,
828
- "ERR1: at least one crc error, reg: 0x%x\n,cnt:%d", val, err_list->cnt);
847
+ csi2_find_err_vc((val >> 12) & 0xf, vc_info);
848
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err_data,vc:%s) ", vc_info);
849
+ csi2_err_strncat(err_str, cur_str);
829850 }
830851
831852 if (val & CSIHOST_ERR1_ERR_CRC) {
832853 err_list = &csi2->err_list[RK_CSI2_ERR_CRC];
833854 err_list->cnt++;
834
- v4l2_err(&csi2->sd,
835
- "ERR1: crc errors, reg: 0x%x, cnt:%d\n",
836
- val, err_list->cnt);
855
+ is_add_cnt = true;
856
+ csi2_find_err_vc((val >> 24) & 0xf, vc_info);
857
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(crc,vc:%s) ", vc_info);
858
+ csi2_err_strncat(err_str, cur_str);
837859 }
838860
839
- csi2->err_list[RK_CSI2_ERR_ALL].cnt++;
840
- err_stat = ((csi2->err_list[RK_CSI2_ERR_FS_FE_MIS].cnt & 0xff) << 8) |
841
- ((csi2->err_list[RK_CSI2_ERR_ALL].cnt) & 0xff);
861
+ if (val & CSIHOST_ERR1_ERR_ECC2) {
862
+ err_list = &csi2->err_list[RK_CSI2_ERR_CRC];
863
+ err_list->cnt++;
864
+ is_add_cnt = true;
865
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc2) ");
866
+ csi2_err_strncat(err_str, cur_str);
867
+ }
842868
843
- atomic_notifier_call_chain(&g_csi_host_chain,
844
- err_stat,
845
- NULL);
869
+ if (val & CSIHOST_ERR1_ERR_CTRL) {
870
+ csi2_find_err_vc((val >> 16) & 0xf, vc_info);
871
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ctrl,vc:%s) ", vc_info);
872
+ csi2_err_strncat(err_str, cur_str);
873
+ }
874
+
875
+ pr_err("%s ERR1:0x%x %s\n", csi2_hw->dev_name, val, err_str);
876
+
877
+ if (is_add_cnt) {
878
+ csi2->err_list[RK_CSI2_ERR_ALL].cnt++;
879
+ err_stat = ((csi2->err_list[RK_CSI2_ERR_FS_FE_MIS].cnt & 0xff) << 8) |
880
+ ((csi2->err_list[RK_CSI2_ERR_ALL].cnt) & 0xff);
881
+
882
+ atomic_notifier_call_chain(&g_csi_host_chain,
883
+ err_stat,
884
+ &csi2->csi_info.csi_idx[csi2->csi_info.csi_num - 1]);
885
+ }
846886
847887 }
848888
....@@ -852,27 +892,45 @@
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;
897
+ char cur_str[CSI_ERRSTR_LEN] = {0};
898
+ char err_str[CSI_ERRSTR_LEN] = {0};
899
+ char vc_info[CSI_VCINFO_LEN] = {0};
857900
858
- 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);
859907 if (val) {
860
- if (val & CSIHOST_ERR2_PHYERR_ESC)
861
- v4l2_err(&csi2->sd, "ERR2: escape entry error(ULPM), reg: 0x%x\n", val);
862
- if (val & CSIHOST_ERR2_PHYERR_SOTHS)
863
- v4l2_err(&csi2->sd,
864
- "ERR2: start of transmission error(synchronization can still be achieved), reg: 0x%x\n",
865
- val);
866
- if (val & CSIHOST_ERR2_ECC_CORRECTED)
867
- v4l2_dbg(1, csi2_debug, &csi2->sd,
868
- "ERR2: header error detected and corrected, reg: 0x%x\n",
869
- val);
870
- if (val & CSIHOST_ERR2_ERR_ID)
871
- v4l2_err(&csi2->sd,
872
- "ERR2: unrecognized or unimplemented data type detected, reg: 0x%x\n",
873
- val);
874
- if (val & CSIHOST_ERR2_PHYERR_CODEHS)
875
- v4l2_err(&csi2->sd, "ERR2: receiv error code, reg: 0x%x\n", val);
908
+ if (val & CSIHOST_ERR2_PHYERR_ESC) {
909
+ csi2_find_err_vc(val & 0xf, vc_info);
910
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ULPM,lane:%s) ", vc_info);
911
+ csi2_err_strncat(err_str, cur_str);
912
+ }
913
+ if (val & CSIHOST_ERR2_PHYERR_SOTHS) {
914
+ csi2_find_err_vc((val >> 4) & 0xf, vc_info);
915
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot,lane:%s) ", vc_info);
916
+ csi2_err_strncat(err_str, cur_str);
917
+ }
918
+ if (val & CSIHOST_ERR2_ECC_CORRECTED) {
919
+ csi2_find_err_vc((val >> 8) & 0xf, vc_info);
920
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc,vc:%s) ", vc_info);
921
+ csi2_err_strncat(err_str, cur_str);
922
+ }
923
+ if (val & CSIHOST_ERR2_ERR_ID) {
924
+ csi2_find_err_vc((val >> 12) & 0xf, vc_info);
925
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err id,vc:%s) ", vc_info);
926
+ csi2_err_strncat(err_str, cur_str);
927
+ }
928
+ if (val & CSIHOST_ERR2_PHYERR_CODEHS) {
929
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err code) ");
930
+ csi2_err_strncat(err_str, cur_str);
931
+ }
932
+
933
+ pr_err("%s ERR2:0x%x %s\n", csi2_hw->dev_name, val, err_str);
876934 }
877935
878936 return IRQ_HANDLED;
....@@ -883,15 +941,14 @@
883941 struct v4l2_async_notifier *ntf = &csi2->notifier;
884942 int ret;
885943
944
+ v4l2_async_notifier_init(ntf);
945
+
886946 ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(csi2->dev,
887947 &csi2->notifier,
888948 sizeof(struct v4l2_async_subdev), 0,
889949 csi2_parse_endpoint);
890950 if (ret < 0)
891951 return ret;
892
-
893
- if (!ntf->num_subdevs)
894
- return -ENODEV; /* no endpoint */
895952
896953 csi2->sd.subdev_notifier = &csi2->notifier;
897954 csi2->notifier.ops = &csi2_async_ops;
....@@ -912,21 +969,43 @@
912969 static const struct csi2_match_data rk1808_csi2_match_data = {
913970 .chip_id = CHIP_RK1808_CSI2,
914971 .num_pads = CSI2_NUM_PADS,
972
+ .num_hw = 1,
915973 };
916974
917975 static const struct csi2_match_data rk3288_csi2_match_data = {
918976 .chip_id = CHIP_RK3288_CSI2,
919977 .num_pads = CSI2_NUM_PADS_SINGLE_LINK,
978
+ .num_hw = 1,
920979 };
921980
922981 static const struct csi2_match_data rv1126_csi2_match_data = {
923982 .chip_id = CHIP_RV1126_CSI2,
924983 .num_pads = CSI2_NUM_PADS,
984
+ .num_hw = 1,
925985 };
926986
927987 static const struct csi2_match_data rk3568_csi2_match_data = {
928988 .chip_id = CHIP_RK3568_CSI2,
929989 .num_pads = CSI2_NUM_PADS,
990
+ .num_hw = 1,
991
+};
992
+
993
+static const struct csi2_match_data rk3588_csi2_match_data = {
994
+ .chip_id = CHIP_RK3588_CSI2,
995
+ .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,
1003
+};
1004
+
1005
+static const struct csi2_match_data rk3562_csi2_match_data = {
1006
+ .chip_id = CHIP_RK3562_CSI2,
1007
+ .num_pads = CSI2_NUM_PADS_MAX,
1008
+ .num_hw = 4,
9301009 };
9311010
9321011 static const struct of_device_id csi2_dt_ids[] = {
....@@ -946,19 +1025,64 @@
9461025 .compatible = "rockchip,rv1126-mipi-csi2",
9471026 .data = &rv1126_csi2_match_data,
9481027 },
1028
+ {
1029
+ .compatible = "rockchip,rk3588-mipi-csi2",
1030
+ .data = &rk3588_csi2_match_data,
1031
+ },
1032
+ {
1033
+ .compatible = "rockchip,rv1106-mipi-csi2",
1034
+ .data = &rv1106_csi2_match_data,
1035
+ },
1036
+ {
1037
+ .compatible = "rockchip,rk3562-mipi-csi2",
1038
+ .data = &rk3562_csi2_match_data,
1039
+ },
9491040 { /* sentinel */ }
9501041 };
9511042 MODULE_DEVICE_TABLE(of, csi2_dt_ids);
9521043
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
+
9531079 static int csi2_probe(struct platform_device *pdev)
9541080 {
9551081 const struct of_device_id *match;
956
- struct device *dev = &pdev->dev;
9571082 struct device_node *node = pdev->dev.of_node;
9581083 struct csi2_dev *csi2 = NULL;
959
- struct resource *res;
9601084 const struct csi2_match_data *data;
961
- int ret, irq;
1085
+ int ret;
9621086
9631087 match = of_match_node(csi2_dt_ids, node);
9641088 if (IS_ERR(match))
....@@ -972,6 +1096,7 @@
9721096 csi2->dev = &pdev->dev;
9731097 csi2->match_data = data;
9741098
1099
+ csi2->dev_name = node->name;
9751100 v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
9761101 v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
9771102 csi2->sd.entity.ops = &csi2_entity_ops;
....@@ -983,59 +1108,11 @@
9831108 v4l2_err(&csi2->sd, "failed to copy name\n");
9841109 platform_set_drvdata(pdev, &csi2->sd);
9851110
986
- csi2->clks_num = devm_clk_bulk_get_all(dev, &csi2->clks_bulk);
987
- if (csi2->clks_num < 0)
988
- dev_err(dev, "failed to get csi2 clks\n");
989
-
990
- csi2->rsts_bulk = devm_reset_control_array_get_optional_exclusive(dev);
991
- if (IS_ERR(csi2->rsts_bulk)) {
992
- if (PTR_ERR(csi2->rsts_bulk) != -EPROBE_DEFER)
993
- dev_err(dev, "failed to get csi2 reset\n");
994
- return PTR_ERR(csi2->rsts_bulk);
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;
9951115 }
996
-
997
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
998
- csi2->base = devm_ioremap_resource(&pdev->dev, res);
999
- if (IS_ERR(csi2->base)) {
1000
- resource_size_t offset = res->start;
1001
- resource_size_t size = resource_size(res);
1002
-
1003
- dev_warn(&pdev->dev, "avoid secondary mipi resource check!\n");
1004
-
1005
- csi2->base = devm_ioremap(&pdev->dev, offset, size);
1006
- if (IS_ERR(csi2->base)) {
1007
- dev_err(&pdev->dev, "Failed to ioremap resource\n");
1008
-
1009
- return PTR_ERR(csi2->base);
1010
- }
1011
- }
1012
-
1013
- irq = platform_get_irq_byname(pdev, "csi-intr1");
1014
- if (irq > 0) {
1015
- ret = devm_request_irq(&pdev->dev, irq,
1016
- rk_csirx_irq1_handler, 0,
1017
- dev_driver_string(&pdev->dev),
1018
- &pdev->dev);
1019
- if (ret < 0)
1020
- v4l2_err(&csi2->sd, "request csi-intr1 irq failed: %d\n",
1021
- ret);
1022
- } else {
1023
- v4l2_err(&csi2->sd, "No found irq csi-intr1\n");
1024
- }
1025
-
1026
- irq = platform_get_irq_byname(pdev, "csi-intr2");
1027
- if (irq > 0) {
1028
- ret = devm_request_irq(&pdev->dev, irq,
1029
- rk_csirx_irq2_handler, 0,
1030
- dev_driver_string(&pdev->dev),
1031
- &pdev->dev);
1032
- if (ret < 0)
1033
- v4l2_err(&csi2->sd, "request csi-intr2 failed: %d\n",
1034
- ret);
1035
- } else {
1036
- v4l2_err(&csi2->sd, "No found irq csi-intr2\n");
1037
- }
1038
-
10391116 mutex_init(&csi2->lock);
10401117
10411118 ret = csi2_media_init(&csi2->sd);
....@@ -1044,10 +1121,6 @@
10441121 ret = csi2_notifier(csi2);
10451122 if (ret)
10461123 goto rmmutex;
1047
-
1048
- csi2_hw_do_reset(csi2);
1049
-
1050
- g_csi2_dev = csi2;
10511124
10521125 v4l2_info(&csi2->sd, "probe success, v4l2_dev:%s!\n", csi2->sd.v4l2_dev->name);
10531126
....@@ -1079,16 +1152,190 @@
10791152 .remove = csi2_remove,
10801153 };
10811154
1082
-int __init rkcif_csi2_plat_drv_init(void)
1155
+int rkcif_csi2_plat_drv_init(void)
10831156 {
10841157 return platform_driver_register(&csi2_driver);
10851158 }
10861159
1087
-void __exit rkcif_csi2_plat_drv_exit(void)
1160
+void rkcif_csi2_plat_drv_exit(void)
10881161 {
10891162 platform_driver_unregister(&csi2_driver);
10901163 }
10911164
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
+
10921339 MODULE_DESCRIPTION("Rockchip MIPI CSI2 driver");
10931340 MODULE_AUTHOR("Macrofly.xu <xuhf@rock-chips.com>");
10941341 MODULE_LICENSE("GPL");