From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198

---
 kernel/drivers/media/i2c/sc401ai.c |   97 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 79 insertions(+), 18 deletions(-)

diff --git a/kernel/drivers/media/i2c/sc401ai.c b/kernel/drivers/media/i2c/sc401ai.c
index e4f965d..0eac2d3 100644
--- a/kernel/drivers/media/i2c/sc401ai.c
+++ b/kernel/drivers/media/i2c/sc401ai.c
@@ -9,6 +9,7 @@
  * V0.0X01.0X03 fix gain range.
  * V0.0X01.0X04 add enum_frame_interval function.
  * V0.0X01.0X05 add quick stream on/off
+ * V0.0X01.0X06 support thunder boot function.
  */
 
 #include <linux/clk.h>
@@ -31,8 +32,9 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-subdev.h>
 #include <linux/pinctrl/consumer.h>
+#include "../platform/rockchip/isp/rkisp_tb_helper.h"
 
-#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x05)
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x06)
 
 #ifndef V4L2_CID_DIGITAL_GAIN
 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
@@ -173,6 +175,8 @@
 	const char		*module_name;
 	const char		*len_name;
 	u32			cur_vts;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
 };
 
@@ -447,6 +451,8 @@
 	SC401AI_LINK_FREQ_630,
 };
 
+static int __sc401ai_power_on(struct sc401ai *sc401ai);
+
 /* Write registers up to 4 at a time */
 static int sc401ai_write_reg(struct i2c_client *client, u16 reg,
 			    u32 len, u32 val)
@@ -623,6 +629,11 @@
 	else
 		DIG_Fine_gain_reg = abs(800 * gain / (Dcg_gainx100 * Coarse_gain *
 							DIG_gain) / ANA_Fine_gainx64);
+
+	if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+		sc401ai->is_thunderboot = false;
+		__sc401ai_power_on(sc401ai);
+	}
 
 	ret = sc401ai_write_reg(sc401ai->client,
 				SC401AI_REG_DIG_GAIN,
@@ -989,23 +1000,31 @@
 {
 	int ret;
 
-	ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
-	if (ret)
-		return ret;
+	if (!sc401ai->is_thunderboot) {
+		ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
+		if (ret)
+			return ret;
 
-	/* In case these controls are set before streaming */
-	ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
-	if (ret)
-		return ret;
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
+		if (ret)
+			return ret;
+	}
 
 	return sc401ai_write_reg(sc401ai->client,
-				 SC401AI_REG_CTRL_MODE,
-				 SC401AI_REG_VALUE_08BIT,
-				 SC401AI_MODE_STREAMING);
+				SC401AI_REG_CTRL_MODE,
+				SC401AI_REG_VALUE_08BIT,
+				SC401AI_MODE_STREAMING);
+
 }
 
 static int __sc401ai_stop_stream(struct sc401ai *sc401ai)
 {
+	if (sc401ai->is_thunderboot) {
+		sc401ai->is_first_streamoff = true;
+		pm_runtime_put(&sc401ai->client->dev);
+	}
+
 	return sc401ai_write_reg(sc401ai->client,
 				 SC401AI_REG_CTRL_MODE,
 				 SC401AI_REG_VALUE_08BIT,
@@ -1024,6 +1043,10 @@
 		goto unlock_and_return;
 
 	if (on) {
+		if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			sc401ai->is_thunderboot = false;
+			__sc401ai_power_on(sc401ai);
+		}
 		ret = pm_runtime_get_sync(&client->dev);
 		if (ret < 0) {
 			pm_runtime_put_noidle(&client->dev);
@@ -1115,6 +1138,10 @@
 		dev_err(dev, "Failed to enable xvclk\n");
 		return ret;
 	}
+
+	if (sc401ai->is_thunderboot)
+		return 0;
+
 	if (!IS_ERR(sc401ai->reset_gpio))
 		gpiod_set_value_cansleep(sc401ai->reset_gpio, 0);
 
@@ -1152,6 +1179,15 @@
 {
 	int ret;
 	struct device *dev = &sc401ai->client->dev;
+
+	if (sc401ai->is_thunderboot) {
+		if (sc401ai->is_first_streamoff) {
+			sc401ai->is_thunderboot = false;
+			sc401ai->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
 
 	if (!IS_ERR(sc401ai->pwdn_gpio))
 		gpiod_set_value_cansleep(sc401ai->pwdn_gpio, 0);
@@ -1491,6 +1527,11 @@
 	u32 id = 0;
 	int ret;
 
+	if (sc401ai->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
+
 	ret = sc401ai_read_reg(client, SC401AI_REG_CHIP_ID,
 			       SC401AI_REG_VALUE_16BIT, &id);
 	if (id != CHIP_ID) {
@@ -1549,6 +1590,8 @@
 		return -EINVAL;
 	}
 
+	sc401ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
+
 	sc401ai->client = client;
 	for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
 		if (hdr_mode == supported_modes[i].hdr_mode) {
@@ -1565,13 +1608,23 @@
 		return -EINVAL;
 	}
 
-	sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(sc401ai->reset_gpio))
-		dev_warn(dev, "Failed to get reset-gpios\n");
+	if (sc401ai->is_thunderboot) {
+		sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+		if (IS_ERR(sc401ai->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
 
-	sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
-	if (IS_ERR(sc401ai->pwdn_gpio))
-		dev_warn(dev, "Failed to get pwdn-gpios\n");
+		sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+		if (IS_ERR(sc401ai->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	} else {
+		sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+		if (IS_ERR(sc401ai->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
+
+		sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+		if (IS_ERR(sc401ai->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	}
 
 	sc401ai->pinctrl = devm_pinctrl_get(dev);
 	if (!IS_ERR(sc401ai->pinctrl)) {
@@ -1646,7 +1699,10 @@
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
+	if (sc401ai->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
 
 	return 0;
 
@@ -1718,7 +1774,12 @@
 	i2c_del_driver(&sc401ai_i2c_driver);
 }
 
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(sensor_mod_init);
+#else
 device_initcall_sync(sensor_mod_init);
+#endif
+
 module_exit(sensor_mod_exit);
 
 MODULE_DESCRIPTION("smartsens sc401ai sensor driver");

--
Gitblit v1.6.2