hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/i2c/sc200ai.c
....@@ -11,8 +11,11 @@
1111 * V0.0X01.0X05 add quick stream on/off.
1212 * V0.0X01.0X06 fix set vflip/hflip failed bug.
1313 * V0.0X01.0X07
14
- * 1. fix set double times exposue value failed issue.
15
- * 2. add some debug info.
14
+ * 1. fix set double times exposue value failed issue.
15
+ * 2. add some debug info.
16
+ * V0.0X01.0X08
17
+ * 1. add support wakeup & sleep for aov function
18
+ * 2. using 60fps output default
1619 */
1720
1821 #include <linux/clk.h>
....@@ -34,8 +37,10 @@
3437 #include <media/v4l2-subdev.h>
3538 #include <linux/pinctrl/consumer.h>
3639 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
40
+#include "cam-tb-setup.h"
41
+#include "cam-sleep-wakeup.h"
3742
38
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x07)
43
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x08)
3944
4045 #ifndef V4L2_CID_DIGITAL_GAIN
4146 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
....@@ -179,6 +184,7 @@
179184 bool is_thunderboot;
180185 bool is_first_streamoff;
181186 struct preisp_hdrae_exp_s init_hdrae_exp;
187
+ struct cam_sw_info *cam_sw_inf;
182188 };
183189
184190 #define to_sc200ai(sd) container_of(sd, struct sc200ai, subdev)
....@@ -611,20 +617,6 @@
611617 .height = 1080,
612618 .max_fps = {
613619 .numerator = 10000,
614
- .denominator = 300000,
615
- },
616
- .exp_def = 0x0080,
617
- .hts_def = 0x44C * 2,
618
- .vts_def = 0x0465,
619
- .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
620
- .reg_list = sc200ai_linear_10_1920x1080_30fps_regs,
621
- .hdr_mode = NO_HDR,
622
- .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
623
- }, {
624
- .width = 1920,
625
- .height = 1080,
626
- .max_fps = {
627
- .numerator = 10000,
628620 .denominator = 600000,
629621 },
630622 .exp_def = 0x0080,
....@@ -634,7 +626,23 @@
634626 .reg_list = sc200ai_linear_10_1920x1080_60fps_regs,
635627 .hdr_mode = NO_HDR,
636628 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
637
- }, {
629
+ },
630
+ {
631
+ .width = 1920,
632
+ .height = 1080,
633
+ .max_fps = {
634
+ .numerator = 10000,
635
+ .denominator = 300000,
636
+ },
637
+ .exp_def = 0x0080,
638
+ .hts_def = 0x44C * 2,
639
+ .vts_def = 0x0465,
640
+ .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
641
+ .reg_list = sc200ai_linear_10_1920x1080_30fps_regs,
642
+ .hdr_mode = NO_HDR,
643
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
644
+ },
645
+ {
638646 .width = 1920,
639647 .height = 1080,
640648 .max_fps = {
....@@ -1215,17 +1223,23 @@
12151223 break;
12161224 case PREISP_CMD_SET_HDRAE_EXP:
12171225 sc200ai_set_hdrae(sc200ai, arg);
1226
+ if (sc200ai->cam_sw_inf)
1227
+ memcpy(&sc200ai->cam_sw_inf->hdr_ae, (struct preisp_hdrae_exp_s *)(arg),
1228
+ sizeof(struct preisp_hdrae_exp_s));
12181229 break;
12191230 case RKMODULE_SET_QUICK_STREAM:
12201231
12211232 stream = *((u32 *)arg);
12221233
1223
- if (stream)
1234
+ if (stream) {
1235
+ gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 1);
12241236 ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
12251237 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_STREAMING);
1226
- else
1238
+ } else {
12271239 ret = sc200ai_write_reg(sc200ai->client, SC200AI_REG_CTRL_MODE,
12281240 SC200AI_REG_VALUE_08BIT, SC200AI_MODE_SW_STANDBY);
1241
+ gpiod_set_value_cansleep(sc200ai->pwdn_gpio, 0);
1242
+ }
12291243 break;
12301244 case RKMODULE_GET_CHANNEL_INFO:
12311245 ch_info = (struct rkmodule_channel_info *)arg;
....@@ -1512,6 +1526,9 @@
15121526 dev_err(dev, "Failed to enable xvclk\n");
15131527 return ret;
15141528 }
1529
+
1530
+ cam_sw_regulator_bulk_init(sc200ai->cam_sw_inf, SC200AI_NUM_SUPPLIES, sc200ai->supplies);
1531
+
15151532 if (sc200ai->is_thunderboot)
15161533 return 0;
15171534
....@@ -1576,6 +1593,51 @@
15761593 regulator_bulk_disable(SC200AI_NUM_SUPPLIES, sc200ai->supplies);
15771594 }
15781595
1596
+#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
1597
+static int __maybe_unused sc200ai_resume(struct device *dev)
1598
+{
1599
+ int ret;
1600
+ struct i2c_client *client = to_i2c_client(dev);
1601
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1602
+ struct sc200ai *sc200ai = to_sc200ai(sd);
1603
+
1604
+ cam_sw_prepare_wakeup(sc200ai->cam_sw_inf, dev);
1605
+
1606
+ usleep_range(4000, 5000);
1607
+ cam_sw_write_array(sc200ai->cam_sw_inf);
1608
+
1609
+ if (__v4l2_ctrl_handler_setup(&sc200ai->ctrl_handler))
1610
+ dev_err(dev, "__v4l2_ctrl_handler_setup fail!");
1611
+
1612
+ if (sc200ai->has_init_exp && sc200ai->cur_mode != NO_HDR) { // hdr mode
1613
+ ret = sc200ai_ioctl(&sc200ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1614
+ &sc200ai->cam_sw_inf->hdr_ae);
1615
+ if (ret) {
1616
+ dev_err(&sc200ai->client->dev, "set exp fail in hdr mode\n");
1617
+ return ret;
1618
+ }
1619
+ }
1620
+ return 0;
1621
+}
1622
+
1623
+static int __maybe_unused sc200ai_suspend(struct device *dev)
1624
+{
1625
+ struct i2c_client *client = to_i2c_client(dev);
1626
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
1627
+ struct sc200ai *sc200ai = to_sc200ai(sd);
1628
+
1629
+ cam_sw_write_array_cb_init(sc200ai->cam_sw_inf, client,
1630
+ (void *)sc200ai->cur_mode->reg_list,
1631
+ (sensor_write_array)sc200ai_write_array);
1632
+ cam_sw_prepare_sleep(sc200ai->cam_sw_inf);
1633
+
1634
+ return 0;
1635
+}
1636
+#else
1637
+#define sc200ai_resume NULL
1638
+#define sc200ai_suspend NULL
1639
+#endif
1640
+
15791641 static int sc200ai_runtime_resume(struct device *dev)
15801642 {
15811643 struct i2c_client *client = to_i2c_client(dev);
....@@ -1636,6 +1698,7 @@
16361698 static const struct dev_pm_ops sc200ai_pm_ops = {
16371699 SET_RUNTIME_PM_OPS(sc200ai_runtime_suspend,
16381700 sc200ai_runtime_resume, NULL)
1701
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(sc200ai_suspend, sc200ai_resume)
16391702 };
16401703
16411704 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
....@@ -1889,109 +1952,28 @@
18891952 }
18901953
18911954 #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
1892
-static u32 rk_cam_hdr;
1893
-static u32 rk_cam_w;
1894
-static u32 rk_cam_h;
1895
-static u32 rk_cam_fps;
1896
-
1897
-static int __init __maybe_unused rk_cam_hdr_setup(char *str)
1898
-{
1899
- int ret = 0;
1900
- unsigned long val = 0;
1901
-
1902
- ret = kstrtoul(str, 0, &val);
1903
- if (!ret)
1904
- rk_cam_hdr = (u32)val;
1905
- else
1906
- pr_err("get rk_cam_hdr fail\n");
1907
- return 1;
1908
-}
1909
-
1910
-static int __init __maybe_unused rk_cam_w_setup(char *str)
1911
-{
1912
- int ret = 0;
1913
- unsigned long val = 0;
1914
-
1915
- ret = kstrtoul(str, 0, &val);
1916
- if (!ret)
1917
- rk_cam_w = (u32)val;
1918
- else
1919
- pr_err("get rk_cam_w fail\n");
1920
- return 1;
1921
-}
1922
-
1923
-static int __init __maybe_unused rk_cam_h_setup(char *str)
1924
-{
1925
- int ret = 0;
1926
- unsigned long val = 0;
1927
-
1928
- ret = kstrtoul(str, 0, &val);
1929
- if (!ret)
1930
- rk_cam_h = (u32)val;
1931
- else
1932
- pr_err("get rk_cam_h fail\n");
1933
- return 1;
1934
-}
1935
-
1936
-static int __init __maybe_unused rk_cam_fps_setup(char *str)
1937
-{
1938
- int ret = 0;
1939
- unsigned long val = 0;
1940
-
1941
- ret = kstrtoul(str, 0, &val);
1942
- if (!ret)
1943
- rk_cam_fps = (u32)val;
1944
- else
1945
- pr_err("get rk_cam_fps fail\n");
1946
- return 1;
1947
-}
1948
-
1949
-__setup("rk_cam_hdr=", rk_cam_hdr_setup);
1950
-__setup("rk_cam_w=", rk_cam_w_setup);
1951
-__setup("rk_cam_h=", rk_cam_h_setup);
1952
-__setup("rk_cam_fps=", rk_cam_fps_setup);
1953
-
19541955 static void find_terminal_resolution(struct sc200ai *sc200ai)
19551956 {
19561957 int i = 0;
19571958 const struct sc200ai_mode *mode = NULL;
1958
- const struct sc200ai_mode *fit_mode = NULL;
1959
- u32 cur_fps = 0;
1960
- u32 dst_fps = 0;
1961
- u32 tmp_fps = 0;
1959
+ u32 rk_cam_hdr = get_rk_cam_hdr();
1960
+ u32 rk_cam_w = get_rk_cam_w();
1961
+ u32 rk_cam_h = get_rk_cam_h();
19621962
1963
- if (rk_cam_w == 0 || rk_cam_h == 0 ||
1964
- rk_cam_fps == 0)
1963
+ if (rk_cam_w == 0 || rk_cam_h == 0)
19651964 goto err_find_res;
19661965
1967
- dst_fps = rk_cam_fps;
19681966 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
19691967 mode = &supported_modes[i];
1970
- cur_fps = mode->max_fps.denominator / mode->max_fps.numerator;
19711968 if (mode->width == rk_cam_w && mode->height == rk_cam_h &&
19721969 mode->hdr_mode == rk_cam_hdr) {
1973
- if (cur_fps == dst_fps) {
1974
- sc200ai->cur_mode = mode;
1975
- return;
1976
- }
1977
- if (cur_fps >= dst_fps) {
1978
- if (fit_mode) {
1979
- tmp_fps = fit_mode->max_fps.denominator / fit_mode->max_fps.numerator;
1980
- if (tmp_fps - dst_fps > cur_fps - dst_fps)
1981
- fit_mode = mode;
1982
- } else {
1983
- fit_mode = mode;
1984
- }
1985
- }
1970
+ sc200ai->cur_mode = mode;
1971
+ return;
19861972 }
19871973 }
1988
- if (fit_mode) {
1989
- sc200ai->cur_mode = fit_mode;
1990
- return;
1991
- }
19921974 err_find_res:
1993
- dev_err(&sc200ai->client->dev, "not match %dx%d@%dfps mode %d\n!",
1994
- rk_cam_w, rk_cam_h, dst_fps, rk_cam_hdr);
1975
+ dev_err(&sc200ai->client->dev, "not match %dx%d mode %d\n!",
1976
+ rk_cam_w, rk_cam_h, rk_cam_hdr);
19951977 sc200ai->cur_mode = &supported_modes[0];
19961978 }
19971979 #else
....@@ -2057,11 +2039,11 @@
20572039 return -EINVAL;
20582040 }
20592041
2060
- sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
2042
+ sc200ai->reset_gpio = devm_gpiod_get(dev, "reset", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
20612043 if (IS_ERR(sc200ai->reset_gpio))
20622044 dev_warn(dev, "Failed to get reset-gpios\n");
20632045
2064
- sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
2046
+ sc200ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", sc200ai->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
20652047 if (IS_ERR(sc200ai->pwdn_gpio))
20662048 dev_warn(dev, "Failed to get pwdn-gpios\n");
20672049
....@@ -2117,6 +2099,13 @@
21172099 goto err_power_off;
21182100 #endif
21192101
2102
+ if (!sc200ai->cam_sw_inf) {
2103
+ sc200ai->cam_sw_inf = cam_sw_init();
2104
+ cam_sw_clk_init(sc200ai->cam_sw_inf, sc200ai->xvclk, SC200AI_XVCLK_FREQ);
2105
+ cam_sw_reset_pin_init(sc200ai->cam_sw_inf, sc200ai->reset_gpio, 0);
2106
+ cam_sw_pwdn_pin_init(sc200ai->cam_sw_inf, sc200ai->pwdn_gpio, 1);
2107
+ }
2108
+
21202109 memset(facing, 0, sizeof(facing));
21212110 if (strcmp(sc200ai->module_facing, "back") == 0)
21222111 facing[0] = 'b';
....@@ -2167,6 +2156,8 @@
21672156 v4l2_ctrl_handler_free(&sc200ai->ctrl_handler);
21682157 mutex_destroy(&sc200ai->mutex);
21692158
2159
+ cam_sw_deinit(sc200ai->cam_sw_inf);
2160
+
21702161 pm_runtime_disable(&client->dev);
21712162 if (!pm_runtime_status_suspended(&client->dev))
21722163 __sc200ai_power_off(sc200ai);