hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/i2c/sc401ai.c
....@@ -9,6 +9,7 @@
99 * V0.0X01.0X03 fix gain range.
1010 * V0.0X01.0X04 add enum_frame_interval function.
1111 * V0.0X01.0X05 add quick stream on/off
12
+ * V0.0X01.0X06 support thunder boot function.
1213 */
1314
1415 #include <linux/clk.h>
....@@ -31,8 +32,9 @@
3132 #include <media/v4l2-ctrls.h>
3233 #include <media/v4l2-subdev.h>
3334 #include <linux/pinctrl/consumer.h>
35
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
3436
35
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05)
37
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06)
3638
3739 #ifndef V4L2_CID_DIGITAL_GAIN
3840 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
....@@ -173,6 +175,8 @@
173175 const char *module_name;
174176 const char *len_name;
175177 u32 cur_vts;
178
+ bool is_thunderboot;
179
+ bool is_first_streamoff;
176180 struct preisp_hdrae_exp_s init_hdrae_exp;
177181 };
178182
....@@ -447,6 +451,8 @@
447451 SC401AI_LINK_FREQ_630,
448452 };
449453
454
+static int __sc401ai_power_on(struct sc401ai *sc401ai);
455
+
450456 /* Write registers up to 4 at a time */
451457 static int sc401ai_write_reg(struct i2c_client *client, u16 reg,
452458 u32 len, u32 val)
....@@ -623,6 +629,11 @@
623629 else
624630 DIG_Fine_gain_reg = abs(800 * gain / (Dcg_gainx100 * Coarse_gain *
625631 DIG_gain) / ANA_Fine_gainx64);
632
+
633
+ if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
634
+ sc401ai->is_thunderboot = false;
635
+ __sc401ai_power_on(sc401ai);
636
+ }
626637
627638 ret = sc401ai_write_reg(sc401ai->client,
628639 SC401AI_REG_DIG_GAIN,
....@@ -989,23 +1000,31 @@
9891000 {
9901001 int ret;
9911002
992
- ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
993
- if (ret)
994
- return ret;
1003
+ if (!sc401ai->is_thunderboot) {
1004
+ ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
1005
+ if (ret)
1006
+ return ret;
9951007
996
- /* In case these controls are set before streaming */
997
- ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
998
- if (ret)
999
- return ret;
1008
+ /* In case these controls are set before streaming */
1009
+ ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
1010
+ if (ret)
1011
+ return ret;
1012
+ }
10001013
10011014 return sc401ai_write_reg(sc401ai->client,
1002
- SC401AI_REG_CTRL_MODE,
1003
- SC401AI_REG_VALUE_08BIT,
1004
- SC401AI_MODE_STREAMING);
1015
+ SC401AI_REG_CTRL_MODE,
1016
+ SC401AI_REG_VALUE_08BIT,
1017
+ SC401AI_MODE_STREAMING);
1018
+
10051019 }
10061020
10071021 static int __sc401ai_stop_stream(struct sc401ai *sc401ai)
10081022 {
1023
+ if (sc401ai->is_thunderboot) {
1024
+ sc401ai->is_first_streamoff = true;
1025
+ pm_runtime_put(&sc401ai->client->dev);
1026
+ }
1027
+
10091028 return sc401ai_write_reg(sc401ai->client,
10101029 SC401AI_REG_CTRL_MODE,
10111030 SC401AI_REG_VALUE_08BIT,
....@@ -1024,6 +1043,10 @@
10241043 goto unlock_and_return;
10251044
10261045 if (on) {
1046
+ if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1047
+ sc401ai->is_thunderboot = false;
1048
+ __sc401ai_power_on(sc401ai);
1049
+ }
10271050 ret = pm_runtime_get_sync(&client->dev);
10281051 if (ret < 0) {
10291052 pm_runtime_put_noidle(&client->dev);
....@@ -1115,6 +1138,10 @@
11151138 dev_err(dev, "Failed to enable xvclk\n");
11161139 return ret;
11171140 }
1141
+
1142
+ if (sc401ai->is_thunderboot)
1143
+ return 0;
1144
+
11181145 if (!IS_ERR(sc401ai->reset_gpio))
11191146 gpiod_set_value_cansleep(sc401ai->reset_gpio, 0);
11201147
....@@ -1152,6 +1179,15 @@
11521179 {
11531180 int ret;
11541181 struct device *dev = &sc401ai->client->dev;
1182
+
1183
+ if (sc401ai->is_thunderboot) {
1184
+ if (sc401ai->is_first_streamoff) {
1185
+ sc401ai->is_thunderboot = false;
1186
+ sc401ai->is_first_streamoff = false;
1187
+ } else {
1188
+ return;
1189
+ }
1190
+ }
11551191
11561192 if (!IS_ERR(sc401ai->pwdn_gpio))
11571193 gpiod_set_value_cansleep(sc401ai->pwdn_gpio, 0);
....@@ -1491,6 +1527,11 @@
14911527 u32 id = 0;
14921528 int ret;
14931529
1530
+ if (sc401ai->is_thunderboot) {
1531
+ dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1532
+ return 0;
1533
+ }
1534
+
14941535 ret = sc401ai_read_reg(client, SC401AI_REG_CHIP_ID,
14951536 SC401AI_REG_VALUE_16BIT, &id);
14961537 if (id != CHIP_ID) {
....@@ -1549,6 +1590,8 @@
15491590 return -EINVAL;
15501591 }
15511592
1593
+ sc401ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
1594
+
15521595 sc401ai->client = client;
15531596 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
15541597 if (hdr_mode == supported_modes[i].hdr_mode) {
....@@ -1565,13 +1608,23 @@
15651608 return -EINVAL;
15661609 }
15671610
1568
- sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1569
- if (IS_ERR(sc401ai->reset_gpio))
1570
- dev_warn(dev, "Failed to get reset-gpios\n");
1611
+ if (sc401ai->is_thunderboot) {
1612
+ sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
1613
+ if (IS_ERR(sc401ai->reset_gpio))
1614
+ dev_warn(dev, "Failed to get reset-gpios\n");
15711615
1572
- sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1573
- if (IS_ERR(sc401ai->pwdn_gpio))
1574
- dev_warn(dev, "Failed to get pwdn-gpios\n");
1616
+ sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
1617
+ if (IS_ERR(sc401ai->pwdn_gpio))
1618
+ dev_warn(dev, "Failed to get pwdn-gpios\n");
1619
+ } else {
1620
+ sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1621
+ if (IS_ERR(sc401ai->reset_gpio))
1622
+ dev_warn(dev, "Failed to get reset-gpios\n");
1623
+
1624
+ sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1625
+ if (IS_ERR(sc401ai->pwdn_gpio))
1626
+ dev_warn(dev, "Failed to get pwdn-gpios\n");
1627
+ }
15751628
15761629 sc401ai->pinctrl = devm_pinctrl_get(dev);
15771630 if (!IS_ERR(sc401ai->pinctrl)) {
....@@ -1646,7 +1699,10 @@
16461699
16471700 pm_runtime_set_active(dev);
16481701 pm_runtime_enable(dev);
1649
- pm_runtime_idle(dev);
1702
+ if (sc401ai->is_thunderboot)
1703
+ pm_runtime_get_sync(dev);
1704
+ else
1705
+ pm_runtime_idle(dev);
16501706
16511707 return 0;
16521708
....@@ -1718,7 +1774,12 @@
17181774 i2c_del_driver(&sc401ai_i2c_driver);
17191775 }
17201776
1777
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
1778
+subsys_initcall(sensor_mod_init);
1779
+#else
17211780 device_initcall_sync(sensor_mod_init);
1781
+#endif
1782
+
17221783 module_exit(sensor_mod_exit);
17231784
17241785 MODULE_DESCRIPTION("smartsens sc401ai sensor driver");