hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/i2c/sc230ai.c
....@@ -173,6 +173,7 @@
173173 const char *module_facing;
174174 const char *module_name;
175175 const char *len_name;
176
+ enum rkmodule_sync_mode sync_mode;
176177 u32 cur_vts;
177178 bool has_init_exp;
178179 bool is_thunderboot;
....@@ -534,6 +535,28 @@
534535 {REG_NULL, 0x00},
535536 };
536537
538
+static __maybe_unused const struct regval sc230ai_interal_sync_master_start_regs[] = {
539
+ {0x300a, 0x24}, //sync as output PAD
540
+ {0x3032, 0xa0},
541
+ {0x3222, 0x00}, //master mode
542
+ {REG_NULL, 0x00},
543
+};
544
+
545
+static __maybe_unused const struct regval sc230ai_interal_sync_master_stop_regs[] = {
546
+ {REG_NULL, 0x00},
547
+};
548
+
549
+static __maybe_unused const struct regval sc230ai_interal_sync_slaver_start_regs[] = {
550
+ {0x300a, 0x20}, //sync as input PAD
551
+ {0x3222, 0x01}, //slave mode
552
+ {0x3224, 0x92}, //fsync trigger
553
+ {0x3614, 0x01},
554
+ {REG_NULL, 0x00},
555
+};
556
+
557
+static __maybe_unused const struct regval sc230ai_interal_sync_slaver_stop_regs[] = {
558
+ {REG_NULL, 0x00},
559
+};
537560
538561 static const struct sc230ai_mode supported_modes[] = {
539562 {
....@@ -930,6 +953,7 @@
930953 u32 i, h, w;
931954 long ret = 0;
932955 u32 stream = 0;
956
+ u32 *sync_mode = NULL;
933957
934958 switch (cmd) {
935959 case RKMODULE_GET_MODULE_INFO:
....@@ -980,6 +1004,14 @@
9801004 ret = sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
9811005 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY);
9821006 break;
1007
+ case RKMODULE_GET_SYNC_MODE:
1008
+ sync_mode = (u32 *)arg;
1009
+ *sync_mode = sc230ai->sync_mode;
1010
+ break;
1011
+ case RKMODULE_SET_SYNC_MODE:
1012
+ sync_mode = (u32 *)arg;
1013
+ sc230ai->sync_mode = *sync_mode;
1014
+ break;
9831015 default:
9841016 ret = -ENOIOCTLCMD;
9851017 break;
....@@ -998,6 +1030,7 @@
9981030 struct preisp_hdrae_exp_s *hdrae;
9991031 long ret;
10001032 u32 stream = 0;
1033
+ u32 sync_mode;
10011034
10021035 switch (cmd) {
10031036 case RKMODULE_GET_MODULE_INFO:
....@@ -1066,6 +1099,21 @@
10661099
10671100 ret = sc230ai_ioctl(sd, cmd, &stream);
10681101 break;
1102
+ case RKMODULE_GET_SYNC_MODE:
1103
+ ret = sc230ai_ioctl(sd, cmd, &sync_mode);
1104
+ if (!ret) {
1105
+ ret = copy_to_user(up, &sync_mode, sizeof(u32));
1106
+ if (ret)
1107
+ ret = -EFAULT;
1108
+ }
1109
+ break;
1110
+ case RKMODULE_SET_SYNC_MODE:
1111
+ ret = copy_from_user(&sync_mode, up, sizeof(u32));
1112
+ if (!ret)
1113
+ ret = sc230ai_ioctl(sd, cmd, &sync_mode);
1114
+ else
1115
+ ret = -EFAULT;
1116
+ break;
10691117 default:
10701118 ret = -ENOIOCTLCMD;
10711119 break;
....@@ -1077,7 +1125,7 @@
10771125
10781126 static int __sc230ai_start_stream(struct sc230ai *sc230ai)
10791127 {
1080
- int ret;
1128
+ int ret = 0;
10811129
10821130 if (!sc230ai->is_thunderboot) {
10831131 ret = sc230ai_write_array(sc230ai->client, sc230ai->cur_mode->reg_list);
....@@ -1096,20 +1144,36 @@
10961144 return ret;
10971145 }
10981146 }
1147
+ if (sc230ai->sync_mode == INTERNAL_MASTER_MODE)
1148
+ ret |= sc230ai_write_array(sc230ai->client,
1149
+ sc230ai_interal_sync_master_start_regs);
1150
+ else if (sc230ai->sync_mode == SLAVE_MODE)
1151
+ ret |= sc230ai_write_array(sc230ai->client,
1152
+ sc230ai_interal_sync_slaver_start_regs);
10991153 }
1100
- return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
1154
+ ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
11011155 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_STREAMING);
1156
+ return ret;
11021157 }
11031158
11041159 static int __sc230ai_stop_stream(struct sc230ai *sc230ai)
11051160 {
1161
+ int ret = 0;
11061162 sc230ai->has_init_exp = false;
11071163 if (sc230ai->is_thunderboot) {
11081164 sc230ai->is_first_streamoff = true;
11091165 pm_runtime_put(&sc230ai->client->dev);
1166
+ } else {
1167
+ if (sc230ai->sync_mode == INTERNAL_MASTER_MODE)
1168
+ ret |= sc230ai_write_array(sc230ai->client,
1169
+ sc230ai_interal_sync_master_stop_regs);
1170
+ else if (sc230ai->sync_mode == SLAVE_MODE)
1171
+ ret |= sc230ai_write_array(sc230ai->client,
1172
+ sc230ai_interal_sync_slaver_stop_regs);
11101173 }
1111
- return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
1174
+ ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
11121175 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY);
1176
+ return ret;
11131177 }
11141178
11151179 static int __sc230ai_power_on(struct sc230ai *sc230ai);
....@@ -1625,6 +1689,7 @@
16251689 char facing[2];
16261690 int ret;
16271691 u32 i, hdr_mode = 0;
1692
+ const char *sync_mode_name = NULL;
16281693
16291694 dev_info(dev, "driver version: %02x.%02x.%02x",
16301695 DRIVER_VERSION >> 16,
....@@ -1648,6 +1713,25 @@
16481713 dev_err(dev, "could not get module information!\n");
16491714 return -EINVAL;
16501715 }
1716
+
1717
+ ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE,
1718
+ &sync_mode_name);
1719
+ if (ret) {
1720
+ sc230ai->sync_mode = NO_SYNC_MODE;
1721
+ dev_err(dev, "could not get sync mode!\n");
1722
+ } else {
1723
+ if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0) {
1724
+ sc230ai->sync_mode = EXTERNAL_MASTER_MODE;
1725
+ dev_info(dev, "external master mode\n");
1726
+ } else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0) {
1727
+ sc230ai->sync_mode = INTERNAL_MASTER_MODE;
1728
+ dev_info(dev, "internal master mode\n");
1729
+ } else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0) {
1730
+ sc230ai->sync_mode = SLAVE_MODE;
1731
+ dev_info(dev, "slave mode\n");
1732
+ }
1733
+ }
1734
+
16511735 sc230ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
16521736 sc230ai->client = client;
16531737 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {