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/sc210iot.c |   54 +++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/kernel/drivers/media/i2c/sc210iot.c b/kernel/drivers/media/i2c/sc210iot.c
index 46418a3..40d1e04 100644
--- a/kernel/drivers/media/i2c/sc210iot.c
+++ b/kernel/drivers/media/i2c/sc210iot.c
@@ -89,14 +89,6 @@
 #define to_sc210iot(sd) container_of(sd, struct sc210iot, subdev)
 
 enum {
-	PAD0,
-	PAD1,
-	PAD2,
-	PAD3,
-	PAD_MAX,
-};
-
-enum {
 	LINK_FREQ_INDEX,
 };
 
@@ -148,6 +140,8 @@
 	struct v4l2_ctrl    *link_freq;
 	struct v4l2_ctrl    *pixel_rate;
 	struct mutex        lock;
+	struct v4l2_fract cur_fps;
+	u32		cur_vts;
 	bool		streaming;
 	bool		power_on;
 	bool		is_thunderboot;
@@ -371,6 +365,14 @@
 	return ret;
 }
 
+static void sc210iot_modify_fps_info(struct sc210iot *sc210iot)
+{
+	const struct sc210iot_mode *mode = sc210iot->cur_mode;
+
+	sc210iot->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
+					sc210iot->cur_vts;
+}
+
 static int sc210iot_set_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct sc210iot *sc210iot = container_of(ctrl->handler,
@@ -402,8 +404,11 @@
 		dev_dbg(sc210iot->dev, "set vblank 0x%x\n", ctrl->val);
 		ret = sc210iot_write_reg(sc210iot, SC210IOT_REG_VTS_H,
 					(ctrl->val + sc210iot->cur_mode->height) >> 8);
-		ret = sc210iot_write_reg(sc210iot, SC210IOT_REG_VTS_L,
+		ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_VTS_L,
 					(ctrl->val + sc210iot->cur_mode->height) & 0xff);
+		if (!ret)
+			sc210iot->cur_vts = ctrl->val + sc210iot->cur_mode->height;
+		sc210iot_modify_fps_info(sc210iot);
 		break;
 	case V4L2_CID_HFLIP:
 		regmap_update_bits(sc210iot->regmap, SC210IOT_REG_MIRROR_FLIP,
@@ -487,6 +492,8 @@
 	}
 	sc210iot->subdev.ctrl_handler = handler;
 	sc210iot->has_init_exp = false;
+	sc210iot->cur_fps = mode->max_fps;
+	sc210iot->cur_vts = mode->vts_def;
 	return 0;
 err_free_handler:
 	v4l2_ctrl_handler_free(handler);
@@ -687,8 +694,11 @@
 			return ret;
 		}
 		ret = sc210iot_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_GET_HDR_CFG:
@@ -698,16 +708,19 @@
 			return ret;
 		}
 		ret = sc210iot_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:
 		break;
 	case RKMODULE_SET_QUICK_STREAM:
 		ret = copy_from_user(&stream, up, sizeof(u32));
 		if (!ret)
 			ret = sc210iot_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
 		break;
 	default:
 		ret = -ENOIOCTLCMD;
@@ -758,20 +771,21 @@
 	struct sc210iot *sc210iot = to_sc210iot(sd);
 	const struct sc210iot_mode *mode = sc210iot->cur_mode;
 
-	mutex_lock(&sc210iot->lock);
-	fi->interval = mode->max_fps;
-	mutex_unlock(&sc210iot->lock);
+	if (sc210iot->streaming)
+		fi->interval = sc210iot->cur_fps;
+	else
+		fi->interval = mode->max_fps;
 	return 0;
 }
 
-static int sc210iot_g_mbus_config(struct v4l2_subdev *sd,
+static int sc210iot_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
 				struct v4l2_mbus_config *config)
 {
 	struct sc210iot *sc210iot = to_sc210iot(sd);
 
 	u32 val = 1 << (SC210IOT_LANES - 1) | V4L2_MBUS_CSI2_CHANNEL_0 |
 		  V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-	config->type = V4L2_MBUS_CSI2;
+	config->type = V4L2_MBUS_CSI2_DPHY;
 	config->flags = (sc210iot->cur_mode->hdr_mode == NO_HDR) ?
 			val : (val | V4L2_MBUS_CSI2_CHANNEL_1);
 	return 0;
@@ -856,6 +870,8 @@
 		__v4l2_ctrl_modify_range(sc210iot->vblank, vblank_def,
 					 SC210IOT_VTS_MAX - mode->height,
 					 1, vblank_def);
+		sc210iot->cur_fps = mode->max_fps;
+		sc210iot->cur_vts = mode->vts_def;
 	}
 	mutex_unlock(&sc210iot->lock);
 	return 0;
@@ -951,7 +967,6 @@
 static const struct v4l2_subdev_video_ops sc210iot_video_ops = {
 	.s_stream = sc210iot_s_stream,
 	.g_frame_interval = sc210iot_g_frame_interval,
-	.g_mbus_config = sc210iot_g_mbus_config,
 };
 
 static const struct v4l2_subdev_pad_ops sc210iot_pad_ops = {
@@ -960,6 +975,7 @@
 	.enum_frame_interval = sc210iot_enum_frame_interval,
 	.get_fmt = sc210iot_get_fmt,
 	.set_fmt = sc210iot_set_fmt,
+	.get_mbus_config = sc210iot_g_mbus_config,
 };
 
 static const struct v4l2_subdev_ops sc210iot_subdev_ops = {

--
Gitblit v1.6.2