From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp

---
 kernel/drivers/media/i2c/imx415.c |  125 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 102 insertions(+), 23 deletions(-)

diff --git a/kernel/drivers/media/i2c/imx415.c b/kernel/drivers/media/i2c/imx415.c
index 5cb5a88..cda7a78 100644
--- a/kernel/drivers/media/i2c/imx415.c
+++ b/kernel/drivers/media/i2c/imx415.c
@@ -23,6 +23,12 @@
  * V0.0X01.0X06
  * 1. support DOL3 10bit 20fps 1485Mbps
  * 2. fixed linkfreq error
+ * V0.0X01.0X07
+ * 1. fix set_fmt & ioctl get mode unmatched issue.
+ * 2. need to set default vblank when change format.
+ * 3. enum all supported mode mbus_code, not just cur_mode.
+ * V0.0X01.0X08
+ * 1. add dcphy param for hdrx2 mode.
  */
 
 #define DEBUG
@@ -46,7 +52,7 @@
 #include <linux/rk-preisp.h>
 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
 
-#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x06)
+#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x08)
 
 #ifndef V4L2_CID_DIGITAL_GAIN
 #define V4L2_CID_DIGITAL_GAIN		V4L2_CID_GAIN
@@ -169,14 +175,6 @@
 
 #define IMX415_NUM_SUPPLIES ARRAY_SIZE(imx415_supply_names)
 
-enum imx415_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;
@@ -234,6 +232,17 @@
 	u32			cur_vts;
 	bool			has_init_exp;
 	struct preisp_hdrae_exp_s init_hdrae_exp;
+};
+
+static struct rkmodule_csi_dphy_param dcphy_param = {
+	.vendor = PHY_VENDOR_SAMSUNG,
+	.lp_vol_ref = 6,
+	.lp_hys_sw = {3, 0, 0, 0},
+	.lp_escclk_pol_sel = {1, 1, 1, 1},
+	.skew_data_cal_clk = {0, 3, 3, 3},
+	.clk_hs_term_sel = 2,
+	.data_hs_term_sel = {2, 2, 2, 2},
+	.reserved = {0},
 };
 
 #define to_imx415(sd) container_of(sd, struct imx415, subdev)
@@ -769,6 +778,7 @@
 		.hdr_mode = NO_HDR,
 		.mipi_freq_idx = 1,
 		.bpp = 10,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
@@ -862,6 +872,7 @@
 		.hdr_mode = NO_HDR,
 		.mipi_freq_idx = 1,
 		.bpp = 12,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
@@ -929,6 +940,7 @@
 		.hdr_mode = NO_HDR,
 		.mipi_freq_idx = 0,
 		.bpp = 12,
+		.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
 	},
 	{
 		.bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
@@ -1059,12 +1071,14 @@
 
 	for (i = 0; i < imx415->cfg_num; i++) {
 		dist = imx415_get_reso_dist(&supported_modes[i], framefmt);
-		if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
+		if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
 			supported_modes[i].bus_fmt == framefmt->code) {
 			cur_best_fit_dist = dist;
 			cur_best_fit = i;
 		}
 	}
+	dev_info(&imx415->client->dev, "%s: cur_best_fit(%d)",
+		 __func__, cur_best_fit);
 
 	return &supported_modes[cur_best_fit];
 }
@@ -1118,11 +1132,14 @@
 		__v4l2_ctrl_modify_range(imx415->vblank, vblank_min,
 					 IMX415_VTS_MAX - mode->height,
 					 1, vblank_def);
+		__v4l2_ctrl_s_ctrl(imx415->vblank, vblank_def);
 		__v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
 		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
 		__v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
 					 pixel_rate);
 	}
+	dev_info(&imx415->client->dev, "%s: mode->mipi_freq_idx(%d)",
+		 __func__, mode->mipi_freq_idx);
 
 	mutex_unlock(&imx415->mutex);
 
@@ -1165,9 +1182,10 @@
 {
 	struct imx415 *imx415 = to_imx415(sd);
 
-	if (code->index != 0)
+	if (code->index >= imx415->cfg_num)
 		return -EINVAL;
-	code->code = imx415->cur_mode->bus_fmt;
+
+	code->code = supported_modes[code->index].bus_fmt;
 
 	return 0;
 }
@@ -1198,14 +1216,12 @@
 	struct imx415 *imx415 = to_imx415(sd);
 	const struct imx415_mode *mode = imx415->cur_mode;
 
-	mutex_lock(&imx415->mutex);
 	fi->interval = mode->max_fps;
-	mutex_unlock(&imx415->mutex);
 
 	return 0;
 }
 
-static int imx415_g_mbus_config(struct v4l2_subdev *sd,
+static int imx415_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
 				struct v4l2_mbus_config *config)
 {
 	struct imx415 *imx415 = to_imx415(sd);
@@ -1219,7 +1235,7 @@
 		val |= V4L2_MBUS_CSI2_CHANNEL_1;
 	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;
@@ -1650,14 +1666,27 @@
 	return ret;
 }
 
+static int imx415_get_channel_info(struct imx415 *imx415, struct rkmodule_channel_info *ch_info)
+{
+	if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
+		return -EINVAL;
+	ch_info->vc = imx415->cur_mode->vc[ch_info->index];
+	ch_info->width = imx415->cur_mode->width;
+	ch_info->height = imx415->cur_mode->height;
+	ch_info->bus_fmt = imx415->cur_mode->bus_fmt;
+	return 0;
+}
+
 static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
 	struct imx415 *imx415 = to_imx415(sd);
 	struct rkmodule_hdr_cfg *hdr;
