hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/i2c/sc530ai.c
....@@ -43,6 +43,7 @@
4343 #include <linux/printk.h>
4444
4545 #include <linux/rk-camera-module.h>
46
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
4647 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
4748
4849 #ifndef V4L2_CID_DIGITAL_GAIN
....@@ -195,6 +196,8 @@
195196 const char *module_name;
196197 const char *len_name;
197198 bool has_init_exp;
199
+ bool is_thunderboot;
200
+ bool is_first_streamoff;
198201 struct preisp_hdrae_exp_s init_hdrae_exp;
199202 };
200203
....@@ -1351,21 +1354,23 @@
13511354 {
13521355 int ret;
13531356
1354
- ret = sc530ai_write_array(sc530ai->client, sc530ai->cur_mode->reg_list);
1355
- if (ret)
1356
- return ret;
1357
-
1358
- /* In case these controls are set before streaming */
1359
- ret = __v4l2_ctrl_handler_setup(&sc530ai->ctrl_handler);
1360
- if (ret)
1361
- return ret;
1362
- if (sc530ai->has_init_exp && sc530ai->cur_mode->hdr_mode != NO_HDR) {
1363
- ret = sc530ai_ioctl(&sc530ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1364
- &sc530ai->init_hdrae_exp);
1365
- if (ret) {
1366
- dev_err(&sc530ai->client->dev,
1367
- "init exp fail in hdr mode\n");
1357
+ if (!sc530ai->is_thunderboot) {
1358
+ ret = sc530ai_write_array(sc530ai->client, sc530ai->cur_mode->reg_list);
1359
+ if (ret)
13681360 return ret;
1361
+
1362
+ /* In case these controls are set before streaming */
1363
+ ret = __v4l2_ctrl_handler_setup(&sc530ai->ctrl_handler);
1364
+ if (ret)
1365
+ return ret;
1366
+ if (sc530ai->has_init_exp && sc530ai->cur_mode->hdr_mode != NO_HDR) {
1367
+ ret = sc530ai_ioctl(&sc530ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1368
+ &sc530ai->init_hdrae_exp);
1369
+ if (ret) {
1370
+ dev_err(&sc530ai->client->dev,
1371
+ "init exp fail in hdr mode\n");
1372
+ return ret;
1373
+ }
13691374 }
13701375 }
13711376 return sc530ai_write_reg(sc530ai->client, SC530AI_REG_CTRL_MODE,
....@@ -1376,11 +1381,16 @@
13761381 static int __sc530ai_stop_stream(struct sc530ai *sc530ai)
13771382 {
13781383 sc530ai->has_init_exp = false;
1384
+ if (sc530ai->is_thunderboot) {
1385
+ sc530ai->is_first_streamoff = true;
1386
+ pm_runtime_put(&sc530ai->client->dev);
1387
+ }
13791388 return sc530ai_write_reg(sc530ai->client, SC530AI_REG_CTRL_MODE,
13801389 SC530AI_REG_VALUE_08BIT,
13811390 SC530AI_MODE_SW_STANDBY);
13821391 }
13831392
1393
+static int __sc530ai_power_on(struct sc530ai *sc530ai);
13841394 static int sc530ai_s_stream(struct v4l2_subdev *sd, int on)
13851395 {
13861396 struct sc530ai *sc530ai = to_sc530ai(sd);
....@@ -1392,6 +1402,10 @@
13921402 if (on == sc530ai->streaming)
13931403 goto unlock_and_return;
13941404 if (on) {
1405
+ if (sc530ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1406
+ sc530ai->is_thunderboot = false;
1407
+ __sc530ai_power_on(sc530ai);
1408
+ }
13951409 ret = pm_runtime_get_sync(&client->dev);
13961410 if (ret < 0) {
13971411 pm_runtime_put_noidle(&client->dev);
....@@ -1434,13 +1448,18 @@
14341448 pm_runtime_put_noidle(&client->dev);
14351449 goto unlock_and_return;
14361450 }
1437
-
1438
- ret |= sc530ai_write_reg(sc530ai->client,
1439
- SC530AI_SOFTWARE_RESET_REG,
1440
- SC530AI_REG_VALUE_08BIT,
1441
- 0x01);
1442
- usleep_range(100, 200);
1443
-
1451
+ if (!sc530ai->is_thunderboot) {
1452
+ ret |= sc530ai_write_reg(sc530ai->client,
1453
+ SC530AI_SOFTWARE_RESET_REG,
1454
+ SC530AI_REG_VALUE_08BIT,
1455
+ 0x01);
1456
+ if (ret) {
1457
+ v4l2_err(sd, "could not set init registers\n");
1458
+ pm_runtime_put_noidle(&client->dev);
1459
+ goto unlock_and_return;
1460
+ }
1461
+ usleep_range(100, 200);
1462
+ }
14441463 sc530ai->power_on = true;
14451464 } else {
14461465 pm_runtime_put(&client->dev);
....@@ -1474,6 +1493,10 @@
14741493 dev_err(dev, "Failed to enable xvclk\n");
14751494 return ret;
14761495 }
1496
+
1497
+ if (sc530ai->is_thunderboot)
1498
+ return 0;
1499
+
14771500 if (!IS_ERR(sc530ai->reset_gpio))
14781501 gpiod_set_value_cansleep(sc530ai->reset_gpio, 0);
14791502
....@@ -1503,6 +1526,15 @@
15031526 {
15041527 int ret;
15051528 struct device *dev = &sc530ai->client->dev;
1529
+
1530
+ if (sc530ai->is_thunderboot) {
1531
+ if (sc530ai->is_first_streamoff) {
1532
+ sc530ai->is_thunderboot = false;
1533
+ sc530ai->is_first_streamoff = false;
1534
+ } else {
1535
+ return;
1536
+ }
1537
+ }
15061538
15071539 if (!IS_ERR(sc530ai->pwdn_gpio))
15081540 gpiod_set_value_cansleep(sc530ai->pwdn_gpio, 0);
....@@ -1903,6 +1935,10 @@
19031935 u32 id = 0;
19041936 int ret;
19051937
1938
+ if (sc530ai->is_thunderboot) {
1939
+ dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1940
+ return 0;
1941
+ }
19061942 ret = sc530ai_read_reg(client, SC530AI_REG_CHIP_ID,
19071943 SC530AI_REG_VALUE_16BIT, &id);
19081944 if (id != SC530AI_CHIP_ID) {
....@@ -1961,6 +1997,7 @@
19611997 return -EINVAL;
19621998 }
19631999
2000
+ sc530ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
19642001 sc530ai->client = client;
19652002
19662003 ret = sc530ai_parse_of(sc530ai);
....@@ -1973,11 +2010,13 @@
19732010 return -EINVAL;
19742011 }
19752012
1976
- sc530ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2013
+ sc530ai->reset_gpio = devm_gpiod_get(dev, "reset",
2014
+ sc530ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
19772015 if (IS_ERR(sc530ai->reset_gpio))
19782016 dev_warn(dev, "Failed to get reset-gpios\n");
19792017
1980
- sc530ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
2018
+ sc530ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn",
2019
+ sc530ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
19812020 if (IS_ERR(sc530ai->pwdn_gpio))
19822021 dev_warn(dev, "Failed to get pwdn-gpios\n");
19832022
....@@ -2051,7 +2090,10 @@
20512090
20522091 pm_runtime_set_active(dev);
20532092 pm_runtime_enable(dev);
2054
- pm_runtime_idle(dev);
2093
+ if (sc530ai->is_thunderboot)
2094
+ pm_runtime_get_sync(dev);
2095
+ else
2096
+ pm_runtime_idle(dev);
20552097
20562098 return 0;
20572099