hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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
....@@ -1454,6 +1504,13 @@
14541504 goto err_power_off;
14551505 #endif
14561506
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
+
14571514 memset(facing, 0, sizeof(facing));
14581515 if (strcmp(sc3338->module_facing, "back") == 0)
14591516 facing[0] = 'b';
....@@ -1504,6 +1561,8 @@
15041561 v4l2_ctrl_handler_free(&sc3338->ctrl_handler);
15051562 mutex_destroy(&sc3338->mutex);
15061563
1564
+ cam_sw_deinit(sc3338->cam_sw_inf);
1565
+
15071566 pm_runtime_disable(&client->dev);
15081567 if (!pm_runtime_status_suspended(&client->dev))
15091568 __sc3338_power_off(sc3338);