hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/media/i2c/sc500ai.c
....@@ -123,14 +123,6 @@
123123
124124 #define sc500ai_NUM_SUPPLIES ARRAY_SIZE(sc500ai_supply_names)
125125
126
-enum sc500ai_max_pad {
127
- PAD0, /* link to isp */
128
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
129
- PAD2, /* link to csi wr1 | hdr x3:L */
130
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
131
- PAD_MAX,
132
-};
133
-
134126 struct regval {
135127 u16 addr;
136128 u8 val;
....@@ -173,6 +165,7 @@
173165 struct v4l2_ctrl *pixel_rate;
174166 struct v4l2_ctrl *link_freq;
175167 struct mutex mutex;
168
+ struct v4l2_fract cur_fps;
176169 bool streaming;
177170 bool power_on;
178171 const struct sc500ai_mode *cur_mode;
....@@ -277,6 +270,7 @@
277270 {0x3e17, 0x80},
278271 {0x4500, 0x88},
279272 {0x4509, 0x20},
273
+ {0x4800, 0x04},
280274 {0x5799, 0x00},
281275 {0x59e0, 0x60},
282276 {0x59e1, 0x08},
....@@ -596,6 +590,8 @@
596590 __v4l2_ctrl_s_ctrl(sc500ai->link_freq, mode->mipi_freq_idx);
597591 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC500AI_LANES;
598592 __v4l2_ctrl_s_ctrl_int64(sc500ai->pixel_rate, pixel_rate);
593
+ sc500ai->cur_fps = mode->max_fps;
594
+ sc500ai->cur_vts = mode->vts_def;
599595 }
600596
601597 mutex_unlock(&sc500ai->mutex);
....@@ -671,14 +667,15 @@
671667 struct sc500ai *sc500ai = to_sc500ai(sd);
672668 const struct sc500ai_mode *mode = sc500ai->cur_mode;
673669
674
- mutex_lock(&sc500ai->mutex);
675
- fi->interval = mode->max_fps;
676
- mutex_unlock(&sc500ai->mutex);
670
+ if (sc500ai->streaming)
671
+ fi->interval = sc500ai->cur_fps;
672
+ else
673
+ fi->interval = mode->max_fps;
677674
678675 return 0;
679676 }
680677
681
-static int sc500ai_g_mbus_config(struct v4l2_subdev *sd,
678
+static int sc500ai_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
682679 struct v4l2_mbus_config *config)
683680 {
684681 struct sc500ai *sc500ai = to_sc500ai(sd);
....@@ -692,7 +689,7 @@
692689 if (mode->hdr_mode == HDR_X3)
693690 val |= V4L2_MBUS_CSI2_CHANNEL_2;
694691
695
- config->type = V4L2_MBUS_CSI2;
692
+ config->type = V4L2_MBUS_CSI2_DPHY;
696693 config->flags = val;
697694
698695 return 0;
....@@ -911,11 +908,23 @@
911908 return ret;
912909 }
913910
911
+static int sc500ai_get_channel_info(struct sc500ai *sc500ai, struct rkmodule_channel_info *ch_info)
912
+{
913
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
914
+ return -EINVAL;
915
+ ch_info->vc = sc500ai->cur_mode->vc[ch_info->index];
916
+ ch_info->width = sc500ai->cur_mode->width;
917
+ ch_info->height = sc500ai->cur_mode->height;
918
+ ch_info->bus_fmt = sc500ai->cur_mode->bus_fmt;
919
+ return 0;
920
+}
921
+
914922 static long sc500ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
915923 {
916924 struct sc500ai *sc500ai = to_sc500ai(sd);
917925 struct rkmodule_hdr_cfg *hdr;
918926 const struct sc500ai_mode *mode;
927
+ struct rkmodule_channel_info *ch_info;
919928
920929 long ret = 0;
921930 u32 i, h, w;
....@@ -959,7 +968,8 @@
959968 __v4l2_ctrl_s_ctrl(sc500ai->link_freq, mode->mipi_freq_idx);
960969 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC500AI_LANES;
961970 __v4l2_ctrl_s_ctrl_int64(sc500ai->pixel_rate, pixel_rate);
962
-
971
+ sc500ai->cur_fps = mode->max_fps;
972
+ sc500ai->cur_vts = mode->vts_def;
963973 dev_info(&sc500ai->client->dev, "sensor mode: %d\n", sc500ai->cur_mode->hdr_mode);
964974 }
965975 break;
....@@ -976,6 +986,10 @@
976986 ret = sc500ai_write_reg(sc500ai->client, SC500AI_REG_CTRL_MODE,
977987 SC500AI_REG_VALUE_08BIT, SC500AI_MODE_SW_STANDBY);
978988 break;
989
+ case RKMODULE_GET_CHANNEL_INFO:
990
+ ch_info = (struct rkmodule_channel_info *)arg;
991
+ ret = sc500ai_get_channel_info(sc500ai, ch_info);
992
+ break;
979993 default:
980994 ret = -ENOIOCTLCMD;
981995 break;
....@@ -990,9 +1004,9 @@
9901004 {
9911005 void __user *up = compat_ptr(arg);
9921006 struct rkmodule_inf *inf;
993
- struct rkmodule_awb_cfg *cfg;
9941007 struct rkmodule_hdr_cfg *hdr;
9951008 struct preisp_hdrae_exp_s *hdrae;
1009
+ struct rkmodule_channel_info *ch_info;
9961010 long ret = 0;
9971011 u32 stream = 0;
9981012
....@@ -1005,21 +1019,12 @@
10051019 }
10061020
10071021 ret = sc500ai_ioctl(sd, cmd, inf);
1008
- if (!ret)
1022
+ if (!ret) {
10091023 ret = copy_to_user(up, inf, sizeof(*inf));
1010
- kfree(inf);
1011
- break;
1012
- case RKMODULE_AWB_CFG:
1013
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
1014
- if (!cfg) {
1015
- ret = -ENOMEM;
1016
- return ret;
1024
+ if (ret)
1025
+ ret = -EFAULT;
10171026 }
1018
-
1019
- ret = copy_from_user(cfg, up, sizeof(*cfg));
1020
- if (!ret)
1021
- ret = sc500ai_ioctl(sd, cmd, cfg);
1022
- kfree(cfg);
1027
+ kfree(inf);
10231028 break;
10241029 case RKMODULE_GET_HDR_CFG:
10251030 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
....@@ -1029,8 +1034,11 @@
10291034 }
10301035
10311036 ret = sc500ai_ioctl(sd, cmd, hdr);
1032
- if (!ret)
1037
+ if (!ret) {
10331038 ret = copy_to_user(up, hdr, sizeof(*hdr));
1039
+ if (ret)
1040
+ ret = -EFAULT;
1041
+ }
10341042 kfree(hdr);
10351043 break;
10361044 case RKMODULE_SET_HDR_CFG:
....@@ -1040,9 +1048,10 @@
10401048 return ret;
10411049 }
10421050
1043
- ret = copy_from_user(hdr, up, sizeof(*hdr));
1044
- if (!ret)
1045
- ret = sc500ai_ioctl(sd, cmd, hdr);
1051
+ if (copy_from_user(hdr, up, sizeof(*hdr)))
1052
+ return -EFAULT;
1053
+
1054
+ ret = sc500ai_ioctl(sd, cmd, hdr);
10461055 kfree(hdr);
10471056 break;
10481057 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -1052,15 +1061,32 @@
10521061 return ret;
10531062 }
10541063
1055
- ret = copy_from_user(hdrae, up, sizeof(*hdrae));
1056
- if (!ret)
1057
- ret = sc500ai_ioctl(sd, cmd, hdrae);
1064
+ if (copy_from_user(hdrae, up, sizeof(*hdrae)))
1065
+ return -EFAULT;
1066
+
1067
+ ret = sc500ai_ioctl(sd, cmd, hdrae);
10581068 kfree(hdrae);
10591069 break;
10601070 case RKMODULE_SET_QUICK_STREAM:
1061
- ret = copy_from_user(&stream, up, sizeof(u32));
1062
- if (!ret)
1063
- ret = sc500ai_ioctl(sd, cmd, &stream);
1071
+ if (copy_from_user(&stream, up, sizeof(u32)))
1072
+ return -EFAULT;
1073
+
1074
+ ret = sc500ai_ioctl(sd, cmd, &stream);
1075
+ break;
1076
+ case RKMODULE_GET_CHANNEL_INFO:
1077
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
1078
+ if (!ch_info) {
1079
+ ret = -ENOMEM;
1080
+ return ret;
1081
+ }
1082
+
1083
+ ret = sc500ai_ioctl(sd, cmd, ch_info);
1084
+ if (!ret) {
1085
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
1086
+ if (ret)
1087
+ ret = -EFAULT;
1088
+ }
1089
+ kfree(ch_info);
10641090 break;
10651091 default:
10661092 ret = -ENOIOCTLCMD;
....@@ -1348,7 +1374,6 @@
13481374 static const struct v4l2_subdev_video_ops sc500ai_video_ops = {
13491375 .s_stream = sc500ai_s_stream,
13501376 .g_frame_interval = sc500ai_g_frame_interval,
1351
- .g_mbus_config = sc500ai_g_mbus_config,
13521377 };
13531378
13541379 static const struct v4l2_subdev_pad_ops sc500ai_pad_ops = {
....@@ -1358,6 +1383,7 @@
13581383 .get_fmt = sc500ai_get_fmt,
13591384 .set_fmt = sc500ai_set_fmt,
13601385 .get_selection = sc500ai_get_selection,
1386
+ .get_mbus_config = sc500ai_g_mbus_config,
13611387 };
13621388
13631389 static const struct v4l2_subdev_ops sc500ai_subdev_ops = {
....@@ -1365,6 +1391,14 @@
13651391 .video = &sc500ai_video_ops,
13661392 .pad = &sc500ai_pad_ops,
13671393 };
1394
+
1395
+static void sc500ai_modify_fps_info(struct sc500ai *sc500ai)
1396
+{
1397
+ const struct sc500ai_mode *mode = sc500ai->cur_mode;
1398
+
1399
+ sc500ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1400
+ sc500ai->cur_vts;
1401
+}
13681402
13691403 static int sc500ai_set_ctrl(struct v4l2_ctrl *ctrl)
13701404 {
....@@ -1399,7 +1433,7 @@
13991433 switch (ctrl->id) {
14001434 case V4L2_CID_EXPOSURE:
14011435 if (sc500ai->cur_mode->hdr_mode != NO_HDR)
1402
- return ret;
1436
+ goto ctrl_end;
14031437 val = ctrl->val << 1;
14041438 ret = sc500ai_write_reg(sc500ai->client,
14051439 SC500AI_REG_EXPOSURE_H,
....@@ -1418,7 +1452,7 @@
14181452 break;
14191453 case V4L2_CID_ANALOGUE_GAIN:
14201454 if (sc500ai->cur_mode->hdr_mode != NO_HDR)
1421
- return ret;
1455
+ goto ctrl_end;
14221456
14231457 sc500ai_get_gain_reg(ctrl->val, &again, &again_fine, &dgain, &dgain_fine);
14241458 ret = sc500ai_write_reg(sc500ai->client,
....@@ -1453,7 +1487,9 @@
14531487 SC500AI_REG_VTS_L,
14541488 SC500AI_REG_VALUE_08BIT,
14551489 vts & 0xff);
1456
- sc500ai->cur_vts = vts;
1490
+ if (!ret)
1491
+ sc500ai->cur_vts = vts;
1492
+ sc500ai_modify_fps_info(sc500ai);
14571493 break;
14581494 case V4L2_CID_HFLIP:
14591495 ret = sc500ai_read_reg(sc500ai->client, SC500AI_FLIP_MIRROR_REG,
....@@ -1520,6 +1556,7 @@
15201556 break;
15211557 }
15221558
1559
+ctrl_end:
15231560 pm_runtime_put(&client->dev);
15241561
15251562 return ret;
....@@ -1565,6 +1602,7 @@
15651602
15661603 vblank_def = mode->vts_def - mode->height;
15671604 sc500ai->cur_vts = mode->vts_def;
1605
+ sc500ai->cur_fps = mode->max_fps;
15681606 sc500ai->vblank = v4l2_ctrl_new_std(handler, &sc500ai_ctrl_ops,
15691607 V4L2_CID_VBLANK, vblank_def,
15701608 SC500AI_VTS_MAX - mode->height,