forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/sc223a.c
....@@ -2,11 +2,12 @@
22 /*
33 * sc223a driver
44 *
5
- * Copyright (C) 2020 Cnd Electronics Co., Ltd.
5
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
66 *
7
- * V0.0X01.0X01 first version.
7
+ * V0.0X01.0X01 first version
88 */
99
10
+//#define DEBUG
1011 #include <linux/clk.h>
1112 #include <linux/device.h>
1213 #include <linux/delay.h>
....@@ -25,6 +26,7 @@
2526 #include <media/v4l2-ctrls.h>
2627 #include <media/v4l2-subdev.h>
2728 #include <linux/pinctrl/consumer.h>
29
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
2830
2931 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
3032
....@@ -34,11 +36,13 @@
3436
3537 #define SC223A_LANES 2
3638 #define SC223A_BITS_PER_SAMPLE 10
37
-#define SC223A_LINK_FREQ_371 371250000// 742.5Mbps
39
+#define SC223A_LINK_FREQ_405 202500000
3840
39
-#define PIXEL_RATE_WITH_371M_10BIT (SC223A_LINK_FREQ_371 * 2 * \
41
+#define PIXEL_RATE_WITH_405M_10BIT (SC223A_LINK_FREQ_405 * 2 * \
4042 SC223A_LANES / SC223A_BITS_PER_SAMPLE)
41
-#define SC223A_XVCLK_FREQ 27000000
43
+/* 79.2Mhz */
44
+#define SC223A_PIXEL_RATE (79200000)
45
+#define SC223A_XVCLK_FREQ 24000000
4246
4347 #define CHIP_ID 0xcb3e
4448 #define SC223A_REG_CHIP_ID 0x3107
....@@ -50,35 +54,23 @@
5054 #define SC223A_REG_EXPOSURE_H 0x3e00
5155 #define SC223A_REG_EXPOSURE_M 0x3e01
5256 #define SC223A_REG_EXPOSURE_L 0x3e02
53
-#define SC223A_REG_SEXPOSURE_H 0x3e22
54
-#define SC223A_REG_SEXPOSURE_M 0x3e04
55
-#define SC223A_REG_SEXPOSURE_L 0x3e05
56
-#define SC223A_EXPOSURE_MIN 1
57
+#define SC223A_EXPOSURE_MIN 3
5758 #define SC223A_EXPOSURE_STEP 1
5859 #define SC223A_VTS_MAX 0x7fff
5960
6061 #define SC223A_REG_DIG_GAIN 0x3e06
6162 #define SC223A_REG_DIG_FINE_GAIN 0x3e07
6263 #define SC223A_REG_ANA_GAIN 0x3e09
63
-#define SC223A_REG_SDIG_GAIN 0x3e10
64
-#define SC223A_REG_SDIG_FINE_GAIN 0x3e11
65
-#define SC223A_REG_SANA_GAIN 0x3e12
66
-#define SC223A_REG_SANA_FINE_GAIN 0x3e13
67
-#define SC223A_GAIN_MIN 0x0040
68
-#define SC223A_GAIN_MAX (54 * 32 * 64)
64
+#define SC223A_GAIN_MIN 0x0080
65
+#define SC223A_GAIN_MAX (29656) //57.92*4*128
6966 #define SC223A_GAIN_STEP 1
70
-#define SC223A_GAIN_DEFAULT 0x0800
71
-#define SC223A_LGAIN 0
72
-#define SC223A_SGAIN 1
67
+#define SC223A_GAIN_DEFAULT 0x80
7368
7469 #define SC223A_REG_GROUP_HOLD 0x3812
75
-#define SC223A_GROUP_HOLD_START 0x00
70
+#define SC223A_GROUP_HOLD_START 0x00
7671 #define SC223A_GROUP_HOLD_END 0x30
7772
78
-#define SC223A_REG_HIGH_TEMP_H 0x3974
79
-#define SC223A_REG_HIGH_TEMP_L 0x3975
80
-
81
-#define SC223A_REG_TEST_PATTERN 0x4501
73
+#define SC223A_REG_TEST_PATTERN 0x4501
8274 #define SC223A_TEST_PATTERN_BIT_MASK BIT(3)
8375
8476 #define SC223A_REG_VTS_H 0x320e
....@@ -86,8 +78,12 @@
8678
8779 #define SC223A_FLIP_MIRROR_REG 0x3221
8880
89
-#define SC223A_FETCH_AGAIN_H(VAL) (((VAL) >> 8) & 0x03)
90
-#define SC223A_FETCH_AGAIN_L(VAL) ((VAL) & 0xFF)
81
+#define SC223A_FETCH_EXP_H(VAL) (((VAL) >> 12) & 0xF)
82
+#define SC223A_FETCH_EXP_M(VAL) (((VAL) >> 4) & 0xFF)
83
+#define SC223A_FETCH_EXP_L(VAL) (((VAL) & 0xF) << 4)
84
+
85
+#define SC223A_FETCH_AGAIN_H(VAL) (((VAL) >> 8) & 0x03)
86
+#define SC223A_FETCH_AGAIN_L(VAL) ((VAL) & 0xFF)
9187
9288 #define SC223A_FETCH_MIRROR(VAL, ENABLE) (ENABLE ? VAL | 0x06 : VAL & 0xf9)
9389 #define SC223A_FETCH_FLIP(VAL, ENABLE) (ENABLE ? VAL | 0x60 : VAL & 0x9f)
....@@ -99,11 +95,12 @@
9995 #define SC223A_REG_VALUE_16BIT 2
10096 #define SC223A_REG_VALUE_24BIT 3
10197
98
+#define RKMODULE_CAMERA_MODULE_MODE "rockchip,camera_mode"
10299 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
103100 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
104
-#define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
105101 #define SC223A_NAME "sc223a"
106
-
102
+#define CAMERA_MIPI_MODE "mipi_mode"
103
+#define CAMERA_DVP_MODE "dvp_mode"
107104 static const char * const sc223a_supply_names[] = {
108105 "avdd", /* Analog power */
109106 "dovdd", /* Digital I/O power */
....@@ -112,12 +109,15 @@
112109
113110 #define SC223A_NUM_SUPPLIES ARRAY_SIZE(sc223a_supply_names)
114111
115
-enum sc223a_max_pad {
116
- PAD0, /* link to isp */
117
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
118
- PAD2, /* link to csi wr1 | hdr x3:L */
119
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
120
- PAD_MAX,
112
+enum sc223a_support_mode_id {
113
+ SC223A_MIPI_1920X1080 = 0,
114
+ SC223A_DVP_1920X1080,
115
+ SC223A_MODE_ID_MAX = SC223A_DVP_1920X1080,
116
+};
117
+
118
+enum sc223a_mode_id {
119
+ SC223A_MIPI_MODE = 0,
120
+ SC223A_DVP_MODE,
121121 };
122122
123123 struct regval {
....@@ -136,6 +136,7 @@
136136 const struct regval *reg_list;
137137 u32 hdr_mode;
138138 u32 vc[PAD_MAX];
139
+ u8 mode_id;
139140 };
140141
141142 struct sc223a {
....@@ -159,6 +160,7 @@
159160 struct v4l2_ctrl *vblank;
160161 struct v4l2_ctrl *test_pattern;
161162 struct mutex mutex;
163
+ struct v4l2_fract cur_fps;
162164 bool streaming;
163165 bool power_on;
164166 const struct sc223a_mode *cur_mode;
....@@ -166,8 +168,11 @@
166168 const char *module_facing;
167169 const char *module_name;
168170 const char *len_name;
171
+ const char *mode;
169172 u32 cur_vts;
170173 bool has_init_exp;
174
+ bool is_thunderboot;
175
+ bool is_first_streamoff;
171176 struct preisp_hdrae_exp_s init_hdrae_exp;
172177 };
173178
....@@ -182,23 +187,29 @@
182187
183188 /*
184189 * Xclk 24Mhz
185
- * max_framerate 90fps
186
- * mipi_datarate per lane 1008Mbps, 4lane
190
+ * max_framerate 30fps
191
+ * mipi_datarate per lane 405Mbps, 2lane
187192 */
188
-static const struct regval sc223a_linear_10_1920x1080_regs[] = {
193
+static const struct regval sc223a_linear_10_1920x1080_30fps_regs[] = {
189194 {0x0100, 0x00},
190195 {0x36e9, 0x80},
191196 {0x37f9, 0x80},
192
- {0x301f, 0x01},
197
+ {0x301f, 0x08},
198
+ {0x30b8, 0x44},
199
+ {0x320c, 0x08},
200
+ {0x320d, 0xca},
201
+ {0x320e, 0x04},
202
+ {0x320f, 0xb0},
193203 {0x3253, 0x0c},
194204 {0x3281, 0x80},
195
- {0x3301, 0x08},
205
+ {0x3301, 0x06},
196206 {0x3302, 0x12},
197
- {0x3306, 0xb0},
207
+ {0x3306, 0x84},
198208 {0x3309, 0x60},
199
- {0x330a, 0x01},
200
- {0x330b, 0x60},
209
+ {0x330a, 0x00},
210
+ {0x330b, 0xe0},
201211 {0x330d, 0x20},
212
+ {0x3314, 0x15},
202213 {0x331e, 0x41},
203214 {0x331f, 0x51},
204215 {0x3320, 0x0a},
....@@ -216,69 +227,115 @@
216227 {0x3390, 0x03},
217228 {0x3391, 0x0f},
218229 {0x3392, 0x1f},
219
- {0x3393, 0x08},
220
- {0x3394, 0x08},
221
- {0x3395, 0x08},
222
- {0x3396, 0x41},
223
- {0x3397, 0x47},
230
+ {0x3393, 0x06},
231
+ {0x3394, 0x06},
232
+ {0x3395, 0x06},
233
+ {0x3396, 0x48},
234
+ {0x3397, 0x4b},
224235 {0x3398, 0x5f},
225
- {0x3399, 0x08},
226
- {0x339a, 0x10},
227
- {0x339b, 0x38},
228
- {0x339c, 0x3c},
236
+ {0x3399, 0x06},
237
+ {0x339a, 0x06},
238
+ {0x339b, 0x9c},
239
+ {0x339c, 0x9c},
229240 {0x33a2, 0x04},
230241 {0x33a3, 0x0a},
231
- {0x33ad, 0x18},
242
+ {0x33ad, 0x1c},
232243 {0x33af, 0x40},
233244 {0x33b1, 0x80},
234245 {0x33b3, 0x20},
235246 {0x349f, 0x02},
236
- {0x34a6, 0x41},
237
- {0x34a7, 0x47},
247
+ {0x34a6, 0x48},
248
+ {0x34a7, 0x4b},
238249 {0x34a8, 0x20},
239250 {0x34a9, 0x20},
240251 {0x34f8, 0x5f},
241
- {0x34f9, 0x20},
252
+ {0x34f9, 0x10},
253
+ {0x3616, 0xac},
242254 {0x3630, 0xc0},
243255 {0x3631, 0x86},
244256 {0x3632, 0x26},
245257 {0x3633, 0x32},
258
+ {0x3637, 0x29},
246259 {0x363a, 0x84},
260
+ {0x363b, 0x04},
261
+ {0x363c, 0x08},
247262 {0x3641, 0x3a},
248
- {0x3670, 0x4e},
263
+ {0x364f, 0x39},
264
+ {0x3670, 0xce},
249265 {0x3674, 0xc0},
250266 {0x3675, 0xc0},
251267 {0x3676, 0xc0},
252268 {0x3677, 0x86},
253269 {0x3678, 0x8b},
254270 {0x3679, 0x8c},
255
- {0x367c, 0x47},
271
+ {0x367c, 0x4b},
256272 {0x367d, 0x5f},
257
- {0x367e, 0x47},
273
+ {0x367e, 0x4b},
258274 {0x367f, 0x5f},
259
- {0x3690, 0x42},
260
- {0x3691, 0x43},
275
+ {0x3690, 0x62},
276
+ {0x3691, 0x63},
261277 {0x3692, 0x63},
262
- {0x3699, 0x84},
263
- {0x369a, 0x8c},
278
+ {0x3699, 0x86},
279
+ {0x369a, 0x92},
264280 {0x369b, 0xa4},
265
- {0x369c, 0x41},
266
- {0x369d, 0x47},
267
- {0x36a2, 0x41},
268
- {0x36a3, 0x47},
281
+ {0x369c, 0x48},
282
+ {0x369d, 0x4b},
283
+ {0x36a2, 0x4b},
284
+ {0x36a3, 0x4f},
285
+ {0x36ea, 0x09},
286
+ {0x36eb, 0x0c},
287
+ {0x36ec, 0x1c},
288
+ {0x36ed, 0x28},
269289 {0x370f, 0x01},
270290 {0x3721, 0x6c},
271291 {0x3722, 0x09},
272
- {0x3725, 0xa4},
292
+ {0x3724, 0x41},
293
+ {0x3725, 0xc4},
273294 {0x37b0, 0x09},
274295 {0x37b1, 0x09},
275
- {0x37b2, 0x05},
276
- {0x37b3, 0x41},
296
+ {0x37b2, 0x09},
297
+ {0x37b3, 0x48},
277298 {0x37b4, 0x5f},
299
+ {0x37fa, 0x09},
300
+ {0x37fb, 0x32},
301
+ {0x37fc, 0x10},
302
+ {0x37fd, 0x37},
303
+ {0x3900, 0x19},
278304 {0x3901, 0x02},
279
- {0x3e01, 0x8c},
280
- {0x4509, 0x28},
305
+ {0x3905, 0xb8},
306
+ {0x391b, 0x82},
307
+ {0x391c, 0x00},
308
+ {0x391f, 0x04},
309
+ {0x3933, 0x81},
310
+ {0x3934, 0x4c},
311
+ {0x393f, 0xff},
312
+ {0x3940, 0x73},
313
+ {0x3942, 0x01},
314
+ {0x3943, 0x4d},
315
+ {0x3946, 0x20},
316
+ {0x3957, 0x86},
317
+ {0x3e01, 0x95},
318
+ {0x3e02, 0x60},
319
+ {0x3e28, 0xc4},
320
+ {0x440e, 0x02},
321
+ {0x4501, 0xc0},
322
+ {0x4509, 0x14},
323
+ {0x450d, 0x11},
281324 {0x4518, 0x00},
325
+ {0x451b, 0x0a},
326
+ {0x4819, 0x07},
327
+ {0x481b, 0x04},
328
+ {0x481d, 0x0e},
329
+ {0x481f, 0x03},
330
+ {0x4821, 0x09},
331
+ {0x4823, 0x04},
332
+ {0x4825, 0x03},
333
+ {0x4827, 0x03},
334
+ {0x4829, 0x06},
335
+ {0x501c, 0x00},
336
+ {0x501d, 0x60},
337
+ {0x501e, 0x00},
338
+ {0x501f, 0x40},
282339 {0x5799, 0x06},
283340 {0x5ae0, 0xfe},
284341 {0x5ae1, 0x40},
....@@ -308,14 +365,228 @@
308365 {0x5afd, 0x3f},
309366 {0x5afe, 0x34},
310367 {0x5aff, 0x2c},
311
- {0x36e9, 0x20},
312
- {0x37f9, 0x27},
313
- {0x0100, 0x01},
368
+ {0x36e9, 0x53},
369
+ {0x37f9, 0x53},
370
+ {REG_NULL, 0x00},
371
+};
372
+
373
+/*
374
+ * Xclk 24Mhz
375
+ * Pclk 79.2Mhz
376
+ * max_framerate 30fps
377
+ * 1920x1080
378
+ * dvp 10bit, 2lane
379
+ */
380
+static const struct regval sc223a_linear_10_1920x1080_dvp_30fps_regs[] = {
381
+ {0x0100, 0x00},
382
+ {0x36e9, 0x80},
383
+ {0x37f9, 0x80},
384
+ {0x3001, 0xff},
385
+ {0x3002, 0xf0},
386
+ {0x300a, 0x24},
387
+ {0x3018, 0x0f},
388
+ {0x301a, 0xf8},
389
+ {0x301c, 0x94},
390
+ {0x301f, 0x40},
391
+ {0x303f, 0x81},
392
+ {0x30b8, 0x44},
393
+ {0x3200, 0x00},
394
+ {0x3201, 0x00},
395
+ {0x3202, 0x00},
396
+ {0x3203, 0x00},
397
+ {0x3204, 0x07},
398
+ {0x3205, 0x87},
399
+ {0x3206, 0x04},
400
+ {0x3207, 0x3f},
401
+ {0x3208, 0x07},
402
+ {0x3209, 0x80},
403
+ {0x320a, 0x04},
404
+ {0x320b, 0x38},
405
+ {0x320c, 0x09},
406
+ {0x320d, 0x60},
407
+ {0x320e, 0x04},
408
+ {0x320f, 0x65},
409
+ {0x3210, 0x00},
410
+ {0x3211, 0x04},
411
+ {0x3212, 0x00},
412
+ {0x3213, 0x04},
413
+ {0x3227, 0x03},
414
+ {0x3250, 0x00},
415
+ {0x3253, 0x0c},
416
+ {0x3281, 0x80},
417
+ {0x3301, 0x06},
418
+ {0x3302, 0x12},
419
+ {0x3306, 0x84},
420
+ {0x3309, 0x60},
421
+ {0x330a, 0x00},
422
+ {0x330b, 0xe0},
423
+ {0x330d, 0x20},
424
+ {0x3314, 0x15},
425
+ {0x331e, 0x41},
426
+ {0x331f, 0x51},
427
+ {0x3320, 0x0a},
428
+ {0x3326, 0x0e},
429
+ {0x3333, 0x10},
430
+ {0x3334, 0x40},
431
+ {0x335d, 0x60},
432
+ {0x335e, 0x06},
433
+ {0x335f, 0x08},
434
+ {0x3364, 0x56},
435
+ {0x337a, 0x06},
436
+ {0x337b, 0x0e},
437
+ {0x337c, 0x02},
438
+ {0x337d, 0x0a},
439
+ {0x3390, 0x03},
440
+ {0x3391, 0x0f},
441
+ {0x3392, 0x1f},
442
+ {0x3393, 0x06},
443
+ {0x3394, 0x06},
444
+ {0x3395, 0x06},
445
+ {0x3396, 0x48},
446
+ {0x3397, 0x4b},
447
+ {0x3398, 0x5f},
448
+ {0x3399, 0x06},
449
+ {0x339a, 0x06},
450
+ {0x339b, 0x9c},
451
+ {0x339c, 0x9c},
452
+ {0x33a2, 0x04},
453
+ {0x33a3, 0x0a},
454
+ {0x33ad, 0x1c},
455
+ {0x33af, 0x40},
456
+ {0x33b1, 0x80},
457
+ {0x33b3, 0x20},
458
+ {0x349f, 0x02},
459
+ {0x34a6, 0x48},
460
+ {0x34a7, 0x4b},
461
+ {0x34a8, 0x20},
462
+ {0x34a9, 0x20},
463
+ {0x34f8, 0x5f},
464
+ {0x34f9, 0x10},
465
+ {0x3616, 0xac},
466
+ {0x3630, 0xc0},
467
+ {0x3631, 0x86},
468
+ {0x3632, 0x26},
469
+ {0x3633, 0x32},
470
+ {0x3637, 0x29},
471
+ {0x363a, 0x84},
472
+ {0x363b, 0x04},
473
+ {0x363c, 0x08},
474
+ {0x3641, 0x3a},
475
+ {0x364f, 0x39},
476
+ {0x3670, 0xce},
477
+ {0x3674, 0xc0},
478
+ {0x3675, 0xc0},
479
+ {0x3676, 0xc0},
480
+ {0x3677, 0x86},
481
+ {0x3678, 0x8b},
482
+ {0x3679, 0x8c},
483
+ {0x367c, 0x4b},
484
+ {0x367d, 0x5f},
485
+ {0x367e, 0x4b},
486
+ {0x367f, 0x5f},
487
+ {0x3690, 0x62},
488
+ {0x3691, 0x63},
489
+ {0x3692, 0x63},
490
+ {0x3699, 0x86},
491
+ {0x369a, 0x92},
492
+ {0x369b, 0xa4},
493
+ {0x369c, 0x48},
494
+ {0x369d, 0x4b},
495
+ {0x36a2, 0x4b},
496
+ {0x36a3, 0x4f},
497
+ {0x36ea, 0x09},
498
+ {0x36eb, 0x0c},
499
+ {0x36ec, 0x1c},
500
+ {0x36ed, 0x28},
501
+ {0x370f, 0x01},
502
+ {0x3721, 0x6c},
503
+ {0x3722, 0x09},
504
+ {0x3724, 0x41},
505
+ {0x3725, 0xc4},
506
+ {0x37b0, 0x09},
507
+ {0x37b1, 0x09},
508
+ {0x37b2, 0x09},
509
+ {0x37b3, 0x48},
510
+ {0x37b4, 0x5f},
511
+ {0x37fa, 0x09},
512
+ {0x37fb, 0x32},
513
+ {0x37fc, 0x10},
514
+ {0x37fd, 0x37},
515
+ {0x3900, 0x19},
516
+ {0x3901, 0x02},
517
+ {0x3905, 0xb8},
518
+ {0x391b, 0x82},
519
+ {0x391c, 0x00},
520
+ {0x391f, 0x04},
521
+ {0x3928, 0xc1},
522
+ {0x3933, 0x81},
523
+ {0x3934, 0x4c},
524
+ {0x393f, 0xff},
525
+ {0x3940, 0x73},
526
+ {0x3942, 0x01},
527
+ {0x3943, 0x4d},
528
+ {0x3946, 0x20},
529
+ {0x3957, 0x86},
530
+ {0x3e01, 0x8c},
531
+ {0x3e02, 0x00},
532
+ {0x3e28, 0xc4},
533
+ {0x440e, 0x02},
534
+ {0x4501, 0xc0},
535
+ {0x4509, 0x14},
536
+ {0x450d, 0x11},
537
+ {0x4518, 0x00},
538
+ {0x451b, 0x0a},
539
+ {0x4603, 0x09},
540
+ {0x4819, 0x07},
541
+ {0x481b, 0x04},
542
+ {0x481d, 0x0e},
543
+ {0x3000, 0xff},
544
+ {0x481f, 0x03},
545
+ {0x4821, 0x09},
546
+ {0x4823, 0x04},
547
+ {0x4825, 0x03},
548
+ {0x4827, 0x03},
549
+ {0x4829, 0x06},
550
+ {0x501c, 0x00},
551
+ {0x501d, 0x60},
552
+ {0x501e, 0x00},
553
+ {0x501f, 0x40},
554
+ {0x5799, 0x06},
555
+ {0x5ae0, 0xfe},
556
+ {0x5ae1, 0x40},
557
+ {0x5ae2, 0x38},
558
+ {0x5ae3, 0x30},
559
+ {0x5ae4, 0x28},
560
+ {0x5ae5, 0x38},
561
+ {0x5ae6, 0x30},
562
+ {0x5ae7, 0x28},
563
+ {0x5ae8, 0x3f},
564
+ {0x5ae9, 0x34},
565
+ {0x5aea, 0x2c},
566
+ {0x5aeb, 0x3f},
567
+ {0x5aec, 0x34},
568
+ {0x5aed, 0x2c},
569
+ {0x5aee, 0xfe},
570
+ {0x5aef, 0x40},
571
+ {0x5af4, 0x38},
572
+ {0x5af5, 0x30},
573
+ {0x5af6, 0x28},
574
+ {0x5af7, 0x38},
575
+ {0x5af8, 0x30},
576
+ {0x5af9, 0x28},
577
+ {0x5afa, 0x3f},
578
+ {0x5afb, 0x34},
579
+ {0x5afc, 0x2c},
580
+ {0x5afd, 0x3f},
581
+ {0x5afe, 0x34},
582
+ {0x5aff, 0x2c},
583
+ {0x36e9, 0x53},
584
+ {0x37f9, 0x53},
314585 {REG_NULL, 0x00},
315586 };
316587
317588 static const struct sc223a_mode supported_modes[] = {
318
- {
589
+ [SC223A_MIPI_1920X1080] = {
319590 .width = 1920,
320591 .height = 1080,
321592 .max_fps = {
....@@ -323,17 +594,34 @@
323594 .denominator = 300000,
324595 },
325596 .exp_def = 0x0080,
326
- .hts_def = 0x44C * 2,
327
- .vts_def = 0x0465,
597
+ .hts_def = 0x08ca,
598
+ .vts_def = 0x04b0,
328599 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
329
- .reg_list = sc223a_linear_10_1920x1080_regs,
600
+ .reg_list = sc223a_linear_10_1920x1080_30fps_regs,
330601 .hdr_mode = NO_HDR,
602
+ .mode_id = SC223A_MIPI_MODE,
331603 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
332
- }
604
+ },
605
+ [SC223A_DVP_1920X1080] = {
606
+ .width = 1920,
607
+ .height = 1080,
608
+ .max_fps = {
609
+ .numerator = 10000,
610
+ .denominator = 300000,
611
+ },
612
+ .exp_def = 0x0080,
613
+ .hts_def = 0x0960,
614
+ .vts_def = 0x0465,
615
+ .bus_fmt = MEDIA_BUS_FMT_SBGGR8_1X8,
616
+ .reg_list = sc223a_linear_10_1920x1080_dvp_30fps_regs,
617
+ .hdr_mode = NO_HDR,
618
+ .mode_id = SC223A_DVP_MODE,
619
+ .vc[PAD0] = 0,
620
+ },
333621 };
334622
335
-static const s64 link_freq_menu_items[] = {
336
- SC223A_LINK_FREQ_371
623
+static const __maybe_unused s64 link_freq_menu_items[] = {
624
+ SC223A_LINK_FREQ_405
337625 };
338626
339627 static const char * const sc223a_test_pattern_menu[] = {
....@@ -369,7 +657,6 @@
369657
370658 if (i2c_master_send(client, buf, len + 2) != len + 2)
371659 return -EIO;
372
-
373660 return 0;
374661 }
375662
....@@ -423,62 +710,69 @@
423710
424711 static int sc223a_set_gain_reg(struct sc223a *sc223a, u32 gain)
425712 {
426
- struct device *dev = &sc223a->client->dev;
427
- u8 again_reg, dgain_reg;
428
- u8 dgain_f_reg;
429
- int ret = 0;
713
+ struct i2c_client *client = sc223a->client;
714
+ u32 coarse_again = 0, coarse_dgain = 0, fine_dgain = 0;
715
+ int ret = 0, gain_factor;
430716
431
- if (gain < 0xe8) {/* 1 - 1.81 gain */
432
- if (gain < 0x80)
433
- dev_info(dev, "The minimum gain reg value is 0x80\n");
434
- again_reg = 0x00;
435
- dgain_reg = 0x00;
436
- dgain_f_reg = gain;
437
- } else if (gain < 0x1cf) {/* 1.81 - 3.62 gain */
438
- again_reg = 0x40;
439
- dgain_reg = 0x00;
440
- dgain_f_reg = (gain * 100) / 181;
441
- } else if (gain < 0x39e) {/* 3.62 - 7.24 gain */
442
- again_reg = 0x48;
443
- dgain_reg = 0x00;
444
- dgain_f_reg = ((gain >> 1) * 100) / 181;
445
- } else if (gain < 0x73d) {/* 7.24 - 14.48 gain */
446
- again_reg = 0x49;
447
- dgain_reg = 0x00;
448
- dgain_f_reg = ((gain >> 2) * 100) / 181;
449
- } else if (gain < 0xe7a) {/* 14.48 - 28.96 gain */
450
- again_reg = 0x4B;
451
- dgain_reg = 0x00;
452
- dgain_f_reg = ((gain >> 3) * 100) / 181;
453
- } else if (gain < 0x1cf5) {/* 28.96 - 57.92 gain */
454
- again_reg = 0x4F;
455
- dgain_reg = 0x00;
456
- dgain_f_reg = ((gain >> 4) * 100) / 181;
457
- } else if (gain < 0x3985) {/* 57.92 - 115.84 gain */
458
- again_reg = 0x5F;
459
- dgain_reg = 0x00;
460
- dgain_f_reg = ((gain >> 5) * 100) / 181;
461
- } else if (gain < 0x73d7) {/* 115.84 - 231.68 gain */
462
- again_reg = 0x5F;
463
- dgain_reg = 0x01;
464
- dgain_f_reg = ((gain >> 6) * 100) / 181;
465
- } else {/* 231.68 gain */
466
- again_reg = 0x5F;
467
- dgain_reg = 0x03;
468
- dgain_f_reg = 0x80;
717
+ if (gain < 128)
718
+ gain = 128;
719
+ else if (gain > SC223A_GAIN_MAX)
720
+ gain = SC223A_GAIN_MAX;
721
+
722
+ gain_factor = gain * 1000 / 128;
723
+ if (gain_factor < 1810) {
724
+ coarse_again = 0x00;
725
+ coarse_dgain = 0x00;
726
+ fine_dgain = gain_factor * 128 / 1000;
727
+ } else if (gain_factor < 1810 * 2) {
728
+ coarse_again = 0x40;
729
+ coarse_dgain = 0x00;
730
+ fine_dgain = gain_factor * 128 / 1810;
731
+ } else if (gain_factor < 1810 * 4) {
732
+ coarse_again = 0x48;
733
+ coarse_dgain = 0x00;
734
+ fine_dgain = gain_factor * 128 / 1810 / 2;
735
+ } else if (gain_factor < 1810 * 8) {
736
+ coarse_again = 0x49;
737
+ coarse_dgain = 0x00;
738
+ fine_dgain = gain_factor * 128 / 1810 / 4;
739
+ } else if (gain_factor < 1810 * 16) {
740
+ coarse_again = 0x4b;
741
+ coarse_dgain = 0x00;
742
+ fine_dgain = gain_factor * 128 / 1810 / 8;
743
+ } else if (gain_factor < 1810 * 32) {
744
+ coarse_again = 0x4f;
745
+ coarse_dgain = 0x00;
746
+ fine_dgain = gain_factor * 128 / 1810 / 16;
747
+ } else if (gain_factor < 1810 * 64) {
748
+ //open dgain begin max digital gain 4X
749
+ coarse_again = 0x5f;
750
+ coarse_dgain = 0x00;
751
+ fine_dgain = gain_factor * 128 / 1810 / 32;
752
+ } else if (gain_factor < 1810 * 128) {
753
+ coarse_again = 0x5f;
754
+ coarse_dgain = 0x01;
755
+ fine_dgain = gain_factor * 128 / 1810 / 64;
756
+ } else {
757
+ coarse_again = 0x5f;
758
+ coarse_dgain = 0x03;
759
+ fine_dgain = 0x80;
469760 }
761
+ dev_dbg(&client->dev, "c_again: 0x%x, c_dgain: 0x%x, f_dgain: 0x%0x\n",
762
+ coarse_again, coarse_dgain, fine_dgain);
763
+
470764 ret = sc223a_write_reg(sc223a->client,
471
- SC223A_REG_DIG_GAIN,
472
- SC223A_REG_VALUE_08BIT,
473
- dgain_reg);
765
+ SC223A_REG_DIG_GAIN,
766
+ SC223A_REG_VALUE_08BIT,
767
+ coarse_dgain);
474768 ret |= sc223a_write_reg(sc223a->client,
475
- SC223A_REG_DIG_FINE_GAIN,
476
- SC223A_REG_VALUE_08BIT,
477
- dgain_f_reg);
769
+ SC223A_REG_DIG_FINE_GAIN,
770
+ SC223A_REG_VALUE_08BIT,
771
+ fine_dgain);
478772 ret |= sc223a_write_reg(sc223a->client,
479
- SC223A_REG_ANA_GAIN,
480
- SC223A_REG_VALUE_08BIT,
481
- again_reg);
773
+ SC223A_REG_ANA_GAIN,
774
+ SC223A_REG_VALUE_08BIT,
775
+ coarse_again);
482776
483777 return ret;
484778 }
....@@ -487,7 +781,7 @@
487781 struct v4l2_mbus_framefmt *framefmt)
488782 {
489783 return abs(mode->width - framefmt->width) +
490
- abs(mode->height - framefmt->height);
784
+ abs(mode->height - framefmt->height);
491785 }
492786
493787 static const struct sc223a_mode *
....@@ -541,6 +835,7 @@
541835 __v4l2_ctrl_modify_range(sc223a->vblank, vblank_def,
542836 SC223A_VTS_MAX - mode->height,
543837 1, vblank_def);
838
+ sc223a->cur_fps = mode->max_fps;
544839 }
545840
546841 mutex_unlock(&sc223a->mutex);
....@@ -633,29 +928,40 @@
633928 struct sc223a *sc223a = to_sc223a(sd);
634929 const struct sc223a_mode *mode = sc223a->cur_mode;
635930
636
- mutex_lock(&sc223a->mutex);
637
- fi->interval = mode->max_fps;
638
- mutex_unlock(&sc223a->mutex);
931
+ if (sc223a->streaming)
932
+ fi->interval = sc223a->cur_fps;
933
+ else
934
+ fi->interval = mode->max_fps;
639935
640936 return 0;
641937 }
642938
643939 static int sc223a_g_mbus_config(struct v4l2_subdev *sd,
644
- struct v4l2_mbus_config *config)
940
+ unsigned int pad_id,
941
+ struct v4l2_mbus_config *config)
645942 {
646943 struct sc223a *sc223a = to_sc223a(sd);
647944 const struct sc223a_mode *mode = sc223a->cur_mode;
648
- u32 val = 1 << (SC223A_LANES - 1) |
649
- V4L2_MBUS_CSI2_CHANNEL_0 |
650
- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
651945
652
- if (mode->hdr_mode != NO_HDR)
653
- val |= V4L2_MBUS_CSI2_CHANNEL_1;
654
- if (mode->hdr_mode == HDR_X3)
655
- val |= V4L2_MBUS_CSI2_CHANNEL_2;
946
+ u32 val;
656947
657
- config->type = V4L2_MBUS_CSI2;
658
- config->flags = val;
948
+ if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
949
+ val = 1 << (SC223A_LANES - 1) |
950
+ V4L2_MBUS_CSI2_CHANNEL_0 |
951
+ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
952
+ if (mode->hdr_mode != NO_HDR)
953
+ val |= V4L2_MBUS_CSI2_CHANNEL_1;
954
+ if (mode->hdr_mode == HDR_X3)
955
+ val |= V4L2_MBUS_CSI2_CHANNEL_2;
956
+
957
+ config->type = V4L2_MBUS_CSI2_DPHY;
958
+ config->flags = val;
959
+ } else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
960
+ config->type = V4L2_MBUS_PARALLEL;
961
+ config->flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |
962
+ V4L2_MBUS_VSYNC_ACTIVE_LOW |
963
+ V4L2_MBUS_PCLK_SAMPLE_RISING;
964
+ }
659965
660966 return 0;
661967 }
....@@ -675,6 +981,7 @@
675981 struct sc223a *sc223a = to_sc223a(sd);
676982 struct rkmodule_hdr_cfg *hdr;
677983 u32 i, h, w;
984
+ u8 mode;
678985 long ret = 0;
679986 u32 stream = 0;
680987
....@@ -691,9 +998,11 @@
691998 hdr = (struct rkmodule_hdr_cfg *)arg;
692999 w = sc223a->cur_mode->width;
6931000 h = sc223a->cur_mode->height;
1001
+ mode = sc223a->cur_mode->mode_id;
6941002 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
6951003 if (w == supported_modes[i].width &&
6961004 h == supported_modes[i].height &&
1005
+ mode == supported_modes[i].mode_id &&
6971006 supported_modes[i].hdr_mode == hdr->hdr_mode) {
6981007 sc223a->cur_mode = &supported_modes[i];
6991008 break;
....@@ -710,7 +1019,10 @@
7101019 __v4l2_ctrl_modify_range(sc223a->hblank, w, w, 1, w);
7111020 __v4l2_ctrl_modify_range(sc223a->vblank, h,
7121021 SC223A_VTS_MAX - sc223a->cur_mode->height, 1, h);
1022
+ sc223a->cur_fps = sc223a->cur_mode->max_fps;
7131023 }
1024
+ break;
1025
+ case PREISP_CMD_SET_HDRAE_EXP:
7141026 break;
7151027 case RKMODULE_SET_QUICK_STREAM:
7161028
....@@ -738,6 +1050,7 @@
7381050 void __user *up = compat_ptr(arg);
7391051 struct rkmodule_inf *inf;
7401052 struct rkmodule_hdr_cfg *hdr;
1053
+ struct preisp_hdrae_exp_s *hdrae;
7411054 long ret;
7421055 u32 stream = 0;
7431056
....@@ -751,9 +1064,8 @@
7511064
7521065 ret = sc223a_ioctl(sd, cmd, inf);
7531066 if (!ret) {
754
- ret = copy_to_user(up, inf, sizeof(*inf));
755
- if (ret)
756
- return -EFAULT;
1067
+ if (copy_to_user(up, inf, sizeof(*inf)))
1068
+ ret = -EFAULT;
7571069 }
7581070 kfree(inf);
7591071 break;
....@@ -766,9 +1078,8 @@
7661078
7671079 ret = sc223a_ioctl(sd, cmd, hdr);
7681080 if (!ret) {
769
- ret = copy_to_user(up, hdr, sizeof(*hdr));
770
- if (ret)
771
- return -EFAULT;
1081
+ if (copy_to_user(up, hdr, sizeof(*hdr)))
1082
+ ret = -EFAULT;
7721083 }
7731084 kfree(hdr);
7741085 break;
....@@ -779,17 +1090,33 @@
7791090 return ret;
7801091 }
7811092
782
- if (copy_from_user(hdr, up, sizeof(*hdr)))
783
- return -EFAULT;
784
-
785
- ret = sc223a_ioctl(sd, cmd, hdr);
1093
+ ret = copy_from_user(hdr, up, sizeof(*hdr));
1094
+ if (!ret)
1095
+ ret = sc223a_ioctl(sd, cmd, hdr);
1096
+ else
1097
+ ret = -EFAULT;
7861098 kfree(hdr);
7871099 break;
788
- case RKMODULE_SET_QUICK_STREAM:
789
- if (copy_from_user(&stream, up, sizeof(u32)))
790
- return -EFAULT;
1100
+ case PREISP_CMD_SET_HDRAE_EXP:
1101
+ hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
1102
+ if (!hdrae) {
1103
+ ret = -ENOMEM;
1104
+ return ret;
1105
+ }
7911106
792
- ret = sc223a_ioctl(sd, cmd, &stream);
1107
+ ret = copy_from_user(hdrae, up, sizeof(*hdrae));
1108
+ if (!ret)
1109
+ ret = sc223a_ioctl(sd, cmd, hdrae);
1110
+ else
1111
+ ret = -EFAULT;
1112
+ kfree(hdrae);
1113
+ break;
1114
+ case RKMODULE_SET_QUICK_STREAM:
1115
+ ret = copy_from_user(&stream, up, sizeof(u32));
1116
+ if (!ret)
1117
+ ret = sc223a_ioctl(sd, cmd, &stream);
1118
+ else
1119
+ ret = -EFAULT;
7931120 break;
7941121 default:
7951122 ret = -ENOIOCTLCMD;
....@@ -804,35 +1131,41 @@
8041131 {
8051132 int ret;
8061133
807
- ret = sc223a_write_array(sc223a->client, sc223a->cur_mode->reg_list);
808
- if (ret)
809
- return ret;
810
-
811
- /* In case these controls are set before streaming */
812
- ret = __v4l2_ctrl_handler_setup(&sc223a->ctrl_handler);
813
- if (ret)
814
- return ret;
815
- if (sc223a->has_init_exp && sc223a->cur_mode->hdr_mode != NO_HDR) {
816
- ret = sc223a_ioctl(&sc223a->subdev, PREISP_CMD_SET_HDRAE_EXP,
817
- &sc223a->init_hdrae_exp);
818
- if (ret) {
819
- dev_err(&sc223a->client->dev,
820
- "init exp fail in hdr mode\n");
1134
+ if (!sc223a->is_thunderboot) {
1135
+ ret = sc223a_write_array(sc223a->client, sc223a->cur_mode->reg_list);
1136
+ if (ret)
8211137 return ret;
1138
+ /* In case these controls are set before streaming */
1139
+ ret = __v4l2_ctrl_handler_setup(&sc223a->ctrl_handler);
1140
+ if (ret)
1141
+ return ret;
1142
+ if (sc223a->has_init_exp && sc223a->cur_mode->hdr_mode != NO_HDR) {
1143
+ ret = sc223a_ioctl(&sc223a->subdev, PREISP_CMD_SET_HDRAE_EXP,
1144
+ &sc223a->init_hdrae_exp);
1145
+ if (ret) {
1146
+ dev_err(&sc223a->client->dev,
1147
+ "init exp fail in hdr mode\n");
1148
+ return ret;
1149
+ }
8221150 }
8231151 }
8241152
8251153 return sc223a_write_reg(sc223a->client, SC223A_REG_CTRL_MODE,
826
- SC223A_REG_VALUE_08BIT, SC223A_MODE_STREAMING);
1154
+ SC223A_REG_VALUE_08BIT, SC223A_MODE_STREAMING);
8271155 }
8281156
8291157 static int __sc223a_stop_stream(struct sc223a *sc223a)
8301158 {
8311159 sc223a->has_init_exp = false;
1160
+ if (sc223a->is_thunderboot) {
1161
+ sc223a->is_first_streamoff = true;
1162
+ pm_runtime_put(&sc223a->client->dev);
1163
+ }
8321164 return sc223a_write_reg(sc223a->client, SC223A_REG_CTRL_MODE,
8331165 SC223A_REG_VALUE_08BIT, SC223A_MODE_SW_STANDBY);
8341166 }
8351167
1168
+static int __sc223a_power_on(struct sc223a *sc223a);
8361169 static int sc223a_s_stream(struct v4l2_subdev *sd, int on)
8371170 {
8381171 struct sc223a *sc223a = to_sc223a(sd);
....@@ -843,14 +1176,16 @@
8431176 on = !!on;
8441177 if (on == sc223a->streaming)
8451178 goto unlock_and_return;
846
-
8471179 if (on) {
1180
+ if (sc223a->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1181
+ sc223a->is_thunderboot = false;
1182
+ __sc223a_power_on(sc223a);
1183
+ }
8481184 ret = pm_runtime_get_sync(&client->dev);
8491185 if (ret < 0) {
8501186 pm_runtime_put_noidle(&client->dev);
8511187 goto unlock_and_return;
8521188 }
853
-
8541189 ret = __sc223a_start_stream(sc223a);
8551190 if (ret) {
8561191 v4l2_err(sd, "start stream failed while write regs\n");
....@@ -863,10 +1198,8 @@
8631198 }
8641199
8651200 sc223a->streaming = on;
866
-
8671201 unlock_and_return:
8681202 mutex_unlock(&sc223a->mutex);
869
-
8701203 return ret;
8711204 }
8721205
....@@ -889,11 +1222,13 @@
8891222 goto unlock_and_return;
8901223 }
8911224
892
- ret = sc223a_write_array(sc223a->client, sc223a_global_regs);
893
- if (ret) {
894
- v4l2_err(sd, "could not set init registers\n");
895
- pm_runtime_put_noidle(&client->dev);
896
- goto unlock_and_return;
1225
+ if (!sc223a->is_thunderboot) {
1226
+ ret = sc223a_write_array(sc223a->client, sc223a_global_regs);
1227
+ if (ret) {
1228
+ v4l2_err(sd, "could not set init registers\n");
1229
+ pm_runtime_put_noidle(&client->dev);
1230
+ goto unlock_and_return;
1231
+ }
8971232 }
8981233
8991234 sc223a->power_on = true;
....@@ -936,6 +1271,10 @@
9361271 dev_err(dev, "Failed to enable xvclk\n");
9371272 return ret;
9381273 }
1274
+
1275
+ if (sc223a->is_thunderboot)
1276
+ return 0;
1277
+
9391278 if (!IS_ERR(sc223a->reset_gpio))
9401279 gpiod_set_value_cansleep(sc223a->reset_gpio, 0);
9411280
....@@ -949,6 +1288,7 @@
9491288 gpiod_set_value_cansleep(sc223a->reset_gpio, 1);
9501289
9511290 usleep_range(500, 1000);
1291
+
9521292 if (!IS_ERR(sc223a->pwdn_gpio))
9531293 gpiod_set_value_cansleep(sc223a->pwdn_gpio, 1);
9541294
....@@ -973,6 +1313,16 @@
9731313 {
9741314 int ret;
9751315 struct device *dev = &sc223a->client->dev;
1316
+
1317
+ clk_disable_unprepare(sc223a->xvclk);
1318
+ if (sc223a->is_thunderboot) {
1319
+ if (sc223a->is_first_streamoff) {
1320
+ sc223a->is_thunderboot = false;
1321
+ sc223a->is_first_streamoff = false;
1322
+ } else {
1323
+ return;
1324
+ }
1325
+ }
9761326
9771327 if (!IS_ERR(sc223a->pwdn_gpio))
9781328 gpiod_set_value_cansleep(sc223a->pwdn_gpio, 0);
....@@ -1067,7 +1417,6 @@
10671417 static const struct v4l2_subdev_video_ops sc223a_video_ops = {
10681418 .s_stream = sc223a_s_stream,
10691419 .g_frame_interval = sc223a_g_frame_interval,
1070
- .g_mbus_config = sc223a_g_mbus_config,
10711420 };
10721421
10731422 static const struct v4l2_subdev_pad_ops sc223a_pad_ops = {
....@@ -1076,6 +1425,7 @@
10761425 .enum_frame_interval = sc223a_enum_frame_interval,
10771426 .get_fmt = sc223a_get_fmt,
10781427 .set_fmt = sc223a_set_fmt,
1428
+ .get_mbus_config = sc223a_g_mbus_config,
10791429 };
10801430
10811431 static const struct v4l2_subdev_ops sc223a_subdev_ops = {
....@@ -1083,6 +1433,14 @@
10831433 .video = &sc223a_video_ops,
10841434 .pad = &sc223a_pad_ops,
10851435 };
1436
+
1437
+static void sc223a_modify_fps_info(struct sc223a *sc223a)
1438
+{
1439
+ const struct sc223a_mode *mode = sc223a->cur_mode;
1440
+
1441
+ sc223a->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1442
+ sc223a->cur_vts;
1443
+}
10861444
10871445 static int sc223a_set_ctrl(struct v4l2_ctrl *ctrl)
10881446 {
....@@ -1092,13 +1450,12 @@
10921450 s64 max;
10931451 int ret = 0;
10941452 u32 val = 0;
1095
- u32 reg = 0;
1453
+
10961454 /* Propagate change of current control to all related controls */
10971455 switch (ctrl->id) {
10981456 case V4L2_CID_VBLANK:
10991457 /* Update max exposure while meeting expected vblanking */
1100
- max = sc223a->cur_mode->height + ctrl->val - 4;
1101
-
1458
+ max = sc223a->cur_mode->height + ctrl->val - 10;
11021459 __v4l2_ctrl_modify_range(sc223a->exposure,
11031460 sc223a->exposure->minimum, max,
11041461 sc223a->exposure->step,
....@@ -1111,43 +1468,43 @@
11111468
11121469 switch (ctrl->id) {
11131470 case V4L2_CID_EXPOSURE:
1471
+ dev_dbg(&client->dev, "set exposure 0x%x\n", ctrl->val);
11141472 if (sc223a->cur_mode->hdr_mode == NO_HDR) {
1115
- val = ctrl->val < 2;
1116
-
1117
- ret = sc223a_read_reg(sc223a->client, SC223A_REG_EXPOSURE_H,
1118
- SC223A_REG_VALUE_08BIT, &reg);
1119
- ret |= sc223a_write_reg(sc223a->client,
1473
+ val = ctrl->val * 2;
1474
+ /* 4 least significant bits of expsoure are fractional part */
1475
+ ret = sc223a_write_reg(sc223a->client,
11201476 SC223A_REG_EXPOSURE_H,
11211477 SC223A_REG_VALUE_08BIT,
1122
- ((val >> 12) | (reg & 0xF0)));
1123
-
1478
+ SC223A_FETCH_EXP_H(val));
11241479 ret |= sc223a_write_reg(sc223a->client,
1125
- SC223A_REG_EXPOSURE_M,
1126
- SC223A_REG_VALUE_08BIT,
1127
- ((val >> 4) & 0xFF));
1128
-
1129
- ret |= sc223a_read_reg(sc223a->client, SC223A_REG_EXPOSURE_L,
1130
- SC223A_REG_VALUE_08BIT, &reg);
1480
+ SC223A_REG_EXPOSURE_M,
1481
+ SC223A_REG_VALUE_08BIT,
1482
+ SC223A_FETCH_EXP_M(val));
11311483 ret |= sc223a_write_reg(sc223a->client,
1132
- SC223A_REG_EXPOSURE_L,
1133
- SC223A_REG_VALUE_08BIT,
1134
- (((val & 0x0f) << 4) | (reg & 0x0F)));
1484
+ SC223A_REG_EXPOSURE_L,
1485
+ SC223A_REG_VALUE_08BIT,
1486
+ SC223A_FETCH_EXP_L(val));
11351487 }
11361488 break;
11371489 case V4L2_CID_ANALOGUE_GAIN:
1490
+ dev_dbg(&client->dev, "set gain 0x%x\n", ctrl->val);
11381491 if (sc223a->cur_mode->hdr_mode == NO_HDR)
11391492 ret = sc223a_set_gain_reg(sc223a, ctrl->val);
11401493 break;
11411494 case V4L2_CID_VBLANK:
1495
+ dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val);
11421496 ret = sc223a_write_reg(sc223a->client,
11431497 SC223A_REG_VTS_H,
11441498 SC223A_REG_VALUE_08BIT,
1145
- (ctrl->val + sc223a->cur_mode->height) >> 8);
1499
+ (ctrl->val + sc223a->cur_mode->height)
1500
+ >> 8);
11461501 ret |= sc223a_write_reg(sc223a->client,
11471502 SC223A_REG_VTS_L,
11481503 SC223A_REG_VALUE_08BIT,
1149
- (ctrl->val + sc223a->cur_mode->height) & 0xff);
1504
+ (ctrl->val + sc223a->cur_mode->height)
1505
+ & 0xff);
11501506 sc223a->cur_vts = ctrl->val + sc223a->cur_mode->height;
1507
+ sc223a_modify_fps_info(sc223a);
11511508 break;
11521509 case V4L2_CID_TEST_PATTERN:
11531510 ret = sc223a_enable_test_pattern(sc223a, ctrl->val);
....@@ -1197,13 +1554,18 @@
11971554 return ret;
11981555 handler->lock = &sc223a->mutex;
11991556
1200
- ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
1201
- 0, 0, link_freq_menu_items);
1202
- if (ctrl)
1203
- ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1557
+ if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
1558
+ ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
1559
+ 0, 0, link_freq_menu_items);
1560
+ if (ctrl)
1561
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1562
+ v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
1563
+ 0, PIXEL_RATE_WITH_405M_10BIT, 1, PIXEL_RATE_WITH_405M_10BIT);
1564
+ } else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
1565
+ v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
1566
+ 0, SC223A_PIXEL_RATE, 1, SC223A_PIXEL_RATE);
1567
+ }
12041568
1205
- v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
1206
- 0, PIXEL_RATE_WITH_371M_10BIT, 1, PIXEL_RATE_WITH_371M_10BIT);
12071569
12081570 h_blank = mode->hts_def - mode->width;
12091571 sc223a->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
....@@ -1215,7 +1577,7 @@
12151577 V4L2_CID_VBLANK, vblank_def,
12161578 SC223A_VTS_MAX - mode->height,
12171579 1, vblank_def);
1218
- exposure_max = mode->vts_def - 4;
1580
+ exposure_max = mode->vts_def - 10;
12191581 sc223a->exposure = v4l2_ctrl_new_std(handler, &sc223a_ctrl_ops,
12201582 V4L2_CID_EXPOSURE, SC223A_EXPOSURE_MIN,
12211583 exposure_max, SC223A_EXPOSURE_STEP,
....@@ -1231,10 +1593,8 @@
12311593 0, 0, sc223a_test_pattern_menu);
12321594 v4l2_ctrl_new_std(handler, &sc223a_ctrl_ops,
12331595 V4L2_CID_HFLIP, 0, 1, 1, 0);
1234
-
12351596 v4l2_ctrl_new_std(handler, &sc223a_ctrl_ops,
12361597 V4L2_CID_VFLIP, 0, 1, 1, 0);
1237
-
12381598 if (handler->error) {
12391599 ret = handler->error;
12401600 dev_err(&sc223a->client->dev,
....@@ -1244,6 +1604,7 @@
12441604
12451605 sc223a->subdev.ctrl_handler = handler;
12461606 sc223a->has_init_exp = false;
1607
+ sc223a->cur_fps = mode->max_fps;
12471608
12481609 return 0;
12491610
....@@ -1259,6 +1620,11 @@
12591620 struct device *dev = &sc223a->client->dev;
12601621 u32 id = 0;
12611622 int ret;
1623
+
1624
+ if (sc223a->is_thunderboot) {
1625
+ dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1626
+ return 0;
1627
+ }
12621628
12631629 ret = sc223a_read_reg(client, SC223A_REG_CHIP_ID,
12641630 SC223A_REG_VALUE_16BIT, &id);
....@@ -1293,7 +1659,7 @@
12931659 struct v4l2_subdev *sd;
12941660 char facing[2];
12951661 int ret;
1296
- u32 i, hdr_mode = 0;
1662
+ int i, hdr_mode = 0;
12971663
12981664 dev_info(dev, "driver version: %02x.%02x.%02x",
12991665 DRIVER_VERSION >> 16,
....@@ -1304,7 +1670,6 @@
13041670 if (!sc223a)
13051671 return -ENOMEM;
13061672
1307
- of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
13081673 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
13091674 &sc223a->module_index);
13101675 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
....@@ -1313,20 +1678,28 @@
13131678 &sc223a->module_name);
13141679 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
13151680 &sc223a->len_name);
1681
+ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_MODE,
1682
+ &sc223a->mode);
13161683 if (ret) {
13171684 dev_err(dev, "could not get module information!\n");
13181685 return -EINVAL;
13191686 }
13201687
1688
+ sc223a->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
1689
+
13211690 sc223a->client = client;
1322
- for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1323
- if (hdr_mode == supported_modes[i].hdr_mode) {
1324
- sc223a->cur_mode = &supported_modes[i];
1325
- break;
1691
+ if (!strcmp(sc223a->mode, CAMERA_MIPI_MODE)) {
1692
+ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1693
+ if (hdr_mode == supported_modes[i].hdr_mode) {
1694
+ sc223a->cur_mode = &supported_modes[i];
1695
+ break;
1696
+ }
13261697 }
1698
+ if (i == ARRAY_SIZE(supported_modes))
1699
+ sc223a->cur_mode = &supported_modes[SC223A_MIPI_1920X1080];
1700
+ } else if (!strcmp(sc223a->mode, CAMERA_DVP_MODE)) {
1701
+ sc223a->cur_mode = &supported_modes[SC223A_DVP_1920X1080];
13271702 }
1328
- if (i == ARRAY_SIZE(supported_modes))
1329
- sc223a->cur_mode = &supported_modes[0];
13301703
13311704 sc223a->xvclk = devm_clk_get(dev, "xvclk");
13321705 if (IS_ERR(sc223a->xvclk)) {
....@@ -1334,13 +1707,23 @@
13341707 return -EINVAL;
13351708 }
13361709
1337
- sc223a->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1338
- if (IS_ERR(sc223a->reset_gpio))
1339
- dev_warn(dev, "Failed to get reset-gpios\n");
1710
+ if (sc223a->is_thunderboot) {
1711
+ sc223a->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
1712
+ if (IS_ERR(sc223a->reset_gpio))
1713
+ dev_warn(dev, "Failed to get reset-gpios\n");
13401714
1341
- sc223a->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1342
- if (IS_ERR(sc223a->pwdn_gpio))
1343
- dev_warn(dev, "Failed to get pwdn-gpios\n");
1715
+ sc223a->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
1716
+ if (IS_ERR(sc223a->pwdn_gpio))
1717
+ dev_warn(dev, "Failed to get pwdn-gpios\n");
1718
+ } else {
1719
+ sc223a->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1720
+ if (IS_ERR(sc223a->reset_gpio))
1721
+ dev_warn(dev, "Failed to get reset-gpios\n");
1722
+
1723
+ sc223a->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1724
+ if (IS_ERR(sc223a->pwdn_gpio))
1725
+ dev_warn(dev, "Failed to get pwdn-gpios\n");
1726
+ }
13441727
13451728 sc223a->pinctrl = devm_pinctrl_get(dev);
13461729 if (!IS_ERR(sc223a->pinctrl)) {
....@@ -1411,7 +1794,10 @@
14111794
14121795 pm_runtime_set_active(dev);
14131796 pm_runtime_enable(dev);
1414
- pm_runtime_idle(dev);
1797
+ if (sc223a->is_thunderboot)
1798
+ pm_runtime_get_sync(dev);
1799
+ else
1800
+ pm_runtime_idle(dev);
14151801
14161802 return 0;
14171803
....@@ -1483,8 +1869,12 @@
14831869 i2c_del_driver(&sc223a_i2c_driver);
14841870 }
14851871
1872
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
1873
+subsys_initcall(sensor_mod_init);
1874
+#else
14861875 device_initcall_sync(sensor_mod_init);
1876
+#endif
14871877 module_exit(sensor_mod_exit);
14881878
14891879 MODULE_DESCRIPTION("smartsens sc223a sensor driver");
1490
-MODULE_LICENSE("GPL v2");
1880
+MODULE_LICENSE("GPL");