From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198
---
kernel/drivers/media/i2c/sc500ai.c | 122 ++++++++++++++++++++++++++--------------
1 files changed, 80 insertions(+), 42 deletions(-)
diff --git a/kernel/drivers/media/i2c/sc500ai.c b/kernel/drivers/media/i2c/sc500ai.c
index 63bc371..f5a2042 100644
--- a/kernel/drivers/media/i2c/sc500ai.c
+++ b/kernel/drivers/media/i2c/sc500ai.c
@@ -123,14 +123,6 @@
#define sc500ai_NUM_SUPPLIES ARRAY_SIZE(sc500ai_supply_names)
-enum sc500ai_max_pad {
- PAD0, /* link to isp */
- PAD1, /* link to csi wr0 | hdr x2:L x3:M */
- PAD2, /* link to csi wr1 | hdr x3:L */
- PAD3, /* link to csi wr2 | hdr x2:M x3:S */
- PAD_MAX,
-};
-
struct regval {
u16 addr;
u8 val;
@@ -173,6 +165,7 @@
struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *link_freq;
struct mutex mutex;
+ struct v4l2_fract cur_fps;
bool streaming;
bool power_on;
const struct sc500ai_mode *cur_mode;
@@ -277,6 +270,7 @@
{0x3e17, 0x80},
{0x4500, 0x88},
{0x4509, 0x20},
+ {0x4800, 0x04},
{0x5799, 0x00},
{0x59e0, 0x60},
{0x59e1, 0x08},
@@ -596,6 +590,8 @@
__v4l2_ctrl_s_ctrl(sc500ai->link_freq, mode->mipi_freq_idx);
pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC500AI_LANES;
__v4l2_ctrl_s_ctrl_int64(sc500ai->pixel_rate, pixel_rate);
+ sc500ai->cur_fps = mode->max_fps;
+ sc500ai->cur_vts = mode->vts_def;
}
mutex_unlock(&sc500ai->mutex);
@@ -671,14 +667,15 @@
struct sc500ai *sc500ai = to_sc500ai(sd);
const struct sc500ai_mode *mode = sc500ai->cur_mode;
- mutex_lock(&sc500ai->mutex);
- fi->interval = mode->max_fps;
- mutex_unlock(&sc500ai->mutex);
+ if (sc500ai->streaming)
+ fi->interval = sc500ai->cur_fps;
+ else
+ fi->interval = mode->max_fps;
return 0;
}
-static int sc500ai_g_mbus_config(struct v4l2_subdev *sd,
+static int sc500ai_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
struct v4l2_mbus_config *config)
{
struct sc500ai *sc500ai = to_sc500ai(sd);
@@ -692,7 +689,7 @@
if (mode->hdr_mode == HDR_X3)
val |= V4L2_MBUS_CSI2_CHANNEL_2;
- config->type = V4L2_MBUS_CSI2;
+ config->type = V4L2_MBUS_CSI2_DPHY;
config->flags = val;
return 0;
@@ -911,11 +908,23 @@
return ret;
}
+static int sc500ai_get_channel_info(struct sc500ai *sc500ai, struct rkmodule_channel_info *ch_info)
+{
+ if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
+ return -EINVAL;
+ ch_info->vc = sc500ai->cur_mode->vc[ch_info->index];
+ ch_info->width = sc500ai->cur_mode->width;
+ ch_info->height = sc500ai->cur_mode->height;
+ ch_info->bus_fmt = sc500ai->cur_mode->bus_fmt;
+ return 0;
+}
+
static long sc500ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
struct sc500ai *sc500ai = to_sc500ai(sd);
struct rkmodule_hdr_cfg *hdr;
const struct sc500ai_mode *mode;
+ struct rkmodule_channel_info *ch_info;
long ret = 0;
u32 i, h, w;
@@ -959,7 +968,8 @@
__v4l2_ctrl_s_ctrl(sc500ai->link_freq, mode->mipi_freq_idx);
pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC500AI_LANES;
__v4l2_ctrl_s_ctrl_int64(sc500ai->pixel_rate, pixel_rate);
-
+ sc500ai->cur_fps = mode->max_fps;
+ sc500ai->cur_vts = mode->vts_def;
dev_info(&sc500ai->client->dev, "sensor mode: %d\n", sc500ai->cur_mode->hdr_mode);
}
break;
@@ -976,6 +986,10 @@
ret = sc500ai_write_reg(sc500ai->client, SC500AI_REG_CTRL_MODE,
SC500AI_REG_VALUE_08BIT, SC500AI_MODE_SW_STANDBY);
break;
+ case RKMODULE_GET_CHANNEL_INFO:
+ ch_info = (struct rkmodule_channel_info *)arg;
+ ret = sc500ai_get_channel_info(sc500ai, ch_info);
+ break;
default:
ret = -ENOIOCTLCMD;
break;
@@ -990,9 +1004,9 @@
{
void __user *up = compat_ptr(arg);
struct rkmodule_inf *inf;
- struct rkmodule_awb_cfg *cfg;
struct rkmodule_hdr_cfg *hdr;
struct preisp_hdrae_exp_s *hdrae;
+ struct rkmodule_channel_info *ch_info;
long ret = 0;
u32 stream = 0;
@@ -1005,21 +1019,12 @@
}
ret = sc500ai_ioctl(sd, cmd, inf);
- if (!ret)
+ if (!ret) {
ret = copy_to_user(up, inf, sizeof(*inf));
- kfree(inf);
- break;
- case RKMODULE_AWB_CFG:
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
- if (!cfg) {
- ret = -ENOMEM;
- return ret;
+ if (ret)
+ ret = -EFAULT;
}
-
- ret = copy_from_user(cfg, up, sizeof(*cfg));
- if (!ret)
- ret = sc500ai_ioctl(sd, cmd, cfg);
- kfree(cfg);
+ kfree(inf);
break;
case RKMODULE_GET_HDR_CFG:
hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
@@ -1029,8 +1034,11 @@
}
ret = sc500ai_ioctl(sd, cmd, hdr);
- if (!ret)
+ if (!ret) {
ret = copy_to_user(up, hdr, sizeof(*hdr));
+ if (ret)
+ ret = -EFAULT;
+ }
kfree(hdr);
break;
case RKMODULE_SET_HDR_CFG:
@@ -1040,9 +1048,10 @@
return ret;
}
- ret = copy_from_user(hdr, up, sizeof(*hdr));
- if (!ret)
- ret = sc500ai_ioctl(sd, cmd, hdr);
+ if (copy_from_user(hdr, up, sizeof(*hdr)))
+ return -EFAULT;
+
+ ret = sc500ai_ioctl(sd, cmd, hdr);
kfree(hdr);
break;
case PREISP_CMD_SET_HDRAE_EXP:
@@ -1052,15 +1061,32 @@
return ret;
}
- ret = copy_from_user(hdrae, up, sizeof(*hdrae));
- if (!ret)
- ret = sc500ai_ioctl(sd, cmd, hdrae);
+ if (copy_from_user(hdrae, up, sizeof(*hdrae)))
+ return -EFAULT;
+
+ ret = sc500ai_ioctl(sd, cmd, hdrae);
kfree(hdrae);
break;
case RKMODULE_SET_QUICK_STREAM:
- ret = copy_from_user(&stream, up, sizeof(u32));
- if (!ret)
- ret = sc500ai_ioctl(sd, cmd, &stream);
+ if (copy_from_user(&stream, up, sizeof(u32)))
+ return -EFAULT;
+
+ ret = sc500ai_ioctl(sd, cmd, &stream);
+ break;
+ case RKMODULE_GET_CHANNEL_INFO:
+ ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
+ if (!ch_info) {
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ ret = sc500ai_ioctl(sd, cmd, ch_info);
+ if (!ret) {
+ ret = copy_to_user(up, ch_info, sizeof(*ch_info));
+ if (ret)
+ ret = -EFAULT;
+ }
+ kfree(ch_info);
break;
default:
ret = -ENOIOCTLCMD;
@@ -1348,7 +1374,6 @@
static const struct v4l2_subdev_video_ops sc500ai_video_ops = {
.s_stream = sc500ai_s_stream,
.g_frame_interval = sc500ai_g_frame_interval,
- .g_mbus_config = sc500ai_g_mbus_config,
};
static const struct v4l2_subdev_pad_ops sc500ai_pad_ops = {
@@ -1358,6 +1383,7 @@
.get_fmt = sc500ai_get_fmt,
.set_fmt = sc500ai_set_fmt,
.get_selection = sc500ai_get_selection,
+ .get_mbus_config = sc500ai_g_mbus_config,
};
static const struct v4l2_subdev_ops sc500ai_subdev_ops = {
@@ -1365,6 +1391,14 @@
.video = &sc500ai_video_ops,
.pad = &sc500ai_pad_ops,
};
+
+static void sc500ai_modify_fps_info(struct sc500ai *sc500ai)
+{
+ const struct sc500ai_mode *mode = sc500ai->cur_mode;
+
+ sc500ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+ sc500ai->cur_vts;
+}
static int sc500ai_set_ctrl(struct v4l2_ctrl *ctrl)
{
@@ -1399,7 +1433,7 @@
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
if (sc500ai->cur_mode->hdr_mode != NO_HDR)
- return ret;
+ goto ctrl_end;
val = ctrl->val << 1;
ret = sc500ai_write_reg(sc500ai->client,
SC500AI_REG_EXPOSURE_H,
@@ -1418,7 +1452,7 @@
break;
case V4L2_CID_ANALOGUE_GAIN:
if (sc500ai->cur_mode->hdr_mode != NO_HDR)
- return ret;
+ goto ctrl_end;
sc500ai_get_gain_reg(ctrl->val, &again, &again_fine, &dgain, &dgain_fine);
ret = sc500ai_write_reg(sc500ai->client,
@@ -1453,7 +1487,9 @@
SC500AI_REG_VTS_L,
SC500AI_REG_VALUE_08BIT,
vts & 0xff);
- sc500ai->cur_vts = vts;
+ if (!ret)
+ sc500ai->cur_vts = vts;
+ sc500ai_modify_fps_info(sc500ai);
break;
case V4L2_CID_HFLIP:
ret = sc500ai_read_reg(sc500ai->client, SC500AI_FLIP_MIRROR_REG,
@@ -1520,6 +1556,7 @@
break;
}
+ctrl_end:
pm_runtime_put(&client->dev);
return ret;
@@ -1565,6 +1602,7 @@
vblank_def = mode->vts_def - mode->height;
sc500ai->cur_vts = mode->vts_def;
+ sc500ai->cur_fps = mode->max_fps;
sc500ai->vblank = v4l2_ctrl_new_std(handler, &sc500ai_ctrl_ops,
V4L2_CID_VBLANK, vblank_def,
SC500AI_VTS_MAX - mode->height,
--
Gitblit v1.6.2