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/sc4336.c |  135 ++++++++++++++++++++++++++++++++------------
 1 files changed, 97 insertions(+), 38 deletions(-)

diff --git a/kernel/drivers/media/i2c/sc4336.c b/kernel/drivers/media/i2c/sc4336.c
index 6ebf54b..f741979 100644
--- a/kernel/drivers/media/i2c/sc4336.c
+++ b/kernel/drivers/media/i2c/sc4336.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
  *
  * V0.0X01.0X01 first version
+ * V0.0X01.0X02 support fastboot
  */
 
 //#define DEBUG
@@ -26,6 +27,7 @@
 #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, 0x01)
 
@@ -110,14 +112,6 @@
 	u8 val;
 };
 
-enum sc4336_max_pad {
-	PAD0, /* link to isp */
-	PAD1, /* link to csi wr0 | hdr x2:L x3:M */
-	PAD2, /* link to csi wr1 | hdr      x3:L */
-	PAD3, /* link to csi wr2 | hdr x2:M x3:S */
-	PAD_MAX,
-};
-
 struct sc4336_mode {
 	u32 bus_fmt;
 	u32 width;
@@ -155,11 +149,14 @@
 	bool			streaming;
 	bool			power_on;
 	const struct sc4336_mode *cur_mode;
+	struct v4l2_fract	cur_fps;
 	u32			module_index;
 	const char		*module_facing;
 	const char		*module_name;
 	const char		*len_name;
 	u32			cur_vts;
+	bool			is_thunderboot;
+	bool			is_first_streamoff;
 };
 
 #define to_sc4336(sd) container_of(sd, struct sc4336, subdev)
@@ -314,6 +311,8 @@
 	{0x5aed, 0x2c},
 	{0x36e9, 0x53},
 	{0x37f9, 0x23},
+	{0x320e, 0x07},
+	{0x320f, 0x08},
 	{REG_NULL, 0x00},
 };
 
@@ -323,11 +322,11 @@
 		.height = 1440,
 		.max_fps = {
 			.numerator = 10000,
-			.denominator = 300000,
+			.denominator = 250000,
 		},
 		.exp_def = 0x0080,
 		.hts_def = 0x0578 * 2,
-		.vts_def = 0x05dc,
+		.vts_def = 0x0708,
 		.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
 		.reg_list = sc4336_linear_10_2560x1440_regs,
 		.hdr_mode = NO_HDR,
@@ -552,6 +551,7 @@
 		__v4l2_ctrl_modify_range(sc4336->vblank, vblank_def,
 					 SC4336_VTS_MAX - mode->height,
 					 1, vblank_def);
+		sc4336->cur_fps = mode->max_fps;
 	}
 
 	mutex_unlock(&sc4336->mutex);
@@ -644,14 +644,16 @@
 	struct sc4336 *sc4336 = to_sc4336(sd);
 	const struct sc4336_mode *mode = sc4336->cur_mode;
 
