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/sc2232.c |   62 ++++++++++++++++++++++---------
 1 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/kernel/drivers/media/i2c/sc2232.c b/kernel/drivers/media/i2c/sc2232.c
index 3e51882..9186997 100644
--- a/kernel/drivers/media/i2c/sc2232.c
+++ b/kernel/drivers/media/i2c/sc2232.c
@@ -93,14 +93,6 @@
 
 #define SC2232_NUM_SUPPLIES ARRAY_SIZE(sc2232_supply_names)
 
-enum sc2232_max_pad {
-	PAD0,
-	PAD1,
-	PAD2,
-	PAD3,
-	PAD_MAX,
-};
-
 struct regval {
 	u16 addr;
 	u8 val;
@@ -141,6 +133,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 sc2232_mode *cur_mode;
@@ -518,6 +511,8 @@
 		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
 			mode->bpp * 2 * SC2232_LANES;
 		__v4l2_ctrl_s_ctrl_int64(sc2232->pixel_rate, pixel_rate);
+		sc2232->cur_fps = mode->max_fps;
+		sc2232->cur_vts = mode->vts_def;
 	}
 
 	mutex_unlock(&sc2232->mutex);
@@ -594,14 +589,15 @@
 	struct sc2232 *sc2232 = to_sc2232(sd);
 	const struct sc2232_mode *mode = sc2232->cur_mode;
 
-	mutex_lock(&sc2232->mutex);
-	fi->interval = mode->max_fps;
-	mutex_unlock(&sc2232->mutex);
+	if (sc2232->streaming)
+		fi->interval = sc2232->cur_fps;
+	else
+		fi->interval = mode->max_fps;
 
 	return 0;
 }
 
-static int sc2232_g_mbus_config(struct v4l2_subdev *sd,
+static int sc2232_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
 				struct v4l2_mbus_config *config)
 {
 	struct sc2232 *sc2232 = to_sc2232(sd);
@@ -618,7 +614,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;
@@ -803,8 +799,11 @@
 		}
 
 		ret = sc2232_ioctl(sd, cmd, inf);
-		if (!ret)
+		if (!ret) {
 			ret = copy_to_user(up, inf, sizeof(*inf));
+			if (ret)
+				ret = -EFAULT;
+		}
 		kfree(inf);
 		break;
 	case RKMODULE_AWB_CFG:
@@ -817,6 +816,8 @@
 		ret = copy_from_user(cfg, up, sizeof(*cfg));
 		if (!ret)
 			ret = sc2232_ioctl(sd, cmd, cfg);
+		else
+			ret = -EFAULT;
 		kfree(cfg);
 		break;
 	case RKMODULE_GET_HDR_CFG:
@@ -827,8 +828,11 @@
 		}
 
 		ret = sc2232_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:
@@ -841,6 +845,8 @@
 		ret = copy_from_user(hdr, up, sizeof(*hdr));
 		if (!ret)
 			ret = sc2232_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
 		kfree(hdr);
 		break;
 	case PREISP_CMD_SET_HDRAE_EXP:
@@ -853,17 +859,23 @@
 		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
 		if (!ret)
 			ret = sc2232_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
 		kfree(hdrae);
 		break;
 	case RKMODULE_SET_CONVERSION_GAIN:
 		ret = copy_from_user(&cg, up, sizeof(cg));
 		if (!ret)
 			ret = sc2232_ioctl(sd, cmd, &cg);
+		else
+			ret = -EFAULT;
 		break;
 	case RKMODULE_SET_QUICK_STREAM:
 		ret = copy_from_user(&stream, up, sizeof(u32));
 		if (!ret)
 			ret = sc2232_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -1128,7 +1140,6 @@
 static const struct v4l2_subdev_video_ops sc2232_video_ops = {
 	.s_stream = sc2232_s_stream,
 	.g_frame_interval = sc2232_g_frame_interval,
-	.g_mbus_config = sc2232_g_mbus_config,
 };
 
 static const struct v4l2_subdev_pad_ops sc2232_pad_ops = {
@@ -1137,6 +1148,7 @@
 	.enum_frame_interval = sc2232_enum_frame_interval,
 	.get_fmt = sc2232_get_fmt,
 	.set_fmt = sc2232_set_fmt,
+	.get_mbus_config = sc2232_g_mbus_config,
 };
 
 static const struct v4l2_subdev_ops sc2232_subdev_ops = {
@@ -1144,6 +1156,14 @@
 	.video	= &sc2232_video_ops,  /* */
 	.pad	= &sc2232_pad_ops,    /* */
 };
+
+static void sc2232_modify_fps_info(struct sc2232 *sc2232)
+{
+	const struct sc2232_mode *mode = sc2232->cur_mode;
+
+	sc2232->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+				      sc2232->cur_vts;
+}
 
 static int sc2232_set_ctrl(struct v4l2_ctrl *ctrl)
 {
@@ -1172,7 +1192,7 @@
 	switch (ctrl->id) {
 	case V4L2_CID_EXPOSURE:
 		if (sc2232->cur_mode->hdr_mode != NO_HDR)
-			return ret;
+			goto ctrl_end;
 		val = ctrl->val << 1;
 		ret = sc2232_write_reg(sc2232->client,
 					SC2232_REG_EXP_LONG_L,
@@ -1190,13 +1210,16 @@
 		break;
 	case V4L2_CID_ANALOGUE_GAIN:
 		if (sc2232->cur_mode->hdr_mode != NO_HDR)
-			return ret;
+			goto ctrl_end;
 		ret = sc2232_set_gain(sc2232, ctrl->val);
 		break;
 	case V4L2_CID_VBLANK:
 		ret = sc2232_write_reg(sc2232->client, SC2232_REG_VTS,
 					SC2232_REG_VALUE_16BIT,
 					ctrl->val + sc2232->cur_mode->height);
+		if (!ret)
+			sc2232->cur_vts = ctrl->val + sc2232->cur_mode->height;
+		sc2232_modify_fps_info(sc2232);
 		dev_dbg(&client->dev, "set vblank 0x%x\n",
 			ctrl->val);
 		break;
@@ -1232,6 +1255,7 @@
 		break;
 	}
 
+ctrl_end:
 	pm_runtime_put(&client->dev);
 	return ret;
 }
@@ -1303,6 +1327,8 @@
 
 	sc2232->subdev.ctrl_handler = handler;
 	sc2232->has_init_exp = false;
+	sc2232->cur_vts = mode->vts_def;
+	sc2232->cur_fps = mode->max_fps;
 
 	return 0;
 

--
Gitblit v1.6.2