forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/sc4238.c
....@@ -114,14 +114,6 @@
114114 #define MIRROR_BIT_MASK (BIT(1) | BIT(2))
115115 #define FLIP_BIT_MASK (BIT(6) | BIT(5))
116116
117
-enum sc4238_max_pad {
118
- PAD0,
119
- PAD1,
120
- PAD2,
121
- PAD3,
122
- PAD_MAX,
123
-};
124
-
125117 struct regval {
126118 u16 addr;
127119 u8 val;
....@@ -167,6 +159,7 @@
167159 struct v4l2_ctrl *h_flip;
168160 struct v4l2_ctrl *v_flip;
169161 struct mutex mutex;
162
+ struct v4l2_fract cur_fps;
170163 bool streaming;
171164 bool power_on;
172165 const struct sc4238_mode *cur_mode;
....@@ -1581,6 +1574,8 @@
15811574 mode->pixel_rate);
15821575 __v4l2_ctrl_s_ctrl(sc4238->link_freq,
15831576 mode->link_freq);
1577
+ sc4238->cur_fps = mode->max_fps;
1578
+ sc4238->cur_vts = mode->vts_def;
15841579 }
15851580
15861581 mutex_unlock(&sc4238->mutex);
....@@ -1674,14 +1669,15 @@
16741669 struct sc4238 *sc4238 = to_sc4238(sd);
16751670 const struct sc4238_mode *mode = sc4238->cur_mode;
16761671
1677
- mutex_lock(&sc4238->mutex);
1678
- fi->interval = mode->max_fps;
1679
- mutex_unlock(&sc4238->mutex);
1672
+ if (sc4238->streaming)
1673
+ fi->interval = sc4238->cur_fps;
1674
+ else
1675
+ fi->interval = mode->max_fps;
16801676
16811677 return 0;
16821678 }
16831679
1684
-static int sc4238_g_mbus_config(struct v4l2_subdev *sd,
1680
+static int sc4238_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
16851681 struct v4l2_mbus_config *config)
16861682 {
16871683 struct sc4238 *sc4238 = to_sc4238(sd);
....@@ -1698,7 +1694,7 @@
16981694 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
16991695 V4L2_MBUS_CSI2_CHANNEL_1;
17001696
1701
- config->type = V4L2_MBUS_CSI2;
1697
+ config->type = V4L2_MBUS_CSI2_DPHY;
17021698 config->flags = val;
17031699
17041700 return 0;
....@@ -1884,10 +1880,22 @@
18841880 return ret;
18851881 }
18861882
1883
+static int sc4238_get_channel_info(struct sc4238 *sc4238, struct rkmodule_channel_info *ch_info)
1884
+{
1885
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
1886
+ return -EINVAL;
1887
+ ch_info->vc = sc4238->cur_mode->vc[ch_info->index];
1888
+ ch_info->width = sc4238->cur_mode->width;
1889
+ ch_info->height = sc4238->cur_mode->height;
1890
+ ch_info->bus_fmt = sc4238->cur_mode->bus_fmt;
1891
+ return 0;
1892
+}
1893
+
18871894 static long sc4238_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
18881895 {
18891896 struct sc4238 *sc4238 = to_sc4238(sd);
18901897 struct rkmodule_hdr_cfg *hdr_cfg;
1898
+ struct rkmodule_channel_info *ch_info;
18911899 long ret = 0;
18921900 u32 i, h, w;
18931901 u32 stream = 0;
....@@ -1923,6 +1931,8 @@
19231931 __v4l2_ctrl_modify_range(sc4238->vblank, h,
19241932 SC4238_VTS_MAX - sc4238->cur_mode->height,
19251933 1, h);
1934
+ sc4238->cur_fps = sc4238->cur_mode->max_fps;
1935
+ sc4238->cur_vts = sc4238->cur_mode->vts_def;
19261936 dev_info(&sc4238->client->dev,
19271937 "sensor mode: %d\n",
19281938 sc4238->cur_mode->hdr_mode);
....@@ -1947,6 +1957,10 @@
19471957 ret = sc4238_write_reg(sc4238->client, SC4238_REG_CTRL_MODE,
19481958 SC4238_REG_VALUE_08BIT, SC4238_MODE_SW_STANDBY);
19491959 break;
1960
+ case RKMODULE_GET_CHANNEL_INFO:
1961
+ ch_info = (struct rkmodule_channel_info *)arg;
1962
+ ret = sc4238_get_channel_info(sc4238, ch_info);
1963
+ break;
19501964 default:
19511965 ret = -ENOIOCTLCMD;
19521966 break;
....@@ -1964,6 +1978,7 @@
19641978 struct rkmodule_awb_cfg *cfg;
19651979 struct rkmodule_hdr_cfg *hdr;
19661980 struct preisp_hdrae_exp_s *hdrae;
1981
+ struct rkmodule_channel_info *ch_info;
19671982 long ret;
19681983 u32 stream = 0;
19691984
....@@ -1976,8 +1991,11 @@
19761991 }
19771992
19781993 ret = sc4238_ioctl(sd, cmd, inf);
1979
- if (!ret)
1994
+ if (!ret) {
19801995 ret = copy_to_user(up, inf, sizeof(*inf));
1996
+ if (ret)
1997
+ ret = -EFAULT;
1998
+ }
19811999 kfree(inf);
19822000 break;
19832001 case RKMODULE_AWB_CFG:
....@@ -1990,6 +2008,8 @@
19902008 ret = copy_from_user(cfg, up, sizeof(*cfg));
19912009 if (!ret)
19922010 ret = sc4238_ioctl(sd, cmd, cfg);
2011
+ else
2012
+ ret = -EFAULT;
19932013 kfree(cfg);
19942014 break;
19952015 case RKMODULE_GET_HDR_CFG:
....@@ -2000,8 +2020,11 @@
20002020 }
20012021
20022022 ret = sc4238_ioctl(sd, cmd, hdr);
2003
- if (!ret)
2023
+ if (!ret) {
20042024 ret = copy_to_user(up, hdr, sizeof(*hdr));
2025
+ if (ret)
2026
+ ret = -EFAULT;
2027
+ }
20052028 kfree(hdr);
20062029 break;
20072030 case RKMODULE_SET_HDR_CFG:
....@@ -2014,6 +2037,8 @@
20142037 ret = copy_from_user(hdr, up, sizeof(*hdr));
20152038 if (!ret)
20162039 ret = sc4238_ioctl(sd, cmd, hdr);
2040
+ else
2041
+ ret = -EFAULT;
20172042 kfree(hdr);
20182043 break;
20192044 case PREISP_CMD_SET_HDRAE_EXP:
....@@ -2026,12 +2051,31 @@
20262051 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
20272052 if (!ret)
20282053 ret = sc4238_ioctl(sd, cmd, hdrae);
2054
+ else
2055
+ ret = -EFAULT;
20292056 kfree(hdrae);
20302057 break;
20312058 case RKMODULE_SET_QUICK_STREAM:
20322059 ret = copy_from_user(&stream, up, sizeof(u32));
20332060 if (!ret)
20342061 ret = sc4238_ioctl(sd, cmd, &stream);
2062
+ else
2063
+ ret = -EFAULT;
2064
+ break;
2065
+ case RKMODULE_GET_CHANNEL_INFO:
2066
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
2067
+ if (!ch_info) {
2068
+ ret = -ENOMEM;
2069
+ return ret;
2070
+ }
2071
+
2072
+ ret = sc4238_ioctl(sd, cmd, ch_info);
2073
+ if (!ret) {
2074
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
2075
+ if (ret)
2076
+ ret = -EFAULT;
2077
+ }
2078
+ kfree(ch_info);
20352079 break;
20362080 default:
20372081 ret = -ENOIOCTLCMD;
....@@ -2345,7 +2389,6 @@
23452389 static const struct v4l2_subdev_video_ops sc4238_video_ops = {
23462390 .s_stream = sc4238_s_stream,
23472391 .g_frame_interval = sc4238_g_frame_interval,
2348
- .g_mbus_config = sc4238_g_mbus_config,
23492392 };
23502393
23512394 static const struct v4l2_subdev_pad_ops sc4238_pad_ops = {
....@@ -2354,6 +2397,7 @@
23542397 .enum_frame_interval = sc4238_enum_frame_interval,
23552398 .get_fmt = sc4238_get_fmt,
23562399 .set_fmt = sc4238_set_fmt,
2400
+ .get_mbus_config = sc4238_g_mbus_config,
23572401 };
23582402
23592403 static const struct v4l2_subdev_ops sc4238_subdev_ops = {
....@@ -2361,6 +2405,14 @@
23612405 .video = &sc4238_video_ops,
23622406 .pad = &sc4238_pad_ops,
23632407 };
2408
+
2409
+static void sc4238_modify_fps_info(struct sc4238 *sc4238)
2410
+{
2411
+ const struct sc4238_mode *mode = sc4238->cur_mode;
2412
+
2413
+ sc4238->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
2414
+ sc4238->cur_vts;
2415
+}
23642416
23652417 static int sc4238_set_ctrl(struct v4l2_ctrl *ctrl)
23662418 {
....@@ -2432,6 +2484,7 @@
24322484 ctrl->val + sc4238->cur_mode->height);
24332485 if (ret == 0)
24342486 sc4238->cur_vts = ctrl->val + sc4238->cur_mode->height;
2487
+ sc4238_modify_fps_info(sc4238);
24352488 dev_dbg(&client->dev, "set vblank 0x%x\n",
24362489 ctrl->val);
24372490 break;
....@@ -2565,6 +2618,8 @@
25652618
25662619 sc4238->subdev.ctrl_handler = handler;
25672620 sc4238->has_init_exp = false;
2621
+ sc4238->cur_fps = mode->max_fps;
2622
+ sc4238->cur_vts = mode->vts_def;
25682623
25692624 return 0;
25702625