forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/sc200ai.c
....@@ -11,8 +11,11 @@
1111 * V0.0X01.0X05 add quick stream on/off.
1212 * V0.0X01.0X06 fix set vflip/hflip failed bug.
1313 * V0.0X01.0X07
14
- * 1. fix set double times exposue value failed issue.
15
- * 2. add some debug info.
14
+ * 1. fix set double times exposue value failed issue.
15
+ * 2. add some debug info.
16
+ * V0.0X01.0X08
17
+ * 1. add support wakeup & sleep for aov function
18
+ * 2. using 60fps output default
1619 */
1720
1821 #include <linux/clk.h>
....@@ -33,8 +36,11 @@
3336 #include <media/v4l2-ctrls.h>
3437 #include <media/v4l2-subdev.h>
3538 #include <linux/pinctrl/consumer.h>
39
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
40
+#include "cam-tb-setup.h"
41
+#include "cam-sleep-wakeup.h"
3642
37
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x07)
43
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x08)
3844
3945 #ifndef V4L2_CID_DIGITAL_GAIN
4046 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
....@@ -46,6 +52,7 @@
4652
4753 #define PIXEL_RATE_WITH_371M_10BIT (SC200AI_LINK_FREQ_371 * 2 * \
4854 SC200AI_LANES / SC200AI_BITS_PER_SAMPLE)
55
+
4956 #define SC200AI_XVCLK_FREQ 27000000
5057
5158 #define CHIP_ID 0xcb1c
....@@ -125,14 +132,6 @@
125132
126133 #define SC200AI_NUM_SUPPLIES ARRAY_SIZE(sc200ai_supply_names)
127134
128
-enum sc200ai_max_pad {
129
- PAD0, /* link to isp */
130
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
131
- PAD2, /* link to csi wr1 | hdr x3:L */
132
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
133
- PAD_MAX,
134
-};
135
-
136135 struct regval {
137136 u16 addr;
138137 u8 val;
....@@ -172,6 +171,7 @@
172171 struct v4l2_ctrl *vblank;
173172 struct v4l2_ctrl *test_pattern;
174173 struct mutex mutex;
174
+ struct v4l2_fract cur_fps;
175175 bool streaming;
176176 bool power_on;
177177 const struct sc200ai_mode *cur_mode;
....@@ -181,7 +181,10 @@
181181 const char *len_name;
182182 u32 cur_vts;
183183 bool has_init_exp;
184
+ bool is_thunderboot;
185
+ bool is_first_streamoff;
184186 struct preisp_hdrae_exp_s init_hdrae_exp;
187
+ struct cam_sw_info *cam_sw_inf;
185188 };
186189
187190 #define to_sc200ai(sd) container_of(sd, struct sc200ai, subdev)
....@@ -195,10 +198,10 @@
195198
196199 /*
197200 * Xclk 24Mhz
198
- * max_framerate 90fps
201
+ * max_framerate 60fps
199202 * mipi_datarate per lane 1008Mbps, 4lane
200203 */
201
-static const struct regval sc200ai_linear_10_1920x1080_regs[] = {
204
+static const struct regval sc200ai_linear_10_1920x1080_60fps_regs[] = {
202205 {0x0103, 0x01},
203206 {0x0100, 0x00},
204207 {0x36e9, 0x80},
....@@ -338,6 +341,113 @@
338341 /*
339342 * Xclk 27Mhz
340343 * max_framerate 30fps
344
+ * mipi_datarate per lane 371.25Mbps, 2lane
345
+ */
346
+static const struct regval sc200ai_linear_10_1920x1080_30fps_regs[] = {
347
+ {0x0103, 0x01},
348
+ {0x0100, 0x00},
349
+ {0x36e9, 0x80},
350
+ {0x36f9, 0x80},
351
+ {0x301f, 0x03},
352
+ //HTS=1100*2=2200
353
+ {0x320c, 0x04},
354
+ {0x320d, 0x4c},
355
+ //VTS=1125
356
+ {0x320e, 0x04},
357
+ {0x320f, 0x65},
358
+ {0x3243, 0x01},
359
+ {0x3248, 0x02},
360
+ {0x3249, 0x09},
361
+ {0x3253, 0x08},
362
+ {0x3271, 0x0a},
363
+ {0x3301, 0x20},
364
+ {0x3304, 0x40},
365
+ {0x3306, 0x32},
366
+ {0x330b, 0x88},
367
+ {0x330f, 0x02},
368
+ {0x331e, 0x39},
369
+ {0x3333, 0x10},
370
+ {0x3621, 0xe8},
371
+ {0x3622, 0x16},
372
+ {0x3637, 0x1b},
373
+ {0x363a, 0x1f},
374
+ {0x363b, 0xc6},
375
+ {0x363c, 0x0e},
376
+ {0x3670, 0x0a},
377
+ {0x3674, 0x82},
378
+ {0x3675, 0x76},
379
+ {0x3676, 0x78},
380
+ {0x367c, 0x48},
381
+ {0x367d, 0x58},
382
+ {0x3690, 0x34},
383
+ {0x3691, 0x33},
384
+ {0x3692, 0x44},
385
+ {0x369c, 0x40},
386
+ {0x369d, 0x48},
387
+ {0x3901, 0x02},
388
+ {0x3904, 0x04},
389
+ {0x3908, 0x41},
390
+ {0x391d, 0x14},
391
+ {0x391f, 0x18},
392
+ {0x3e01, 0x8c},
393
+ {0x3e02, 0x20},
394
+ {0x3e16, 0x00},
395
+ {0x3e17, 0x80},
396
+ {0x3f09, 0x48},
397
+ {0x5787, 0x10},
398
+ {0x5788, 0x06},
399
+ {0x578a, 0x10},
400
+ {0x578b, 0x06},
401
+ {0x5790, 0x10},
402
+ {0x5791, 0x10},
403
+ {0x5792, 0x00},
404
+ {0x5793, 0x10},
405
+ {0x5794, 0x10},
406
+ {0x5795, 0x00},
407
+ {0x5799, 0x00},
408
+ {0x57c7, 0x10},
409
+ {0x57c8, 0x06},
410
+ {0x57ca, 0x10},
411
+ {0x57cb, 0x06},
412
+ {0x57d1, 0x10},
413
+ {0x57d4, 0x10},
414
+ {0x57d9, 0x00},
415
+ {0x59e0, 0x60},
416
+ {0x59e1, 0x08},
417
+ {0x59e2, 0x3f},
418
+ {0x59e3, 0x18},
419
+ {0x59e4, 0x18},
420
+ {0x59e5, 0x3f},
421
+ {0x59e6, 0x06},
422
+ {0x59e7, 0x02},
423
+ {0x59e8, 0x38},
424
+ {0x59e9, 0x10},
425
+ {0x59ea, 0x0c},
426
+ {0x59eb, 0x10},
427
+ {0x59ec, 0x04},
428
+ {0x59ed, 0x02},
429
+ {0x59ee, 0xa0},
430
+ {0x59ef, 0x08},
431
+ {0x59f4, 0x18},
432
+ {0x59f5, 0x10},
433
+ {0x59f6, 0x0c},
434
+ {0x59f7, 0x10},
435
+ {0x59f8, 0x06},
436
+ {0x59f9, 0x02},
437
+ {0x59fa, 0x18},
438
+ {0x59fb, 0x10},
439
+ {0x59fc, 0x0c},
440
+ {0x59fd, 0x10},
441
+ {0x59fe, 0x04},
442
+ {0x59ff, 0x02},
443
+ {0x36e9, 0x20},
444
+ {0x36f9, 0x27},
445
+ {REG_NULL, 0x00},
446
+};
447
+
448
+/*
449
+ * Xclk 27Mhz
450
+ * max_framerate 30fps
341451 * mipi_datarate per lane 742.5Mbps, HDR 2lane
342452 */
343453 static const struct regval sc200ai_hdr_10_1920x1080_regs[] = {
....@@ -346,8 +456,12 @@
346456 {0x36e9, 0x80},
347457 {0x36f9, 0x80},
348458 {0x301f, 0x02},
459
+ //HTS=1100*2=2200
460
+ {0x320c, 0x04},
461
+ {0x320d, 0x4c},
462
+ //VTS =2252
349463 {0x320e, 0x08},
350
- {0x320f, 0xca},
464
+ {0x320f, 0xcc},
351465 {0x3220, 0x53},
352466 {0x3243, 0x01},
353467 {0x3248, 0x02},
....@@ -372,9 +486,11 @@
372486 {0x331f, 0x61},
373487 {0x3320, 0x07},
374488 {0x3333, 0x10},
489
+ {0x3347, 0x77},
375490 {0x334c, 0x08},
376491 {0x3356, 0x09},
377492 {0x3364, 0x17},
493
+ {0x336c, 0xcc},
378494 {0x3390, 0x08},
379495 {0x3391, 0x18},
380496 {0x3392, 0x38},
....@@ -431,8 +547,8 @@
431547 {0x3e13, 0x40},
432548 {0x3e16, 0x00},
433549 {0x3e17, 0x80},
434
- {0x3e23, 0x00},
435
- {0x3e24, 0x40},
550
+ {0x3e23, 0x01},
551
+ {0x3e24, 0x9e},
436552 {0x3f09, 0x48},
437553 {0x4816, 0xb1},
438554 {0x4819, 0x09},
....@@ -507,10 +623,11 @@
507623 .hts_def = 0x44C * 2,
508624 .vts_def = 0x0465,
509625 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
510
- .reg_list = sc200ai_linear_10_1920x1080_regs,
626
+ .reg_list = sc200ai_linear_10_1920x1080_60fps_regs,
511627 .hdr_mode = NO_HDR,
512628 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
513
- }, {
629
+ },
630
+ {
514631 .width = 1920,
515632 .height = 1080,
516633 .max_fps = {
....@@ -519,7 +636,22 @@
519636 },
520637 .exp_def = 0x0080,
521638 .hts_def = 0x44C * 2,
522
- .vts_def = 0x08CA,
639
+ .vts_def = 0x0465,
640
+ .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
641
+ .reg_list = sc200ai_linear_10_1920x1080_30fps_regs,
642
+ .hdr_mode = NO_HDR,
643
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
644
+ },
645
+ {
646
+ .width = 1920,
647
+ .height = 1080,
648
+ .max_fps = {
649
+ .numerator = 10000,
650
+ .denominator = 300000,
651
+ },
652
+ .exp_def = 0x0080,
653
+ .hts_def = 0x44C * 2,
654
+ .vts_def = 0x08CC,
523655 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
524656 .reg_list = sc200ai_hdr_10_1920x1080_regs,
525657 .hdr_mode = HDR_X2,
....@@ -814,8 +946,8 @@
814946 s_exp_time = s_exp_time * 2;
815947 if (l_exp_time > 4362) //(2250 - 64 - 5) * 2
816948 l_exp_time = 4362;
817
- if (s_exp_time > 118) //(64 - 5) * 2
818
- s_exp_time = 118;
949
+ if (s_exp_time > 404) //(64 - 5) * 2
950
+ s_exp_time = 404;
819951
820952 ret = sc200ai_write_reg(sc200ai->client,
821953 SC200AI_REG_EXPOSURE_H,
....@@ -837,7 +969,6 @@
837969 SC200AI_REG_SEXPOSURE_L,
838970 SC200AI_REG_VALUE_08BIT,
839971 SC200AI_FETCH_EXP_L(s_exp_time));
840
-
841972
842973 ret |= sc200ai_set_gain_reg(sc200ai, l_a_gain, SC200AI_LGAIN);
843974 ret |= sc200ai_set_gain_reg(sc200ai, s_a_gain, SC200AI_SGAIN);
....@@ -902,6 +1033,8 @@
9021033 __v4l2_ctrl_modify_range(sc200ai->vblank, vblank_def,
9031034 SC200AI_VTS_MAX - mode->height,
9041035 1, vblank_def);
1036
+ sc200ai->cur_fps = mode->max_fps;
1037
+ sc200ai->cur_vts = mode->vts_def;
9051038 }
9061039
9071040 mutex_unlock(&sc200ai->mutex);
....@@ -994,14 +1127,15 @@
9941127 struct sc200ai *sc200ai = to_sc200ai(sd);
9951128 const struct sc200ai_mode *mode = sc200ai->cur_mode;
9961129
997
- mutex_lock(&sc200ai->mutex);
998
- fi->interval = mode->max_fps;
999
- mutex_unlock(&sc200ai->mutex);
1130
+ if (sc200ai->streaming)
1131
+ fi->interval = sc200ai->cur_fps;
1132
+ else
1133
+ fi->interval = mode->max_fps;
10001134
10011135 return 0;
10021136 }
10031137
1004
-static int sc200ai_g_mbus_config(struct v4l2_subdev *sd,
1138
+static int sc200ai_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
10051139 struct v4l2_mbus_config *config)
10061140 {
10071141 struct sc200ai *sc200ai = to_sc200ai(sd);
....@@ -1015,7 +1149,7 @@
10151149 if (mode->hdr_mode == HDR_X3)
10161150 val |= V4L2_MBUS_CSI2_CHANNEL_2;
10171151
1018
- config->type = V4L2_MBUS_CSI2;
1152
+ config->type = V4L2_MBUS_CSI2_DPHY;
10191153 config->flags = val;
10201154
10211155 return 0;
....@@ -1031,10 +1165,22 @@
10311165 strlcpy(inf->base.lens, sc200ai->len_name, sizeof(inf->base.lens));
10321166 }
10331167
1168
+static int sc200ai_get_channel_info(struct sc200ai *sc200ai, struct rkmodule_channel_info *ch_info)
1169
+{
1170
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
1171
+ return -EINVAL;
1172
+ ch_info->vc = sc200ai->cur_mode->vc[ch_info->index];
1173
+ ch_info->width = sc200ai->cur_mode->width;
1174
+ ch_info->height = sc200ai->cur_mode->height;
1175
+ ch_info->bus_fmt = sc200ai->cur_mode->bus_fmt;
1176
+ return 0;
1177
+}
1178
+
10341179 static long sc200ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
10351180 {
10361181 struct sc200ai *sc200ai = to_sc200ai(sd);
10371182 struct rkmodule_hdr_cfg *hdr;
1183
+ struct rkmodule_channel_info *ch_info;
10381184 u32 i, h, w;
10391185 long ret = 0;
10401186 u32 stream = 0;
....@@ -1071,21 +1217,33 @@
10711217 __v4l2_ctrl_modify_range(sc200ai->hblank, w, w, 1, w);
10721218 __v4l2_ctrl_modify_range(sc200ai->vblank, h,
10731219 SC200AI_VTS_MAX - sc200ai->cur_mode->height, 1, h);
1220
+ sc200ai->cur_fps = sc200ai->cur_mode->max_fps;
1221
+ sc200ai->cur_vts = sc200ai->cur_mode->vts_def;
10741222 }
10751223 break;
10761224 case PREISP_CMD_SET_HDRAE_EXP:
10771225 sc200ai_set_hdrae(sc200ai, arg);
1226
+ if (sc200ai->cam_sw_inf)
1227
+ memcpy(&sc200ai->cam_sw_inf->hdr_ae, (struct preisp_hdrae_exp_s *)(arg),
1228
+ sizeof(struct preisp_hdrae_exp_s));
10781229 break;
10791230 case RKMODULE_SET_QUICK_STREAM:
10801231
10811232 stream = *((u32 *)arg);
10821233
1083
- if (stream)
1234
+ if (stream) {
1235
+ gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 1);
10841236 ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
10851237 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
1086
- else
1238
+ } else {
10871239 ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
10881240 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
1241
+ gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 0);
1242
+ }
1243
+ break;
1244
+ case RKMODULE_GET_CHANNEL_INFO:
1245
+ ch_info = (struct rkmodule_channel_info *)arg;
1246
+ ret = sc200ai_get_channel_info(sc200ai, ch_info);
10891247 break;
10901248 default:
10911249 ret = -ENOIOCTLCMD;
....@@ -1104,6 +1262,7 @@
11041262 struct rkmodule_awb_cfg *cfg;
11051263 struct rkmodule_hdr_cfg *hdr;
11061264 struct preisp_hdrae_exp_s *hdrae;
1265
+ struct rkmodule_channel_info *ch_info;
11071266 long ret;
11081267 u32 stream = 0;
11091268
....@@ -1116,8 +1275,11 @@
11161275 }
11171276
11181277 ret = sc200ai_ioctl(sd, cmd, inf);
1119
- if (!ret)
1278
+ if (!ret) {
11201279 ret = copy_to_user(up, inf, sizeof(*inf));
1280
+ if (ret)
1281
+ ret = -EFAULT;
1282
+ }
11211283 kfree(inf);
11221284 break;
11231285 case RKMODULE_AWB_CFG:
....@@ -1130,6 +1292,8 @@
11301292 ret = copy_from_user(cfg, up, sizeof(*cfg));
11311293 if (!ret)
11321294 ret = sc200ai_ioctl(sd, cmd, cfg);
1295
+ else
1296
+ ret = -EFAULT;
11331297 kfree(cfg);
11341298 break;
11351299 case RKMODULE_GET_HDR_CFG:
....@@ -1140,8 +1304,11 @@
11401304 }
11411305
11421306 ret = sc200ai_ioctl(sd, cmd, hdr);
1143
- if (!ret)
1307
+ if (!ret) {
11441308 ret = copy_to_user(up, hdr, sizeof(*hdr));
1309
+ if (ret)
1310
+ ret = -EFAULT;
1311
+ }
11451312 kfree(hdr);
11461313 break;
11471314 case RKMODULE_SET_HDR_CFG:
....@@ -1154,6 +1321,8 @@
11541321 ret = copy_from_user(hdr, up, sizeof(*hdr));
11551322 if (!ret)
11561323 ret = sc200ai_ioctl(sd, cmd, hdr);
1324
+ else
1325
+ ret = -EFAULT;
11571326 kfree(hdr);
11581327 break;
11591328 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1166,12 +1335,31 @@
11661335 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
11671336 if (!ret)
11681337 ret = sc200ai_ioctl(sd, cmd, hdrae);
1338
+ else
1339
+ ret = -EFAULT;
11691340 kfree(hdrae);
11701341 break;
11711342 case RKMODULE_SET_QUICK_STREAM:
11721343 ret = copy_from_user(&stream, up, sizeof(u32));
11731344 if (!ret)
11741345 ret = sc200ai_ioctl(sd, cmd, &stream);
1346
+ else
1347
+ ret = -EFAULT;
1348
+ break;
1349
+ case RKMODULE_GET_CHANNEL_INFO:
1350
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
1351
+ if (!ch_info) {
1352
+ ret = -ENOMEM;
1353
+ return ret;
1354
+ }
1355
+
1356
+ ret = sc200ai_ioctl(sd, cmd, ch_info);
1357
+ if (!ret) {
1358
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
1359
+ if (ret)
1360
+ ret = -EFAULT;
1361
+ }
1362
+ kfree(ch_info);
11751363 break;
11761364 default:
11771365 ret = -ENOIOCTLCMD;
....@@ -1186,21 +1374,30 @@
11861374 {
11871375 int ret;
11881376
1189
- ret = sc200ai_write_array(sc200ai->client, sc200ai->cur_mode->reg_list);
1190
- if (ret)
1191
- return ret;
1192
-
1193
- /* In case these controls are set before streaming */
1194
- ret = __v4l2_ctrl_handler_setup(&sc200ai->ctrl_handler);
1195
- if (ret)
1196
- return ret;
1197
- if (sc200ai->has_init_exp && sc200ai->cur_mode->hdr_mode != NO_HDR) {
1198
- ret = sc200ai_ioctl(&sc200ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1199
- &sc200ai->init_hdrae_exp);
1200
- if (ret) {
1201
- dev_err(&sc200ai->client->dev,
1202
- "init exp fail in hdr mode\n");
1377
+ dev_info(&sc200ai->client->dev,
1378
+ "%dx%d@%d, mode %d, vts 0x%x\n",
1379
+ sc200ai->cur_mode->width,
1380
+ sc200ai->cur_mode->height,
1381
+ sc200ai->cur_fps.denominator / sc200ai->cur_fps.numerator,
1382
+ sc200ai->cur_mode->hdr_mode,
1383
+ sc200ai->cur_vts);
1384
+ if (!sc200ai->is_thunderboot) {
1385
+ ret = sc200ai_write_array(sc200ai->client, sc200ai->cur_mode->reg_list);
1386
+ if (ret)
12031387 return ret;
1388
+
1389
+ /* In case these controls are set before streaming */
1390
+ ret = __v4l2_ctrl_handler_setup(&sc200ai->ctrl_handler);
1391
+ if (ret)
1392
+ return ret;
1393
+ if (sc200ai->has_init_exp && sc200ai->cur_mode->hdr_mode != NO_HDR) {
1394
+ ret = sc200ai_ioctl(&sc200ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1395
+ &sc200ai->init_hdrae_exp);
1396
+ if (ret) {
1397
+ dev_err(&sc200ai->client->dev,
1398
+ "init exp fail in hdr mode\n");
1399
+ return ret;
1400
+ }
12041401 }
12051402 }
12061403
....@@ -1211,10 +1408,15 @@
12111408 static int __sc200ai_stop_stream(struct sc200ai *sc200ai)
12121409 {
12131410 sc200ai->has_init_exp = false;
1411
+ if (sc200ai->is_thunderboot) {
1412
+ sc200ai->is_first_streamoff = true;
1413
+ pm_runtime_put(&sc200ai->client->dev);
1414
+ }
12141415 return sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
12151416 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
12161417 }
12171418
1419
+static int __sc200ai_power_on(struct sc200ai *sc200ai);
12181420 static int sc200ai_s_stream(struct v4l2_subdev *sd, int on)
12191421 {
12201422 struct sc200ai *sc200ai = to_sc200ai(sd);
....@@ -1227,6 +1429,10 @@
12271429 goto unlock_and_return;
12281430
12291431 if (on) {
1432
+ if (sc200ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1433
+ sc200ai->is_thunderboot = false;
1434
+ __sc200ai_power_on(sc200ai);
1435
+ }
12301436 ret = pm_runtime_get_sync(&client->dev);
12311437 if (ret < 0) {
12321438 pm_runtime_put_noidle(&client->dev);
....@@ -1271,11 +1477,13 @@
12711477 goto unlock_and_return;
12721478 }
12731479
1274
- ret = sc200ai_write_array(sc200ai->client, sc200ai_global_regs);
1275
- if (ret) {
1276
- v4l2_err(sd, "could not set init registers\n");
1277
- pm_runtime_put_noidle(&client->dev);
1278
- goto unlock_and_return;
1480
+ if (!sc200ai->is_thunderboot) {
1481
+ ret = sc200ai_write_array(sc200ai->client, sc200ai_global_regs);
1482
+ if (ret) {
1483
+ v4l2_err(sd, "could not set init registers\n");
1484
+ pm_runtime_put_noidle(&client->dev);
1485
+ goto unlock_and_return;
1486
+ }
12791487 }
12801488
12811489 sc200ai->power_on = true;
....@@ -1318,6 +1526,12 @@
13181526 dev_err(dev, "Failed to enable xvclk\n");
13191527 return ret;
13201528 }
1529
+
1530
+ cam_sw_regulator_bulk_init(sc200ai->cam_sw_inf, SC200AI_NUM_SUPPLIES, sc200ai->supplies);
1531
+
1532
+ if (sc200ai->is_thunderboot)
1533
+ return 0;
1534
+
13211535 if (!IS_ERR(sc200ai->reset_gpio))
13221536 gpiod_set_value_cansleep(sc200ai->reset_gpio, 0);
13231537
....@@ -1356,6 +1570,15 @@
13561570 int ret;
13571571 struct device *dev = &sc200ai->client->dev;
13581572
1573
+ clk_disable_unprepare(sc200ai->xvclk);
1574
+ if (sc200ai->is_thunderboot) {
1575
+ if (sc200ai->is_first_streamoff) {
1576
+ sc200ai->is_thunderboot = false;
1577
+ sc200ai->is_first_streamoff = false;
1578
+ } else {
1579
+ return;
1580
+ }
1581
+ }
13591582 if (!IS_ERR(sc200ai->pwdn_gpio))
13601583 gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 0);
13611584 clk_disable_unprepare(sc200ai->xvclk);
....@@ -1369,6 +1592,51 @@
13691592 }
13701593 regulator_bulk_disable(SC200AI_NUM_SUPPLIES, sc200ai->supplies);
13711594 }
1595
+
1596
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
1597
+static int __maybe_unused sc200ai_resume(struct device *dev)
1598
+{
1599
+ int ret;
1600
+ struct i2c_client *client = to_i2c_client(dev);
1601
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1602
+ struct sc200ai *sc200ai = to_sc200ai(sd);
1603
+
1604
+ cam_sw_prepare_wakeup(sc200ai->cam_sw_inf, dev);
1605
+
1606
+ usleep_range(4000, 5000);
1607
+ cam_sw_write_array(sc200ai->cam_sw_inf);
1608
+
1609
+ if (__v4l2_ctrl_handler_setup(&sc200ai->ctrl_handler))
1610
+ dev_err(dev, "__v4l2_ctrl_handler_setup fail!");
1611
+
1612
+ if (sc200ai->has_init_exp && sc200ai->cur_mode != NO_HDR) { // hdr mode
1613
+ ret = sc200ai_ioctl(&sc200ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1614
+ &sc200ai->cam_sw_inf->hdr_ae);
1615
+ if (ret) {
1616
+ dev_err(&sc200ai->client->dev, "set exp fail in hdr mode\n");
1617
+ return ret;
1618
+ }
1619
+ }
1620
+ return 0;
1621
+}
1622
+
1623
+static int __maybe_unused sc200ai_suspend(struct device *dev)
1624
+{
1625
+ struct i2c_client *client = to_i2c_client(dev);
1626
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1627
+ struct sc200ai *sc200ai = to_sc200ai(sd);
1628
+
1629
+ cam_sw_write_array_cb_init(sc200ai->cam_sw_inf, client,
1630
+ (void *)sc200ai->cur_mode->reg_list,
1631
+ (sensor_write_array)sc200ai_write_array);
1632
+ cam_sw_prepare_sleep(sc200ai->cam_sw_inf);
1633
+
1634
+ return 0;
1635
+}
1636
+#else
1637
+#define sc200ai_resume NULL
1638
+#define sc200ai_suspend NULL
1639
+#endif
13721640
13731641 static int sc200ai_runtime_resume(struct device *dev)
13741642 {
....@@ -1430,6 +1698,7 @@
14301698 static const struct dev_pm_ops sc200ai_pm_ops = {
14311699 SET_RUNTIME_PM_OPS(sc200ai_runtime_suspend,
14321700 sc200ai_runtime_resume, NULL)
1701
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(sc200ai_suspend, sc200ai_resume)
14331702 };
14341703
14351704 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
....@@ -1449,7 +1718,6 @@
14491718 static const struct v4l2_subdev_video_ops sc200ai_video_ops = {
14501719 .s_stream = sc200ai_s_stream,
14511720 .g_frame_interval = sc200ai_g_frame_interval,
1452
- .g_mbus_config = sc200ai_g_mbus_config,
14531721 };
14541722
14551723 static const struct v4l2_subdev_pad_ops sc200ai_pad_ops = {
....@@ -1458,6 +1726,7 @@
14581726 .enum_frame_interval = sc200ai_enum_frame_interval,
14591727 .get_fmt = sc200ai_get_fmt,
14601728 .set_fmt = sc200ai_set_fmt,
1729
+ .get_mbus_config = sc200ai_g_mbus_config,
14611730 };
14621731
14631732 static const struct v4l2_subdev_ops sc200ai_subdev_ops = {
....@@ -1465,6 +1734,14 @@
14651734 .video = &sc200ai_video_ops,
14661735 .pad = &sc200ai_pad_ops,
14671736 };
1737
+
1738
+static void sc200ai_modify_fps_info(struct sc200ai *sc200ai)
1739
+{
1740
+ const struct sc200ai_mode *mode = sc200ai->cur_mode;
1741
+
1742
+ sc200ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def/
1743
+ sc200ai->cur_vts;
1744
+}
14681745
14691746 static int sc200ai_set_ctrl(struct v4l2_ctrl *ctrl)
14701747 {
....@@ -1528,7 +1805,9 @@
15281805 SC200AI_REG_VALUE_08BIT,
15291806 (ctrl->val + sc200ai->cur_mode->height)
15301807 & 0xff);
1531
- sc200ai->cur_vts = ctrl->val + sc200ai->cur_mode->height;
1808
+ if (!ret)
1809
+ sc200ai->cur_vts = ctrl->val + sc200ai->cur_mode->height;
1810
+ sc200ai_modify_fps_info(sc200ai);
15321811 break;
15331812 case V4L2_CID_TEST_PATTERN:
15341813 ret = sc200ai_enable_test_pattern(sc200ai, ctrl->val);
....@@ -1591,12 +1870,14 @@
15911870 h_blank, h_blank, 1, h_blank);
15921871 if (sc200ai->hblank)
15931872 sc200ai->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1873
+ sc200ai->cur_fps = mode->max_fps;
15941874 vblank_def = mode->vts_def - mode->height;
1875
+ sc200ai->cur_vts = mode->vts_def;
15951876 sc200ai->vblank = v4l2_ctrl_new_std(handler, &sc200ai_ctrl_ops,
15961877 V4L2_CID_VBLANK, vblank_def,
15971878 SC200AI_VTS_MAX - mode->height,
15981879 1, vblank_def);
1599
- exposure_max = mode->vts_def - 4;
1880
+ exposure_max = 2 * mode->vts_def - 8;
16001881 sc200ai->exposure = v4l2_ctrl_new_std(handler, &sc200ai_ctrl_ops,
16011882 V4L2_CID_EXPOSURE, SC200AI_EXPOSURE_MIN,
16021883 exposure_max, SC200AI_EXPOSURE_STEP,
....@@ -1641,6 +1922,11 @@
16411922 u32 id = 0;
16421923 int ret;
16431924
1925
+ if (sc200ai->is_thunderboot) {
1926
+ dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1927
+ return 0;
1928
+ }
1929
+
16441930 ret = sc200ai_read_reg(client, SC200AI_REG_CHIP_ID,
16451931 SC200AI_REG_VALUE_16BIT, &id);
16461932 if (id != CHIP_ID) {
....@@ -1665,6 +1951,51 @@
16651951 sc200ai->supplies);
16661952 }
16671953
1954
+#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
1955
+static void find_terminal_resolution(struct sc200ai *sc200ai)
1956
+{
1957
+ int i = 0;
1958
+ const struct sc200ai_mode *mode = NULL;
1959
+ u32 rk_cam_hdr = get_rk_cam_hdr();
1960
+ u32 rk_cam_w = get_rk_cam_w();
1961
+ u32 rk_cam_h = get_rk_cam_h();
1962
+
1963
+ if (rk_cam_w == 0 || rk_cam_h == 0)
1964
+ goto err_find_res;
1965
+
1966
+ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1967
+ mode = &supported_modes[i];
1968
+ if (mode->width == rk_cam_w && mode->height == rk_cam_h &&
1969
+ mode->hdr_mode == rk_cam_hdr) {
1970
+ sc200ai->cur_mode = mode;
1971
+ return;
1972
+ }
1973
+ }
1974
+err_find_res:
1975
+ dev_err(&sc200ai->client->dev, "not match %dx%d mode %d\n!",
1976
+ rk_cam_w, rk_cam_h, rk_cam_hdr);
1977
+ sc200ai->cur_mode = &supported_modes[0];
1978
+}
1979
+#else
1980
+static void find_terminal_resolution(struct sc200ai *sc200ai)
1981
+{
1982
+ u32 hdr_mode = 0;
1983
+ struct device_node *node = sc200ai->client->dev.of_node;
1984
+ int i = 0;
1985
+
1986
+ of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
1987
+ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1988
+ if (hdr_mode == supported_modes[i].hdr_mode) {
1989
+ sc200ai->cur_mode = &supported_modes[i];
1990
+ break;
1991
+ }
1992
+ }
1993
+ if (i == ARRAY_SIZE(supported_modes))
1994
+ sc200ai->cur_mode = &supported_modes[0];
1995
+
1996
+}
1997
+#endif
1998
+
16681999 static int sc200ai_probe(struct i2c_client *client,
16692000 const struct i2c_device_id *id)
16702001 {
....@@ -1674,7 +2005,6 @@
16742005 struct v4l2_subdev *sd;
16752006 char facing[2];
16762007 int ret;
1677
- u32 i, hdr_mode = 0;
16782008
16792009 dev_info(dev, "driver version: %02x.%02x.%02x",
16802010 DRIVER_VERSION >> 16,
....@@ -1685,7 +2015,6 @@
16852015 if (!sc200ai)
16862016 return -ENOMEM;
16872017
1688
- of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
16892018 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
16902019 &sc200ai->module_index);
16912020 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
....@@ -1699,15 +2028,10 @@
16992028 return -EINVAL;
17002029 }
17012030
2031
+ sc200ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
17022032 sc200ai->client = client;
1703
- for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1704
- if (hdr_mode == supported_modes[i].hdr_mode) {
1705
- sc200ai->cur_mode = &supported_modes[i];
1706
- break;
1707
- }
1708
- }
1709
- if (i == ARRAY_SIZE(supported_modes))
1710
- sc200ai->cur_mode = &supported_modes[0];
2033
+
2034
+ find_terminal_resolution(sc200ai);
17112035
17122036 sc200ai->xvclk = devm_clk_get(dev, "xvclk");
17132037 if (IS_ERR(sc200ai->xvclk)) {
....@@ -1715,11 +2039,11 @@
17152039 return -EINVAL;
17162040 }
17172041
1718
- sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2042
+ sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
17192043 if (IS_ERR(sc200ai->reset_gpio))
17202044 dev_warn(dev, "Failed to get reset-gpios\n");
17212045
1722
- sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
2046
+ sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
17232047 if (IS_ERR(sc200ai->pwdn_gpio))
17242048 dev_warn(dev, "Failed to get pwdn-gpios\n");
17252049
....@@ -1775,6 +2099,13 @@
17752099 goto err_power_off;
17762100 #endif
17772101
2102
+ if (!sc200ai->cam_sw_inf) {
2103
+ sc200ai->cam_sw_inf = cam_sw_init();
2104
+ cam_sw_clk_init(sc200ai->cam_sw_inf, sc200ai->xvclk, SC200AI_XVCLK_FREQ);
2105
+ cam_sw_reset_pin_init(sc200ai->cam_sw_inf, sc200ai->reset_gpio, 0);
2106
+ cam_sw_pwdn_pin_init(sc200ai->cam_sw_inf, sc200ai->pwdn_gpio, 1);
2107
+ }
2108
+
17782109 memset(facing, 0, sizeof(facing));
17792110 if (strcmp(sc200ai->module_facing, "back") == 0)
17802111 facing[0] = 'b';
....@@ -1792,7 +2123,10 @@
17922123
17932124 pm_runtime_set_active(dev);
17942125 pm_runtime_enable(dev);
1795
- pm_runtime_idle(dev);
2126
+ if (sc200ai->is_thunderboot)
2127
+ pm_runtime_get_sync(dev);
2128
+ else
2129
+ pm_runtime_idle(dev);
17962130
17972131 return 0;
17982132
....@@ -1821,6 +2155,8 @@
18212155 #endif
18222156 v4l2_ctrl_handler_free(&sc200ai->ctrl_handler);
18232157 mutex_destroy(&sc200ai->mutex);
2158
+
2159
+ cam_sw_deinit(sc200ai->cam_sw_inf);
18242160
18252161 pm_runtime_disable(&client->dev);
18262162 if (!pm_runtime_status_suspended(&client->dev))
....@@ -1864,8 +2200,12 @@
18642200 i2c_del_driver(&sc200ai_i2c_driver);
18652201 }
18662202
2203
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
2204
+subsys_initcall(sensor_mod_init);
2205
+#else
18672206 device_initcall_sync(sensor_mod_init);
2207
+#endif
18682208 module_exit(sensor_mod_exit);
18692209
18702210 MODULE_DESCRIPTION("smartsens sc200ai sensor driver");
1871
-MODULE_LICENSE("GPL v2");
2211
+MODULE_LICENSE("GPL");