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/gc4c33.c |   82 +++++++++++++++++++++++++++++-----------
 1 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/kernel/drivers/media/i2c/gc4c33.c b/kernel/drivers/media/i2c/gc4c33.c
index bfc893b..02ba9d7 100644
--- a/kernel/drivers/media/i2c/gc4c33.c
+++ b/kernel/drivers/media/i2c/gc4c33.c
@@ -107,14 +107,6 @@
 
 #define GC4C33_NUM_SUPPLIES ARRAY_SIZE(gc4c33_supply_names)
 
-enum gc4c33_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;
@@ -1322,11 +1314,6 @@
 		fmt->format.height = mode->height;
 		fmt->format.code = mode->bus_fmt;
 		fmt->format.field = V4L2_FIELD_NONE;
-		/* format info: width/height/data type/virctual channel */
-		if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
-			fmt->reserved[0] = mode->vc[fmt->pad];
-		else
-			fmt->reserved[0] = mode->vc[PAD0];
 	}
 	mutex_unlock(&gc4c33->mutex);
 
@@ -1523,14 +1510,12 @@
 	struct gc4c33 *gc4c33 = to_gc4c33(sd);
 	const struct gc4c33_mode *mode = gc4c33->cur_mode;
 
-	mutex_lock(&gc4c33->mutex);
 	fi->interval = mode->max_fps;
-	mutex_unlock(&gc4c33->mutex);
 
 	return 0;
 }
 
-static int gc4c33_g_mbus_config(struct v4l2_subdev *sd,
+static int gc4c33_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
 				struct v4l2_mbus_config *config)
 {
 	struct gc4c33 *gc4c33 = to_gc4c33(sd);
@@ -1544,7 +1529,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;
@@ -1560,6 +1545,17 @@
 	strlcpy(inf->base.lens, gc4c33->len_name, sizeof(inf->base.lens));
 }
 
+static int gc4c33_get_channel_info(struct gc4c33 *gc4c33, struct rkmodule_channel_info *ch_info)
+{
+	if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
+		return -EINVAL;
+	ch_info->vc = gc4c33->cur_mode->vc[ch_info->index];
+	ch_info->width = gc4c33->cur_mode->width;
+	ch_info->height = gc4c33->cur_mode->height;
+	ch_info->bus_fmt = gc4c33->cur_mode->bus_fmt;
+	return 0;
+}
+
 static long gc4c33_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
 	struct gc4c33 *gc4c33 = to_gc4c33(sd);
@@ -1568,6 +1564,7 @@
 	u32 i, h, w;
 	long ret = 0;
 	u32 stream = 0;
+	struct rkmodule_channel_info *ch_info;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -1629,6 +1626,10 @@
 			ret = gc4c33_write_reg(gc4c33->client, GC4C33_REG_CTRL_MODE,
 				GC4C33_REG_VALUE_08BIT, GC4C33_MODE_SW_STANDBY);
 		break;
+	case RKMODULE_GET_CHANNEL_INFO:
+		ch_info = (struct rkmodule_channel_info *)arg;
+		ret = gc4c33_get_channel_info(gc4c33, ch_info);
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 		break;
@@ -1650,6 +1651,7 @@
 	struct rkmodule_nr_switch_threshold *nr_switch;
 	long ret;
 	u32 stream = 0;
+	struct rkmodule_channel_info *ch_info;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -1660,8 +1662,11 @@
 		}
 
 		ret = gc4c33_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:
@@ -1674,6 +1679,8 @@
 		ret = copy_from_user(cfg, up, sizeof(*cfg));
 		if (!ret)
 			ret = gc4c33_ioctl(sd, cmd, cfg);
+		else
+			ret = -EFAULT;
 		kfree(cfg);
 		break;
 	case RKMODULE_GET_HDR_CFG:
@@ -1684,8 +1691,11 @@
 		}
 
 		ret = gc4c33_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:
@@ -1698,6 +1708,8 @@
 		ret = copy_from_user(hdr, up, sizeof(*hdr));
 		if (!ret)
 			ret = gc4c33_ioctl(sd, cmd, hdr);
+		else
+			ret = -EFAULT;
 		kfree(hdr);
 		break;
 	case RKMODULE_SET_DPCC_CFG:
@@ -1710,6 +1722,8 @@
 		ret = copy_from_user(dpcc, up, sizeof(*dpcc));
 		if (!ret)
 			ret = gc4c33_ioctl(sd, cmd, dpcc);
+		else
+			ret = -EFAULT;
 		kfree(dpcc);
 		break;
 	case PREISP_CMD_SET_HDRAE_EXP:
@@ -1722,6 +1736,8 @@
 		ret = copy_from_user(hdrae, up, sizeof(*hdrae));
 		if (!ret)
 			ret = gc4c33_ioctl(sd, cmd, hdrae);
+		else
+			ret = -EFAULT;
 		kfree(hdrae);
 		break;
 	case RKMODULE_GET_NR_SWITCH_THRESHOLD:
@@ -1732,14 +1748,34 @@
 		}
 
 		ret = gc4c33_ioctl(sd, cmd, nr_switch);
-		if (!ret)
+		if (!ret) {
 			ret = copy_to_user(up, nr_switch, sizeof(*nr_switch));
+			if (ret)
+				ret = -EFAULT;
+		}
 		kfree(nr_switch);
 		break;
 	case RKMODULE_SET_QUICK_STREAM:
 		ret = copy_from_user(&stream, up, sizeof(u32));
 		if (!ret)
 			ret = gc4c33_ioctl(sd, cmd, &stream);
+		else
+			ret = -EFAULT;
+		break;
+	case RKMODULE_GET_CHANNEL_INFO:
+		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
+		if (!ch_info) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = gc4c33_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;
@@ -2046,7 +2082,7 @@
 		gpiod_set_value_cansleep(gc4c33->pwren_gpio, 0);
 }
 
-static int gc4c33_runtime_resume(struct device *dev)
+static int __maybe_unused gc4c33_runtime_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -2055,7 +2091,7 @@
 	return __gc4c33_power_on(gc4c33);
 }
 
-static int gc4c33_runtime_suspend(struct device *dev)
+static int __maybe_unused gc4c33_runtime_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -2127,7 +2163,6 @@
 static const struct v4l2_subdev_video_ops gc4c33_video_ops = {
 	.s_stream = gc4c33_s_stream,
 	.g_frame_interval = gc4c33_g_frame_interval,
-	.g_mbus_config = gc4c33_g_mbus_config,
 };
 
 static const struct v4l2_subdev_pad_ops gc4c33_pad_ops = {
@@ -2136,6 +2171,7 @@
 	.enum_frame_interval = gc4c33_enum_frame_interval,
 	.get_fmt = gc4c33_get_fmt,
 	.set_fmt = gc4c33_set_fmt,
+	.get_mbus_config = gc4c33_g_mbus_config,
 };
 
 static const struct v4l2_subdev_ops gc4c33_subdev_ops = {

--
Gitblit v1.6.2