From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 19 Dec 2024 01:47:39 +0000 Subject: [PATCH] add wifi6 8852be driver --- kernel/drivers/media/i2c/sc2310.c | 71 ++++++++++++++++++++++++++++------- 1 files changed, 57 insertions(+), 14 deletions(-) diff --git a/kernel/drivers/media/i2c/sc2310.c b/kernel/drivers/media/i2c/sc2310.c index 536d96c..574836d 100644 --- a/kernel/drivers/media/i2c/sc2310.c +++ b/kernel/drivers/media/i2c/sc2310.c @@ -121,14 +121,6 @@ #define SC2310_NUM_SUPPLIES ARRAY_SIZE(sc2310_supply_names) -enum sc2310_max_pad { - PAD0, - PAD1, - PAD2, - PAD3, - PAD_MAX, -}; - struct regval { u16 addr; u8 val; @@ -170,6 +162,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 sc2310_mode *cur_mode; @@ -776,6 +769,8 @@ pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC2310_LANES; __v4l2_ctrl_s_ctrl_int64(sc2310->pixel_rate, pixel_rate); + sc2310->cur_fps = mode->max_fps; + sc2310->cur_vts = mode->vts_def; } mutex_unlock(&sc2310->mutex); @@ -868,14 +863,15 @@ struct sc2310 *sc2310 = to_sc2310(sd); const struct sc2310_mode *mode = sc2310->cur_mode; - mutex_lock(&sc2310->mutex); - fi->interval = mode->max_fps; - mutex_unlock(&sc2310->mutex); + if (sc2310->streaming) + fi->interval = sc2310->cur_fps; + else + fi->interval = mode->max_fps; return 0; } -static int sc2310_g_mbus_config(struct v4l2_subdev *sd, +static int sc2310_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, struct v4l2_mbus_config *config) { struct sc2310 *sc2310 = to_sc2310(sd); @@ -892,7 +888,7 @@ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CHANNEL_1; - config->type = V4L2_MBUS_CSI2; + config->type = V4L2_MBUS_CSI2_DPHY; config->flags = val; return 0; @@ -1078,11 +1074,23 @@ return 0; } +static int sc2310_get_channel_info(struct sc2310 *sc2310, struct rkmodule_channel_info *ch_info) +{ + if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX) + return -EINVAL; + ch_info->vc = sc2310->cur_mode->vc[ch_info->index]; + ch_info->width = sc2310->cur_mode->width; + ch_info->height = sc2310->cur_mode->height; + ch_info->bus_fmt = sc2310->cur_mode->bus_fmt; + return 0; +} + static long sc2310_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct sc2310 *sc2310 = to_sc2310(sd); struct rkmodule_hdr_cfg *hdr_cfg; const struct sc2310_mode *mode; + struct rkmodule_channel_info *ch_info; long ret = 0; u64 pixel_rate = 0; u32 i, h, w, stream; @@ -1127,6 +1135,8 @@ mode->bpp * 2 * SC2310_LANES; __v4l2_ctrl_s_ctrl_int64(sc2310->pixel_rate, pixel_rate); + sc2310->cur_fps = mode->max_fps; + sc2310->cur_vts = mode->vts_def; dev_info(&sc2310->client->dev, "sensor mode: %d\n", mode->hdr_mode); } @@ -1150,6 +1160,10 @@ ret = sc2310_write_reg(sc2310->client, SC2310_REG_CTRL_MODE, SC2310_REG_VALUE_08BIT, SC2310_MODE_SW_STANDBY); break; + case RKMODULE_GET_CHANNEL_INFO: + ch_info = (struct rkmodule_channel_info *)arg; + ret = sc2310_get_channel_info(sc2310, ch_info); + break; default: ret = -ENOIOCTLCMD; break; @@ -1167,6 +1181,7 @@ 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 cg = 0; u32 stream = 0; @@ -1255,6 +1270,21 @@ if (copy_from_user(&stream, up, sizeof(u32))) return -EFAULT; ret = sc2310_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 = sc2310_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; @@ -1523,7 +1553,6 @@ static const struct v4l2_subdev_video_ops sc2310_video_ops = { .s_stream = sc2310_s_stream, .g_frame_interval = sc2310_g_frame_interval, - .g_mbus_config = sc2310_g_mbus_config, }; static const struct v4l2_subdev_pad_ops sc2310_pad_ops = { @@ -1532,6 +1561,7 @@ .enum_frame_interval = sc2310_enum_frame_interval, .get_fmt = sc2310_get_fmt, .set_fmt = sc2310_set_fmt, + .get_mbus_config = sc2310_g_mbus_config, }; static const struct v4l2_subdev_ops sc2310_subdev_ops = { @@ -1539,6 +1569,14 @@ .video = &sc2310_video_ops, /* */ .pad = &sc2310_pad_ops, /* */ }; + +static void sc2310_modify_fps_info(struct sc2310 *sc2310) +{ + const struct sc2310_mode *mode = sc2310->cur_mode; + + sc2310->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / + sc2310->cur_vts; +} static int sc2310_set_ctrl(struct v4l2_ctrl *ctrl) { @@ -1613,6 +1651,9 @@ ret = sc2310_write_reg(sc2310->client, SC2310_REG_VTS, SC2310_REG_VALUE_16BIT, ctrl->val + sc2310->cur_mode->height); + if (!ret) + sc2310->cur_vts = ctrl->val + sc2310->cur_mode->height; + sc2310_modify_fps_info(sc2310); dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val); break; @@ -1727,6 +1768,8 @@ sc2310->subdev.ctrl_handler = handler; sc2310->has_init_exp = false; + sc2310->cur_fps = mode->max_fps; + sc2310->cur_vts = mode->vts_def; return 0; -- Gitblit v1.6.2