+	struct rkmodule_channel_info *ch_info;
 	u32 i, h, w, stream;
 	long ret = 0;
 	const struct imx415_mode *mode;
 	u64 pixel_rate = 0;
+	struct rkmodule_csi_dphy_param *dphy_param;
 
 	switch (cmd) {
 	case PREISP_CMD_SET_HDRAE_EXP:
@@ -1706,6 +1735,7 @@
 			}
 			w = mode->hts_def - imx415->cur_mode->width;
 			h = mode->vts_def - mode->height;
+			mutex_lock(&imx415->mutex);
 			__v4l2_ctrl_modify_range(imx415->hblank, w, w, 1, w);
 			__v4l2_ctrl_modify_range(imx415->vblank, h,
 				IMX415_VTS_MAX - mode->height,
@@ -1714,6 +1744,7 @@
 			pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
 			__v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
 						 pixel_rate);
+			mutex_unlock(&imx415->mutex);
 		}
 		break;
 	case RKMODULE_SET_QUICK_STREAM:
@@ -1733,6 +1764,20 @@
 		else
 			*((u32 *)arg) = BRL_BINNING;
 		break;
+	case RKMODULE_GET_CHANNEL_INFO:
+		ch_info = (struct rkmodule_channel_info *)arg;
+		ret = imx415_get_channel_info(imx415, ch_info);
+		break;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		if (imx415->cur_mode->hdr_mode == HDR_X2) {
+			dphy_param = (struct rkmodule_csi_dphy_param *)arg;
+			if (dphy_param->vendor == dcphy_param.vendor)
+				*dphy_param = dcphy_param;
+			dev_info(&imx415->client->dev,
+				 "get sensor dphy param\n");
+		} else
+			ret = -EINVAL;
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 		break;
@@ -1750,9 +1795,11 @@
 	struct rkmodule_awb_cfg *cfg;
 	struct rkmodule_hdr_cfg *hdr;
 	struct preisp_hdrae_exp_s *hdrae;
+	struct rkmodule_channel_info *ch_info;
 	long ret;
 	u32  stream;
 	u32 brl = 0;
+	struct rkmodule_csi_dphy_param *dphy_param;
 
 	switch (cmd) {
 	case RKMODULE_GET_MODULE_INFO:
@@ -1841,6 +1888,37 @@
 				return -EFAULT;
 		}
 		break;
+	case RKMODULE_GET_CHANNEL_INFO:
+		ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
+		if (!ch_info) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = imx415_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;
+	case RKMODULE_GET_CSI_DPHY_PARAM:
+		dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
+		if (!dphy_param) {
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		ret = imx415_ioctl(sd, cmd, dphy_param);
+		if (!ret) {
+			ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(dphy_param);
+		break;
+
 	default:
 		ret = -ENOIOCTLCMD;
 		break;
@@ -1896,7 +1974,7 @@
 	struct i2c_client *client = imx415->client;
 	int ret = 0;
 
-	dev_dbg(&imx415->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n",
+	dev_info(&imx415->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n",
 	       on, imx415->cur_mode->width, imx415->cur_mode->height,
 	       imx415->cur_mode->hdr_mode, imx415->cur_mode->bpp);
 
@@ -2051,7 +2129,7 @@
 	regulator_bulk_disable(IMX415_NUM_SUPPLIES, imx415->supplies);
 }
 
-static int imx415_runtime_resume(struct device *dev)
+static int __maybe_unused imx415_runtime_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -2060,7 +2138,7 @@
 	return __imx415_power_on(imx415);
 }
 
-static int imx415_runtime_suspend(struct device *dev)
+static int __maybe_unused imx415_runtime_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -2175,7 +2253,6 @@
 static const struct v4l2_subdev_video_ops imx415_video_ops = {
 	.s_stream = imx415_s_stream,
 	.g_frame_interval = imx415_g_frame_interval,
-	.g_mbus_config = imx415_g_mbus_config,
 };
 
 static const struct v4l2_subdev_pad_ops imx415_pad_ops = {
@@ -2185,6 +2262,7 @@
 	.get_fmt = imx415_get_fmt,
 	.set_fmt = imx415_set_fmt,
 	.get_selection = imx415_get_selection,
+	.get_mbus_config = imx415_g_mbus_config,
 };
 
 static const struct v4l2_subdev_ops imx415_subdev_ops = {
@@ -2223,7 +2301,7 @@
 	switch (ctrl->id) {
 	case V4L2_CID_EXPOSURE:
 		if (imx415->cur_mode->hdr_mode != NO_HDR)
-			return ret;
+			goto ctrl_end;
 		shr0 = imx415->cur_vts - ctrl->val;
 		ret = imx415_write_reg(imx415->client, IMX415_LF_EXPO_REG_L,
 				       IMX415_REG_VALUE_08BIT,
@@ -2239,7 +2317,7 @@
 		break;
 	case V4L2_CID_ANALOGUE_GAIN:
 		if (imx415->cur_mode->hdr_mode != NO_HDR)
-			return ret;
+			goto ctrl_end;
 		ret = imx415_write_reg(imx415->client, IMX415_LF_GAIN_REG_H,
 				       IMX415_REG_VALUE_08BIT,
 				       IMX415_FETCH_GAIN_H(ctrl->val));
@@ -2308,6 +2386,7 @@
 		break;
 	}
 
+ctrl_end:
 	pm_runtime_put(&client->dev);
 
 	return ret;
@@ -2337,7 +2416,7 @@
 				V4L2_CID_LINK_FREQ,
 				ARRAY_SIZE(link_freq_items) - 1, 0,
 				link_freq_items);
-	__v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
+	v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
 
 	/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
 	pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;

--
Gitblit v1.6.2