-	mutex_lock(&sc4336->mutex);
-	fi->interval = mode->max_fps;
-	mutex_unlock(&sc4336->mutex);
+	if (sc4336->streaming)
+		fi->interval = sc4336->cur_fps;
+	else
+		fi->interval = mode->max_fps;
 
 	return 0;
 }
 
 static int sc4336_g_mbus_config(struct v4l2_subdev *sd,
+				unsigned int pad_id,
 				struct v4l2_mbus_config *config)
 {
 	struct sc4336 *sc4336 = to_sc4336(sd);
@@ -665,7 +667,7 @@
 	if (mode->hdr_mode == HDR_X3)
 		val |= V4L2_MBUS_CSI2_CHANNEL_2;
 
-	config->type = V4L2_MBUS_CSI2;
+	config->type = V4L2_MBUS_CSI2_DPHY;
 	config->flags = val;
 
 	return 0;
@@ -831,15 +833,16 @@
 static int __sc4336_start_stream(struct sc4336 *sc4336)
 {
 	int ret;
+	if (!sc4336->is_thunderboot) {
+		ret = sc4336_write_array(sc4336->client, sc4336->cur_mode->reg_list);
+		if (ret)
+			return ret;
 
-	ret = sc4336_write_array(sc4336->client, sc4336->cur_mode->reg_list);
-	if (ret)
-		return ret;
-
-	/* In case these controls are set before streaming */
-	ret = __v4l2_ctrl_handler_setup(&sc4336->ctrl_handler);
-	if (ret)
-		return ret;
+		/* In case these controls are set before streaming */
+		ret = __v4l2_ctrl_handler_setup(&sc4336->ctrl_handler);
+		if (ret)
+			return ret;
+	}
 
 	return sc4336_write_reg(sc4336->client, SC4336_REG_CTRL_MODE,
 				 SC4336_REG_VALUE_08BIT, SC4336_MODE_STREAMING);
@@ -847,10 +850,15 @@
 
 static int __sc4336_stop_stream(struct sc4336 *sc4336)
 {
+	if (sc4336->is_thunderboot) {
+		sc4336->is_first_streamoff = true;
+		pm_runtime_put(&sc4336->client->dev);
+	}
 	return sc4336_write_reg(sc4336->client, SC4336_REG_CTRL_MODE,
 				 SC4336_REG_VALUE_08BIT, SC4336_MODE_SW_STANDBY);
 }
 
+static int __sc4336_power_on(struct sc4336 *sc4336);
 static int sc4336_s_stream(struct v4l2_subdev *sd, int on)
 {
 	struct sc4336 *sc4336 = to_sc4336(sd);
@@ -863,6 +871,11 @@
 		goto unlock_and_return;
 
 	if (on) {
+		if (sc4336->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
+			sc4336->is_thunderboot = false;
+			__sc4336_power_on(sc4336);
+		}
+
 		ret = pm_runtime_get_sync(&client->dev);
 		if (ret < 0) {
 			pm_runtime_put_noidle(&client->dev);
@@ -907,11 +920,13 @@
 			goto unlock_and_return;
 		}
 
-		ret = sc4336_write_array(sc4336->client, sc4336_global_regs);
-		if (ret) {
-			v4l2_err(sd, "could not set init registers\n");
-			pm_runtime_put_noidle(&client->dev);
-			goto unlock_and_return;
+		if (!sc4336->is_thunderboot) {
+			ret = sc4336_write_array(sc4336->client, sc4336_global_regs);
+			if (ret) {
+				v4l2_err(sd, "could not set init registers\n");
+				pm_runtime_put_noidle(&client->dev);
+				goto unlock_and_return;
+			}
 		}
 
 		sc4336->power_on = true;
@@ -954,6 +969,9 @@
 		dev_err(dev, "Failed to enable xvclk\n");
 		return ret;
 	}
+	if (sc4336->is_thunderboot)
+		return 0;
+
 	if (!IS_ERR(sc4336->reset_gpio))
 		gpiod_set_value_cansleep(sc4336->reset_gpio, 0);
 
@@ -992,9 +1010,18 @@
 	int ret;
 	struct device *dev = &sc4336->client->dev;
 
+	clk_disable_unprepare(sc4336->xvclk);
+	if (sc4336->is_thunderboot) {
+		if (sc4336->is_first_streamoff) {
+			sc4336->is_thunderboot = false;
+			sc4336->is_first_streamoff = false;
+		} else {
+			return;
+		}
+	}
+
 	if (!IS_ERR(sc4336->pwdn_gpio))
 		gpiod_set_value_cansleep(sc4336->pwdn_gpio, 0);
-	clk_disable_unprepare(sc4336->xvclk);
 	if (!IS_ERR(sc4336->reset_gpio))
 		gpiod_set_value_cansleep(sc4336->reset_gpio, 0);
 	if (!IS_ERR_OR_NULL(sc4336->pins_sleep)) {
@@ -1006,7 +1033,7 @@
 	regulator_bulk_disable(SC4336_NUM_SUPPLIES, sc4336->supplies);
 }
 
-static int sc4336_runtime_resume(struct device *dev)
+static int __maybe_unused sc4336_runtime_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -1015,7 +1042,7 @@
 	return __sc4336_power_on(sc4336);
 }
 
-static int sc4336_runtime_suspend(struct device *dev)
+static int __maybe_unused sc4336_runtime_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -1085,7 +1112,6 @@
 static const struct v4l2_subdev_video_ops sc4336_video_ops = {
 	.s_stream = sc4336_s_stream,
 	.g_frame_interval = sc4336_g_frame_interval,
-	.g_mbus_config = sc4336_g_mbus_config,
 };
 
 static const struct v4l2_subdev_pad_ops sc4336_pad_ops = {
@@ -1094,6 +1120,7 @@
 	.enum_frame_interval = sc4336_enum_frame_interval,
 	.get_fmt = sc4336_get_fmt,
 	.set_fmt = sc4336_set_fmt,
+	.get_mbus_config = sc4336_g_mbus_config,
 };
 
 static const struct v4l2_subdev_ops sc4336_subdev_ops = {
@@ -1101,6 +1128,14 @@
 	.video	= &sc4336_video_ops,
 	.pad	= &sc4336_pad_ops,
 };
+
+static void sc4336_modify_fps_info(struct sc4336 *sc4336)
+{
+	const struct sc4336_mode *mode = sc4336->cur_mode;
+
+	sc4336->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+				      sc4336->cur_vts;
+}
 
 static int sc4336_set_ctrl(struct v4l2_ctrl *ctrl)
 {
@@ -1164,6 +1199,7 @@
 					 (ctrl->val + sc4336->cur_mode->height)
 					 & 0xff);
 		sc4336->cur_vts = ctrl->val + sc4336->cur_mode->height;
+		sc4336_modify_fps_info(sc4336);
 		break;
 	case V4L2_CID_TEST_PATTERN:
 		ret = sc4336_enable_test_pattern(sc4336, ctrl->val);
@@ -1231,6 +1267,7 @@
 					    V4L2_CID_VBLANK, vblank_def,
 					    SC4336_VTS_MAX - mode->height,
 					    1, vblank_def);
+	sc4336->cur_fps = mode->max_fps;
 	exposure_max = mode->vts_def - 8;
 	sc4336->exposure = v4l2_ctrl_new_std(handler, &sc4336_ctrl_ops,
 					      V4L2_CID_EXPOSURE, SC4336_EXPOSURE_MIN,
@@ -1272,6 +1309,11 @@
 	struct device *dev = &sc4336->client->dev;
 	u32 id = 0;
 	int ret;
+
+	if (sc4336->is_thunderboot) {
+		dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
+		return 0;
+	}
 
 	ret = sc4336_read_reg(client, SC4336_REG_CHIP_ID,
 			       SC4336_REG_VALUE_16BIT, &id);
@@ -1329,6 +1371,7 @@
 		return -EINVAL;
 	}
 
+	sc4336->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
 	sc4336->client = client;
 	sc4336->cur_mode = &supported_modes[0];
 
@@ -1338,14 +1381,23 @@
 		return -EINVAL;
 	}
 
-	sc4336->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(sc4336->reset_gpio))
-		dev_warn(dev, "Failed to get reset-gpios\n");
+	if (sc4336->is_thunderboot) {
+		sc4336->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
+		if (IS_ERR(sc4336->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
 
-	sc4336->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
-	if (IS_ERR(sc4336->pwdn_gpio))
-		dev_warn(dev, "Failed to get pwdn-gpios\n");
+		sc4336->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
+		if (IS_ERR(sc4336->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	} else {
+		sc4336->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+		if (IS_ERR(sc4336->reset_gpio))
+			dev_warn(dev, "Failed to get reset-gpios\n");
 
+		sc4336->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
+		if (IS_ERR(sc4336->pwdn_gpio))
+			dev_warn(dev, "Failed to get pwdn-gpios\n");
+	}
 	sc4336->pinctrl = devm_pinctrl_get(dev);
 	if (!IS_ERR(sc4336->pinctrl)) {
 		sc4336->pins_default =
@@ -1415,7 +1467,10 @@
 
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
+	if (sc4336->is_thunderboot)
+		pm_runtime_get_sync(dev);
+	else
+		pm_runtime_idle(dev);
 
 	return 0;
 
@@ -1487,7 +1542,11 @@
 	i2c_del_driver(&sc4336_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 sc4336 sensor driver");

--
Gitblit v1.6.2