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