forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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
....@@ -120,14 +122,6 @@
120122
121123 #define SC401AI_NUM_SUPPLIES ARRAY_SIZE(sc401ai_supply_names)
122124
123
-enum sc401ai_max_pad {
124
- PAD0, /* link to isp */
125
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
126
- PAD2, /* link to csi wr1 | hdr x3:L */
127
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
128
- PAD_MAX,
129
-};
130
-
131125 struct regval {
132126 u16 addr;
133127 u8 val;
....@@ -170,6 +164,7 @@
170164 struct v4l2_ctrl *pixel_rate;
171165 struct v4l2_ctrl *link_freq;
172166 struct mutex mutex;
167
+ struct v4l2_fract cur_fps;
173168 bool streaming;
174169 bool power_on;
175170 unsigned int lane_num;
....@@ -180,6 +175,8 @@
180175 const char *module_name;
181176 const char *len_name;
182177 u32 cur_vts;
178
+ bool is_thunderboot;
179
+ bool is_first_streamoff;
183180 struct preisp_hdrae_exp_s init_hdrae_exp;
184181 };
185182
....@@ -454,6 +451,8 @@
454451 SC401AI_LINK_FREQ_630,
455452 };
456453
454
+static int __sc401ai_power_on(struct sc401ai *sc401ai);
455
+
457456 /* Write registers up to 4 at a time */
458457 static int sc401ai_write_reg(struct i2c_client *client, u16 reg,
459458 u32 len, u32 val)
....@@ -631,6 +630,11 @@
631630 DIG_Fine_gain_reg = abs(800 * gain / (Dcg_gainx100 * Coarse_gain *
632631 DIG_gain) / ANA_Fine_gainx64);
633632
633
+ if (sc401ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
634
+ sc401ai->is_thunderboot = false;
635
+ __sc401ai_power_on(sc401ai);
636
+ }
637
+
634638 ret = sc401ai_write_reg(sc401ai->client,
635639 SC401AI_REG_DIG_GAIN,
636640 SC401AI_REG_VALUE_08BIT,
....@@ -709,6 +713,8 @@
709713 __v4l2_ctrl_modify_range(sc401ai->vblank, vblank_def,
710714 SC401AI_VTS_MAX - mode->height,
711715 1, vblank_def);
716
+ sc401ai->cur_fps = mode->max_fps;
717
+ sc401ai->cur_vts = mode->vts_def;
712718 }
713719
714720 mutex_unlock(&sc401ai->mutex);
....@@ -800,15 +806,17 @@
800806 struct sc401ai *sc401ai = to_sc401ai(sd);
801807 const struct sc401ai_mode *mode = sc401ai->cur_mode;
802808
803
- mutex_lock(&sc401ai->mutex);
804
- fi->interval = mode->max_fps;
805
- mutex_unlock(&sc401ai->mutex);
809
+ if (sc401ai->streaming)
810
+ fi->interval = sc401ai->cur_fps;
811
+ else
812
+ fi->interval = mode->max_fps;
806813
807814 return 0;
808815 }
809816
810817 static int sc401ai_g_mbus_config(struct v4l2_subdev *sd,
811
- struct v4l2_mbus_config *config)
818
+ unsigned int pad_id,
819
+ struct v4l2_mbus_config *config)
812820 {
813821 struct sc401ai *sc401ai = to_sc401ai(sd);
814822 const struct sc401ai_mode *mode = sc401ai->cur_mode;
....@@ -823,7 +831,7 @@
823831 if (mode->hdr_mode == HDR_X3)
824832 val |= V4L2_MBUS_CSI2_CHANNEL_2;
825833
826
- config->type = V4L2_MBUS_CSI2;
834
+ config->type = V4L2_MBUS_CSI2_DPHY;
827835 config->flags = val;
828836
829837 return 0;
....@@ -833,10 +841,10 @@
833841 struct rkmodule_inf *inf)
834842 {
835843 memset(inf, 0, sizeof(*inf));
836
- strlcpy(inf->base.sensor, SC401AI_NAME, sizeof(inf->base.sensor));
837
- strlcpy(inf->base.module, sc401ai->module_name,
844
+ strscpy(inf->base.sensor, SC401AI_NAME, sizeof(inf->base.sensor));
845
+ strscpy(inf->base.module, sc401ai->module_name,
838846 sizeof(inf->base.module));
839
- strlcpy(inf->base.lens, sc401ai->len_name, sizeof(inf->base.lens));
847
+ strscpy(inf->base.lens, sc401ai->len_name, sizeof(inf->base.lens));
840848 }
841849
842850 static long sc401ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
....@@ -992,23 +1000,31 @@
9921000 {
9931001 int ret;
9941002
995
- ret = sc401ai_write_array(sc401ai->client, sc401ai->cur_mode->reg_list);
996
- if (ret)
997
- 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;
9981007
999
- /* In case these controls are set before streaming */
1000
- ret = __v4l2_ctrl_handler_setup(&sc401ai->ctrl_handler);
1001
- if (ret)
1002
- 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
+ }
10031013
10041014 return sc401ai_write_reg(sc401ai->client,
1005
- SC401AI_REG_CTRL_MODE,
1006
- SC401AI_REG_VALUE_08BIT,
1007
- SC401AI_MODE_STREAMING);
1015
+ SC401AI_REG_CTRL_MODE,
1016
+ SC401AI_REG_VALUE_08BIT,
1017
+ SC401AI_MODE_STREAMING);
1018
+
10081019 }
10091020
10101021 static int __sc401ai_stop_stream(struct sc401ai *sc401ai)
10111022 {
1023
+ if (sc401ai->is_thunderboot) {
1024
+ sc401ai->is_first_streamoff = true;
1025
+ pm_runtime_put(&sc401ai->client->dev);
1026
+ }
1027
+
10121028 return sc401ai_write_reg(sc401ai->client,
10131029 SC401AI_REG_CTRL_MODE,
10141030 SC401AI_REG_VALUE_08BIT,
....@@ -1027,6 +1043,10 @@
10271043 goto unlock_and_return;
10281044
10291045 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
+ }
10301050 ret = pm_runtime_get_sync(&client->dev);
10311051 if (ret < 0) {
10321052 pm_runtime_put_noidle(&client->dev);
....@@ -1118,6 +1138,10 @@
11181138 dev_err(dev, "Failed to enable xvclk\n");
11191139 return ret;
11201140 }
1141
+
1142
+ if (sc401ai->is_thunderboot)
1143
+ return 0;
1144
+
11211145 if (!IS_ERR(sc401ai->reset_gpio))
11221146 gpiod_set_value_cansleep(sc401ai->reset_gpio, 0);
11231147
....@@ -1155,6 +1179,15 @@
11551179 {
11561180 int ret;
11571181 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
+ }
11581191
11591192 if (!IS_ERR(sc401ai->pwdn_gpio))
11601193 gpiod_set_value_cansleep(sc401ai->pwdn_gpio, 0);
....@@ -1249,7 +1282,6 @@
12491282 static const struct v4l2_subdev_video_ops sc401ai_video_ops = {
12501283 .s_stream = sc401ai_s_stream,
12511284 .g_frame_interval = sc401ai_g_frame_interval,
1252
- .g_mbus_config = sc401ai_g_mbus_config,
12531285 };
12541286
12551287 static const struct v4l2_subdev_pad_ops sc401ai_pad_ops = {
....@@ -1258,6 +1290,7 @@
12581290 .enum_frame_interval = sc401ai_enum_frame_interval,
12591291 .get_fmt = sc401ai_get_fmt,
12601292 .set_fmt = sc401ai_set_fmt,
1293
+ .get_mbus_config = sc401ai_g_mbus_config,
12611294 };
12621295
12631296 static const struct v4l2_subdev_ops sc401ai_subdev_ops = {
....@@ -1265,6 +1298,14 @@
12651298 .video = &sc401ai_video_ops,
12661299 .pad = &sc401ai_pad_ops,
12671300 };
1301
+
1302
+static void sc401ai_modify_fps_info(struct sc401ai *sc401ai)
1303
+{
1304
+ const struct sc401ai_mode *mode = sc401ai->cur_mode;
1305
+
1306
+ sc401ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1307
+ sc401ai->cur_vts;
1308
+}
12681309
12691310 static int sc401ai_set_ctrl(struct v4l2_ctrl *ctrl)
12701311 {
....@@ -1324,7 +1365,9 @@
13241365 SC401AI_REG_VALUE_08BIT,
13251366 (ctrl->val + sc401ai->cur_mode->height)
13261367 & 0xff);
1327
- sc401ai->cur_vts = ctrl->val + sc401ai->cur_mode->height;
1368
+ if (!ret)
1369
+ sc401ai->cur_vts = ctrl->val + sc401ai->cur_mode->height;
1370
+ sc401ai_modify_fps_info(sc401ai);
13281371 break;
13291372 case V4L2_CID_TEST_PATTERN:
13301373 ret = sc401ai_enable_test_pattern(sc401ai, ctrl->val);
....@@ -1466,6 +1509,8 @@
14661509 }
14671510
14681511 sc401ai->subdev.ctrl_handler = handler;
1512
+ sc401ai->cur_fps = mode->max_fps;
1513
+ sc401ai->cur_vts = mode->vts_def;
14691514
14701515 return 0;
14711516
....@@ -1481,6 +1526,11 @@
14811526 struct device *dev = &sc401ai->client->dev;
14821527 u32 id = 0;
14831528 int ret;
1529
+
1530
+ if (sc401ai->is_thunderboot) {
1531
+ dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1532
+ return 0;
1533
+ }
14841534
14851535 ret = sc401ai_read_reg(client, SC401AI_REG_CHIP_ID,
14861536 SC401AI_REG_VALUE_16BIT, &id);
....@@ -1540,6 +1590,8 @@
15401590 return -EINVAL;
15411591 }
15421592
1593
+ sc401ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
1594
+
15431595 sc401ai->client = client;
15441596 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
15451597 if (hdr_mode == supported_modes[i].hdr_mode) {
....@@ -1556,13 +1608,23 @@
15561608 return -EINVAL;
15571609 }
15581610
1559
- sc401ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1560
- if (IS_ERR(sc401ai->reset_gpio))
1561
- 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");
15621615
1563
- sc401ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1564
- if (IS_ERR(sc401ai->pwdn_gpio))
1565
- 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
+ }
15661628
15671629 sc401ai->pinctrl = devm_pinctrl_get(dev);
15681630 if (!IS_ERR(sc401ai->pinctrl)) {
....@@ -1637,7 +1699,10 @@
16371699
16381700 pm_runtime_set_active(dev);
16391701 pm_runtime_enable(dev);
1640
- pm_runtime_idle(dev);
1702
+ if (sc401ai->is_thunderboot)
1703
+ pm_runtime_get_sync(dev);
1704
+ else
1705
+ pm_runtime_idle(dev);
16411706
16421707 return 0;
16431708
....@@ -1709,8 +1774,13 @@
17091774 i2c_del_driver(&sc401ai_i2c_driver);
17101775 }
17111776
1777
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
1778
+subsys_initcall(sensor_mod_init);
1779
+#else
17121780 device_initcall_sync(sensor_mod_init);
1781
+#endif
1782
+
17131783 module_exit(sensor_mod_exit);
17141784
17151785 MODULE_DESCRIPTION("smartsens sc401ai sensor driver");
1716
-MODULE_LICENSE("GPL v2");
1786
+MODULE_LICENSE("GPL");