forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/sc3338.c
....@@ -27,6 +27,7 @@
2727 #include <media/v4l2-subdev.h>
2828 #include <linux/pinctrl/consumer.h>
2929 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
30
+#include "cam-sleep-wakeup.h"
3031
3132 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
3233
....@@ -158,6 +159,7 @@
158159 bool is_thunderboot;
159160 bool is_first_streamoff;
160161 struct preisp_hdrae_exp_s init_hdrae_exp;
162
+ struct cam_sw_info *cam_sw_inf;
161163 };
162164
163165 #define to_sc3338(sd) container_of(sd, struct sc3338, subdev)
....@@ -722,6 +724,9 @@
722724 }
723725 break;
724726 case PREISP_CMD_SET_HDRAE_EXP:
727
+ if (sc3338->cam_sw_inf)
728
+ memcpy(&sc3338->cam_sw_inf->hdr_ae, (struct preisp_hdrae_exp_s *)(arg),
729
+ sizeof(struct preisp_hdrae_exp_s));
725730 break;
726731 case RKMODULE_SET_QUICK_STREAM:
727732
....@@ -970,6 +975,8 @@
970975 return ret;
971976 }
972977
978
+ cam_sw_regulator_bulk_init(sc3338->cam_sw_inf, SC3338_NUM_SUPPLIES, sc3338->supplies);
979
+
973980 if (sc3338->is_thunderboot)
974981 return 0;
975982
....@@ -1036,6 +1043,47 @@
10361043 regulator_bulk_disable(SC3338_NUM_SUPPLIES, sc3338->supplies);
10371044 }
10381045
1046
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
1047
+static int sc3338_resume(struct device *dev)
1048
+{
1049
+ int ret;
1050
+ struct i2c_client *client = to_i2c_client(dev);
1051
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1052
+ struct sc3338 *sc3338 = to_sc3338(sd);
1053
+
1054
+ cam_sw_prepare_wakeup(sc3338->cam_sw_inf, dev);
1055
+
1056
+ usleep_range(6000, 8000);
1057
+ cam_sw_write_array(sc3338->cam_sw_inf);
1058
+
1059
+ if (__v4l2_ctrl_handler_setup(&sc3338->ctrl_handler))
1060
+ dev_err(dev, "__v4l2_ctrl_handler_setup fail!");
1061
+
1062
+ if (sc3338->has_init_exp && sc3338->cur_mode != NO_HDR) { // hdr mode
1063
+ ret = sc3338_ioctl(&sc3338->subdev, PREISP_CMD_SET_HDRAE_EXP,
1064
+ &sc3338->cam_sw_inf->hdr_ae);
1065
+ if (ret) {
1066
+ dev_err(&sc3338->client->dev, "set exp fail in hdr mode\n");
1067
+ return ret;
1068
+ }
1069
+ }
1070
+ return 0;
1071
+}
1072
+
1073
+static int sc3338_suspend(struct device *dev)
1074
+{
1075
+ struct i2c_client *client = to_i2c_client(dev);
1076
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1077
+ struct sc3338 *sc3338 = to_sc3338(sd);
1078
+
1079
+ cam_sw_write_array_cb_init(sc3338->cam_sw_inf, client,
1080
+ (void *)sc3338->cur_mode->reg_list, (sensor_write_array)sc3338_write_array);
1081
+ cam_sw_prepare_sleep(sc3338->cam_sw_inf);
1082
+
1083
+ return 0;
1084
+}
1085
+#endif
1086
+
10391087 static int sc3338_runtime_resume(struct device *dev)
10401088 {
10411089 struct i2c_client *client = to_i2c_client(dev);
....@@ -1094,8 +1142,10 @@
10941142 }
10951143
10961144 static const struct dev_pm_ops sc3338_pm_ops = {
1097
- SET_RUNTIME_PM_OPS(sc3338_runtime_suspend,
1098
- sc3338_runtime_resume, NULL)
1145
+ SET_RUNTIME_PM_OPS(sc3338_runtime_suspend, sc3338_runtime_resume, NULL)
1146
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
1147
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(sc3338_suspend, sc3338_resume)
1148
+#endif
10991149 };
11001150
11011151 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
....@@ -1202,8 +1252,7 @@
12021252 (ctrl->val + sc3338->cur_mode->height)
12031253 & 0xff);
12041254 sc3338->cur_vts = ctrl->val + sc3338->cur_mode->height;
1205
- if (sc3338->cur_vts != sc3338->cur_mode->vts_def)
1206
- sc3338_modify_fps_info(sc3338);
1255
+ sc3338_modify_fps_info(sc3338);
12071256 break;
12081257 case V4L2_CID_TEST_PATTERN:
12091258 ret = sc3338_enable_test_pattern(sc3338, ctrl->val);
....@@ -1395,11 +1444,11 @@
13951444 return -EINVAL;
13961445 }
13971446
1398
- sc3338->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
1447
+ sc3338->reset_gpio = devm_gpiod_get(dev, "reset", sc3338->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
13991448 if (IS_ERR(sc3338->reset_gpio))
14001449 dev_warn(dev, "Failed to get reset-gpios\n");
14011450
1402
- sc3338->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
1451
+ sc3338->pwdn_gpio = devm_gpiod_get(dev, "pwdn", sc3338->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
14031452 if (IS_ERR(sc3338->pwdn_gpio))
14041453 dev_warn(dev, "Failed to get pwdn-gpios\n");
14051454
....@@ -1455,6 +1504,13 @@
14551504 goto err_power_off;
14561505 #endif
14571506
1507
+ if (!sc3338->cam_sw_inf) {
1508
+ sc3338->cam_sw_inf = cam_sw_init();
1509
+ cam_sw_clk_init(sc3338->cam_sw_inf, sc3338->xvclk, SC3338_XVCLK_FREQ);
1510
+ cam_sw_reset_pin_init(sc3338->cam_sw_inf, sc3338->reset_gpio, 0);
1511
+ cam_sw_pwdn_pin_init(sc3338->cam_sw_inf, sc3338->pwdn_gpio, 1);
1512
+ }
1513
+
14581514 memset(facing, 0, sizeof(facing));
14591515 if (strcmp(sc3338->module_facing, "back") == 0)
14601516 facing[0] = 'b';
....@@ -1505,6 +1561,8 @@
15051561 v4l2_ctrl_handler_free(&sc3338->ctrl_handler);
15061562 mutex_destroy(&sc3338->mutex);
15071563
1564
+ cam_sw_deinit(sc3338->cam_sw_inf);
1565
+
15081566 pm_runtime_disable(&client->dev);
15091567 if (!pm_runtime_status_suspended(&client->dev))
15101568 __sc3338_power_off(sc3338);