From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198
---
kernel/drivers/media/i2c/os04a10.c | 684 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 562 insertions(+), 122 deletions(-)
diff --git a/kernel/drivers/media/i2c/os04a10.c b/kernel/drivers/media/i2c/os04a10.c
index 5cd5dd9..19662b3 100644
--- a/kernel/drivers/media/i2c/os04a10.c
+++ b/kernel/drivers/media/i2c/os04a10.c
@@ -30,6 +30,8 @@
#include <media/v4l2-subdev.h>
#include <linux/pinctrl/consumer.h>
#include <linux/rk-preisp.h>
+#include <media/v4l2-fwnode.h>
+#include <linux/of_graph.h>
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05)
@@ -40,9 +42,11 @@
#define MIPI_FREQ_360M 360000000
#define MIPI_FREQ_648M 648000000
+#define MIPI_FREQ_720M 720000000
#define PIXEL_RATE_WITH_360M (MIPI_FREQ_360M * 2 / 10 * 4)
-#define PIXEL_RATE_WITH_648M (MIPI_FREQ_648M * 2 / 12 * 4)
+#define PIXEL_RATE_WITH_648M (MIPI_FREQ_648M * 2 / 10 * 4)
+#define PIXEL_RATE_WITH_720M (MIPI_FREQ_720M * 2 / 10 * 4)
#define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
@@ -100,16 +104,12 @@
#define OS04A10_REG_VALUE_16BIT 2
#define OS04A10_REG_VALUE_24BIT 3
-#define OS04A10_LANES 4
-
#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
#define OS04A10_NAME "os04a10"
#define USED_SYS_DEBUG
-
-struct preisp_hdrae_exp_s init_hdrae_exp;
static const char * const os04a10_supply_names[] = {
"avdd", /* Analog power */
@@ -122,14 +122,6 @@
#define OS04A10_FLIP_REG 0x3820
#define MIRROR_BIT_MASK BIT(1)
#define FLIP_BIT_MASK BIT(2)
-
-enum os04a10_max_pad {
- PAD0,
- PAD1,
- PAD2,
- PAD3,
- PAD_MAX,
-};
struct regval {
u16 addr;
@@ -144,8 +136,11 @@
u32 hts_def;
u32 vts_def;
u32 exp_def;
+ const struct regval *global_reg_list;
const struct regval *reg_list;
u32 hdr_mode;
+ u32 link_freq_idx;
+ u32 bpp;
u32 vc[PAD_MAX];
};
@@ -176,6 +171,7 @@
struct mutex mutex;
bool streaming;
bool power_on;
+ const struct os04a10_mode *supported_modes;
const struct os04a10_mode *cur_mode;
u32 cfg_num;
u32 module_index;
@@ -192,6 +188,7 @@
bool is_first_streamoff;
u8 flip;
u32 dcg_ratio;
+ struct v4l2_fwnode_endpoint bus_cfg;
};
#define to_os04a10(sd) container_of(sd, struct os04a10, subdev)
@@ -793,6 +790,367 @@
{REG_NULL, 0x00},
};
+static const struct regval os04a10_global_regs_2lane[] = {
+ {0x0109, 0x01},
+ {0x0104, 0x02},
+ {0x0102, 0x00},
+ {0x0306, 0x00},
+ {0x0307, 0x00},
+ {0x0308, 0x04},
+ {0x030a, 0x01},
+ {0x0317, 0x09},
+ {0x0322, 0x01},
+ {0x0323, 0x02},
+ {0x0324, 0x00},
+ {0x0327, 0x05},
+ {0x0329, 0x02},
+ {0x032c, 0x02},
+ {0x032d, 0x02},
+ {0x032e, 0x02},
+ {0x300f, 0x11},
+ {0x3012, 0x21},
+ {0x3026, 0x10},
+ {0x3027, 0x08},
+ {0x302d, 0x24},
+ {0x3104, 0x01},
+ {0x3106, 0x11},
+ {0x3400, 0x00},
+ {0x3408, 0x05},
+ {0x340c, 0x0c},
+ {0x340d, 0xb0},
+ {0x3425, 0x51},
+ {0x3426, 0x10},
+ {0x3427, 0x14},
+ {0x3428, 0x10},
+ {0x3429, 0x10},
+ {0x342a, 0x10},
+ {0x342b, 0x04},
+ {0x3501, 0x02},
+ {0x3504, 0x08},
+ {0x3508, 0x01},
+ {0x3509, 0x00},
+ {0x350a, 0x01},
+ {0x3544, 0x08},
+ {0x3548, 0x01},
+ {0x3549, 0x00},
+ {0x3584, 0x08},
+ {0x3588, 0x01},
+ {0x3589, 0x00},
+ {0x3601, 0x70},
+ {0x3604, 0xe3},
+ {0x3605, 0x7f},
+ {0x3606, 0x80},
+ {0x3608, 0xa8},
+ {0x360a, 0xd0},
+ {0x360b, 0x08},
+ {0x360e, 0xc8},
+ {0x360f, 0x66},
+ {0x3610, 0x89},
+ {0x3611, 0x8a},
+ {0x3612, 0x4e},
+ {0x3613, 0xbd},
+ {0x3614, 0x9b},
+ {0x362a, 0x0e},
+ {0x362b, 0x0e},
+ {0x362c, 0x0e},
+ {0x362d, 0x0e},
+ {0x362e, 0x1a},
+ {0x362f, 0x34},
+ {0x3630, 0x67},
+ {0x3631, 0x7f},
+ {0x3638, 0x00},
+ {0x3643, 0x00},
+ {0x3644, 0x00},
+ {0x3645, 0x00},
+ {0x3646, 0x00},
+ {0x3647, 0x00},
+ {0x3648, 0x00},
+ {0x3649, 0x00},
+ {0x364a, 0x04},
+ {0x364c, 0x0e},
+ {0x364d, 0x0e},
+ {0x364e, 0x0e},
+ {0x364f, 0x0e},
+ {0x3650, 0xff},
+ {0x3651, 0xff},
+ {0x365a, 0x00},
+ {0x365b, 0x00},
+ {0x365c, 0x00},
+ {0x365d, 0x00},
+ {0x3661, 0x07},
+ {0x3662, 0x02},
+ {0x3663, 0x20},
+ {0x3665, 0x12},
+ {0x3668, 0x80},
+ {0x366c, 0x00},
+ {0x366d, 0x00},
+ {0x366e, 0x00},
+ {0x366f, 0x00},
+ {0x3673, 0x2a},
+ {0x3681, 0x80},
+ {0x3700, 0x2d},
+ {0x3701, 0x22},
+ {0x3702, 0x25},
+ {0x3703, 0x20},
+ {0x3705, 0x00},
+ {0x3706, 0x72},
+ {0x3707, 0x0a},
+ {0x3708, 0x36},
+ {0x3709, 0x57},
+ {0x370a, 0x01},
+ {0x370b, 0x14},
+ {0x3714, 0x01},
+ {0x3719, 0x1f},
+ {0x371b, 0x16},
+ {0x371c, 0x00},
+ {0x371d, 0x08},
+ {0x373f, 0x63},
+ {0x3740, 0x63},
+ {0x3741, 0x63},
+ {0x3742, 0x63},
+ {0x3743, 0x01},
+ {0x3756, 0x9d},
+ {0x3757, 0x9d},
+ {0x3762, 0x1c},
+ {0x3673, 0x2a},
+ {0x3681, 0x80},
+ {0x3700, 0x2d},
+ {0x3701, 0x22},
+ {0x3702, 0x25},
+ {0x3703, 0x20},
+ {0x3705, 0x00},
+ {0x3706, 0x72},
+ {0x3707, 0x0a},
+ {0x3708, 0x36},
+ {0x3709, 0x57},
+ {0x370a, 0x01},
+ {0x370b, 0x14},
+ {0x3714, 0x01},
+ {0x3719, 0x1f},
+ {0x371b, 0x16},
+ {0x371c, 0x00},
+ {0x371d, 0x08},
+ {0x373f, 0x63},
+ {0x3740, 0x63},
+ {0x3741, 0x63},
+ {0x3742, 0x63},
+ {0x3743, 0x01},
+ {0x3756, 0x9d},
+ {0x3757, 0x9d},
+ {0x3762, 0x1c},
+ {0x3776, 0x05},
+ {0x3777, 0x22},
+ {0x3779, 0x60},
+ {0x377c, 0x48},
+ {0x3784, 0x06},
+ {0x3785, 0x0a},
+ {0x3790, 0x10},
+ {0x3793, 0x04},
+ {0x3794, 0x07},
+ {0x3796, 0x00},
+ {0x3797, 0x02},
+ {0x379c, 0x4d},
+ {0x37a1, 0x80},
+ {0x37bb, 0x88},
+ {0x37be, 0x48},
+ {0x37bf, 0x01},
+ {0x37c0, 0x01},
+ {0x37c4, 0x72},
+ {0x37c5, 0x72},
+ {0x37c6, 0x72},
+ {0x37ca, 0x21},
+ {0x37cc, 0x13},
+ {0x37cd, 0x90},
+ {0x37cf, 0x02},
+ {0x37d0, 0x00},
+ {0x37d1, 0x72},
+ {0x37d2, 0x01},
+ {0x37d3, 0x14},
+ {0x37d4, 0x00},
+ {0x37d5, 0x6c},
+ {0x37d6, 0x00},
+ {0x37d7, 0xf7},
+ {0x37d8, 0x01},
+ {0x37dc, 0x00},
+ {0x37dd, 0x00},
+ {0x37da, 0x00},
+ {0x37db, 0x00},
+ {0x3800, 0x00},
+ {0x3801, 0x00},
+ {0x3802, 0x00},
+ {0x3803, 0x00},
+ {0x3804, 0x0a},
+ {0x3805, 0x8f},
+ {0x3806, 0x05},
+ {0x3807, 0xff},
+ {0x3808, 0x0a},
+ {0x3809, 0x80},
+ {0x380a, 0x05},
+ {0x380b, 0xf0},
+ {0x380e, 0x06},
+ {0x380f, 0x58},
+ {0x3811, 0x08},
+ {0x3813, 0x08},
+ {0x3814, 0x01},
+ {0x3815, 0x01},
+ {0x3816, 0x01},
+ {0x3817, 0x01},
+ {0x3821, 0x00},
+ {0x3822, 0x14},
+ {0x3823, 0x18},
+ {0x3826, 0x00},
+ {0x3827, 0x00},
+ {0x384c, 0x02},
+ {0x384d, 0xdc},
+ {0x3858, 0x3c},
+ {0x3865, 0x02},
+ {0x3866, 0x00},
+ {0x3867, 0x00},
+ {0x3868, 0x02},
+ {0x3900, 0x13},
+ {0x3940, 0x13},
+ {0x3980, 0x13},
+ {0x3c01, 0x11},
+ {0x3c05, 0x00},
+ {0x3c0f, 0x1c},
+ {0x3c12, 0x0d},
+ {0x3c19, 0x00},
+ {0x3c21, 0x00},
+ {0x3c3a, 0x10},
+ {0x3c3b, 0x18},
+ {0x3c3d, 0xc6},
+ {0x3c5a, 0x55},
+ {0x3c5d, 0xcf},
+ {0x3c5e, 0xcf},
+ {0x3d8c, 0x70},
+ {0x3d8d, 0x10},
+ {0x4000, 0xf9},
+ {0x4004, 0x00},
+ {0x4005, 0x40},
+ {0x4008, 0x02},
+ {0x4009, 0x11},
+ {0x400a, 0x06},
+ {0x400b, 0x40},
+ {0x400e, 0x40},
+ {0x402e, 0x00},
+ {0x402f, 0x40},
+ {0x4030, 0x00},
+ {0x4031, 0x40},
+ {0x4032, 0x0f},
+ {0x4033, 0x80},
+ {0x4050, 0x00},
+ {0x4051, 0x07},
+ {0x4011, 0xbb},
+ {0x410f, 0x01},
+ {0x4289, 0x00},
+ {0x428a, 0x46},
+ {0x430b, 0x0f},
+ {0x430c, 0xfc},
+ {0x430d, 0x00},
+ {0x430e, 0x00},
+ {0x4314, 0x04},
+ {0x4500, 0x18},
+ {0x4501, 0x18},
+ {0x4503, 0x10},
+ {0x4504, 0x00},
+ {0x4506, 0x32},
+ {0x4601, 0x30},
+ {0x4603, 0x00},
+ {0x460a, 0x50},
+ {0x460c, 0x60},
+ {0x4640, 0x62},
+ {0x4646, 0xaa},
+ {0x4647, 0x55},
+ {0x4648, 0x99},
+ {0x4649, 0x66},
+ {0x464d, 0x00},
+ {0x4654, 0x11},
+ {0x4655, 0x22},
+ {0x4800, 0x44},
+ {0x4810, 0xff},
+ {0x4811, 0xff},
+ {0x481f, 0x30},
+ {0x4d00, 0x4d},
+ {0x4d01, 0x9d},
+ {0x4d02, 0xb9},
+ {0x4d03, 0x2e},
+ {0x4d04, 0x4a},
+ {0x4d05, 0x3d},
+ {0x4d09, 0x4f},
+ {0x5000, 0x1f},
+ {0x5080, 0x00},
+ {0x50c0, 0x00},
+ {0x5100, 0x00},
+ {0x5200, 0x00},
+ {0x5201, 0x00},
+ {0x5202, 0x03},
+ {0x5203, 0xff},
+ {0x5780, 0x53},
+ {0x5782, 0x18},
+ {0x5783, 0x3c},
+ {0x5786, 0x01},
+ {0x5788, 0x18},
+ {0x5789, 0x3c},
+ {0x5792, 0x11},
+ {0x5793, 0x33},
+ {0x5857, 0xff},
+ {0x5858, 0xff},
+ {0x5859, 0xff},
+ {0x58d7, 0xff},
+ {0x58d8, 0xff},
+ {0x58d9, 0xff},
+ {REG_NULL, 0x00},
+};
+
+static const struct regval os04a10_linear10bit_2688x1520_regs_2lane[] = {
+ {0x0305, 0x5c},
+ {0x0325, 0xd8},
+ {0x3667, 0xd4},
+ {0x3671, 0x08},
+ {0x376c, 0x14},
+ {0x380c, 0x08},
+ {0x380d, 0x94},
+ {0x381c, 0x00},
+ {0x3820, 0x02},
+ {0x3833, 0x40},
+ {0x3c55, 0x08},
+ {0x4001, 0x2f},
+ {0x4288, 0xcf},
+ {0x4507, 0x02},
+ {0x480e, 0x00},
+ {0x4813, 0x00},
+ {0x4837, 0x0e},
+ {0x484b, 0x27},
+ {0x5001, 0x0d},
+ {REG_NULL, 0x00},
+};
+
+static const struct regval os04a10_hdr10bit_2688x1520_regs_2lane[] = {
+ {0x0305, 0x78},
+ {0x0325, 0x90},
+ {0x3667, 0x54},
+ {0x3671, 0x09},
+ {0x376c, 0x04},
+ {0x380c, 0x02},
+ {0x380d, 0xdc},
+ {0x381c, 0x08},
+ {0x3820, 0x03},
+ {0x3833, 0x41},
+ {0x3c55, 0xcb},
+ {0x4001, 0xef},
+ {0x4288, 0xce},
+ {0x4507, 0x03},
+ {0x480e, 0x04},
+ {0x4813, 0x84},
+ {0x4837, 0x07},
+ {0x484b, 0x67},
+ {0x4883, 0x05},
+ {0x4884, 0x08},
+ {0x4885, 0x03},
+ {0x5001, 0x0c},
+ {REG_NULL, 0x00},
+};
+
/*
* The width and height must be configured to be
* the same as the current output resolution of the sensor.
@@ -817,8 +1175,11 @@
.exp_def = 0x0240,
.hts_def = 0x02dc * 4,
.vts_def = 0x0cb0,
+ .global_reg_list = os04a10_global_regs,
.reg_list = os04a10_linear10bit_2688x1520_regs,
.hdr_mode = NO_HDR,
+ .link_freq_idx = 0,
+ .bpp = 10,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
},
{
@@ -834,8 +1195,11 @@
.hts_def = 0x02dc * 4,
.vts_def = 0x0658,
/*.vts_def = 0x0cb0,*/
+ .global_reg_list = os04a10_global_regs,
.reg_list = os04a10_hdr10bit_2688x1520_regs,
.hdr_mode = HDR_X2,
+ .link_freq_idx = 0,
+ .bpp = 10,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
@@ -852,8 +1216,11 @@
.exp_def = 0x0240,
.hts_def = 0x05c4 * 2,
.vts_def = 0x0984,
+ .global_reg_list = os04a10_global_regs,
.reg_list = os04a10_linear12bit_2688x1520_regs,
.hdr_mode = NO_HDR,
+ .link_freq_idx = 1,
+ .bpp = 12,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
},
{
@@ -867,8 +1234,11 @@
.exp_def = 0x0240,
.hts_def = 0x05c4 * 2,
.vts_def = 0x0658,
+ .global_reg_list = os04a10_global_regs,
.reg_list = os04a10_hdr12bit_2688x1520_regs,
.hdr_mode = HDR_X2,
+ .link_freq_idx = 1,
+ .bpp = 12,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
@@ -885,8 +1255,55 @@
.exp_def = 0x0200,
.hts_def = 0x05a0 * 2,
.vts_def = 0x05dc,
+ .global_reg_list = os04a10_global_regs,
.reg_list = os04a10_hdr12bit_2560x1440_regs,
.hdr_mode = HDR_X2,
+ .link_freq_idx = 1,
+ .bpp = 12,
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
+ .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
+ .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
+ .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
+ },
+};
+
+static const struct os04a10_mode supported_modes_2lane[] = {
+ {
+ .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .width = 2688,
+ .height = 1520,
+ .max_fps = {
+ .numerator = 10000,
+ .denominator = 302834,
+ },
+ .exp_def = 0x0640,
+ .hts_def = 0x0894,
+ .vts_def = 0x0658,
+ .global_reg_list = os04a10_global_regs_2lane,
+ .reg_list = os04a10_linear10bit_2688x1520_regs_2lane,
+ .hdr_mode = NO_HDR,
+ .link_freq_idx = 0,
+ .bpp = 10,
+ .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
+ },
+ {
+ .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .width = 2688,
+ .height = 1520,
+ .max_fps = {
+ .numerator = 10000,
+ .denominator = 302834,
+ /*.denominator = 151417,*/
+ },
+ .exp_def = 0x0640,
+ .hts_def = 0x02dc * 4,
+ .vts_def = 0x0658,
+ /*.vts_def = 0x0cb0,*/
+ .global_reg_list = os04a10_global_regs_2lane,
+ .reg_list = os04a10_hdr10bit_2688x1520_regs_2lane,
+ .hdr_mode = HDR_X2,
+ .link_freq_idx = 2,
+ .bpp = 10,
.vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
.vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
.vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
@@ -897,6 +1314,7 @@
static const s64 link_freq_menu_items[] = {
MIPI_FREQ_360M,
MIPI_FREQ_648M,
+ MIPI_FREQ_720M,
};
static const char * const os04a10_test_pattern_menu[] = {
@@ -1005,15 +1423,15 @@
unsigned int i;
for (i = 0; i < os04a10->cfg_num; i++) {
- dist = os04a10_get_reso_dist(&supported_modes[i], framefmt);
- if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
- (supported_modes[i].bus_fmt == framefmt->code)) {
+ dist = os04a10_get_reso_dist(&os04a10->supported_modes[i], framefmt);
+ if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
+ (os04a10->supported_modes[i].bus_fmt == framefmt->code)) {
cur_best_fit_dist = dist;
cur_best_fit = i;
}
}
- return &supported_modes[cur_best_fit];
+ return &os04a10->supported_modes[cur_best_fit];
}
static int os04a10_set_fmt(struct v4l2_subdev *sd,
@@ -1025,6 +1443,7 @@
s64 h_blank, vblank_def;
u64 dst_link_freq = 0;
u64 dst_pixel_rate = 0;
+ u8 lanes = os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes;
mutex_lock(&os04a10->mutex);
@@ -1049,28 +1468,9 @@
__v4l2_ctrl_modify_range(os04a10->vblank, vblank_def,
OS04A10_VTS_MAX - mode->height,
1, vblank_def);
- if (mode->hdr_mode == NO_HDR) {
- if (mode->bus_fmt == MEDIA_BUS_FMT_SBGGR10_1X10) {
- dst_link_freq = 0;
- dst_pixel_rate = PIXEL_RATE_WITH_360M;
- } else {
- dst_link_freq = 1;
- dst_pixel_rate = PIXEL_RATE_WITH_648M;
- }
- } else if (mode->hdr_mode == HDR_X2) {
- if (mode->width == 2560 && mode->height == 1440) {
- dst_link_freq = 1;
- dst_pixel_rate = PIXEL_RATE_WITH_648M;
- } else {
- if (mode->bus_fmt == MEDIA_BUS_FMT_SBGGR10_1X10) {
- dst_link_freq = 0;
- dst_pixel_rate = PIXEL_RATE_WITH_360M;
- } else {
- dst_link_freq = 1;
- dst_pixel_rate = PIXEL_RATE_WITH_648M;
- }
- }
- }
+ dst_link_freq = mode->link_freq_idx;
+ dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] /
+ mode->bpp * 2 * lanes;
__v4l2_ctrl_s_ctrl_int64(os04a10->pixel_rate,
dst_pixel_rate);
__v4l2_ctrl_s_ctrl(os04a10->link_freq,
@@ -1134,13 +1534,13 @@
if (fse->index >= os04a10->cfg_num)
return -EINVAL;
- if (fse->code != supported_modes[fse->index].bus_fmt)
+ if (fse->code != os04a10->supported_modes[fse->index].bus_fmt)
return -EINVAL;
- fse->min_width = supported_modes[fse->index].width;
- fse->max_width = supported_modes[fse->index].width;
- fse->max_height = supported_modes[fse->index].height;
- fse->min_height = supported_modes[fse->index].height;
+ fse->min_width = os04a10->supported_modes[fse->index].width;
+ fse->max_width = os04a10->supported_modes[fse->index].width;
+ fse->max_height = os04a10->supported_modes[fse->index].height;
+ fse->min_height = os04a10->supported_modes[fse->index].height;
return 0;
}
@@ -1167,31 +1567,30 @@
struct os04a10 *os04a10 = to_os04a10(sd);
const struct os04a10_mode *mode = os04a10->cur_mode;
- mutex_lock(&os04a10->mutex);
fi->interval = mode->max_fps;
- mutex_unlock(&os04a10->mutex);
return 0;
}
-static int os04a10_g_mbus_config(struct v4l2_subdev *sd,
+static int os04a10_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
struct v4l2_mbus_config *config)
{
struct os04a10 *os04a10 = to_os04a10(sd);
const struct os04a10_mode *mode = os04a10->cur_mode;
u32 val = 0;
+ u8 lanes = os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes;
if (mode->hdr_mode == NO_HDR)
- val = 1 << (OS04A10_LANES - 1) |
+ val = 1 << (lanes - 1) |
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
if (mode->hdr_mode == HDR_X2)
- val = 1 << (OS04A10_LANES - 1) |
+ val = 1 << (lanes - 1) |
V4L2_MBUS_CSI2_CHANNEL_0 |
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;
@@ -1201,10 +1600,10 @@
struct rkmodule_inf *inf)
{
memset(inf, 0, sizeof(*inf));
- strlcpy(inf->base.sensor, OS04A10_NAME, sizeof(inf->base.sensor));
- strlcpy(inf->base.module, os04a10->module_name,
+ strscpy(inf->base.sensor, OS04A10_NAME, sizeof(inf->base.sensor));
+ strscpy(inf->base.module, os04a10->module_name,
sizeof(inf->base.module));
- strlcpy(inf->base.lens, os04a10->len_name, sizeof(inf->base.lens));
+ strscpy(inf->base.lens, os04a10->len_name, sizeof(inf->base.lens));
}
static int os04a10_set_hdrae(struct os04a10 *os04a10,
@@ -1455,6 +1854,10 @@
long ret = 0;
u32 i, h, w;
u32 stream = 0;
+ u64 dst_link_freq = 0;
+ u64 dst_pixel_rate = 0;
+ u8 lanes = os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes;
+ const struct os04a10_mode *mode;
switch (cmd) {
case PREISP_CMD_SET_HDRAE_EXP:
@@ -1464,10 +1867,10 @@
w = os04a10->cur_mode->width;
h = os04a10->cur_mode->height;
for (i = 0; i < os04a10->cfg_num; i++) {
- if (w == supported_modes[i].width &&
- h == supported_modes[i].height &&
- supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
- os04a10->cur_mode = &supported_modes[i];
+ if (w == os04a10->supported_modes[i].width &&
+ h == os04a10->supported_modes[i].height &&
+ os04a10->supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
+ os04a10->cur_mode = &os04a10->supported_modes[i];
break;
}
}
@@ -1477,12 +1880,20 @@
hdr_cfg->hdr_mode, w, h);
ret = -EINVAL;
} else {
- w = os04a10->cur_mode->hts_def - os04a10->cur_mode->width;
- h = os04a10->cur_mode->vts_def - os04a10->cur_mode->height;
+ mode = os04a10->cur_mode;
+ w = mode->hts_def - mode->width;
+ h = mode->vts_def - mode->height;
__v4l2_ctrl_modify_range(os04a10->hblank, w, w, 1, w);
__v4l2_ctrl_modify_range(os04a10->vblank, h,
OS04A10_VTS_MAX - os04a10->cur_mode->height,
1, h);
+ dst_link_freq = mode->link_freq_idx;
+ dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] /
+ mode->bpp * 2 * lanes;
+ __v4l2_ctrl_s_ctrl_int64(os04a10->pixel_rate,
+ dst_pixel_rate);
+ __v4l2_ctrl_s_ctrl(os04a10->link_freq,
+ dst_link_freq);
dev_info(&os04a10->client->dev,
"sensor mode: %d\n",
os04a10->cur_mode->hdr_mode);
@@ -1535,7 +1946,6 @@
{
void __user *up = compat_ptr(arg);
struct rkmodule_inf *inf;
- struct rkmodule_awb_cfg *cfg;
struct rkmodule_hdr_cfg *hdr;
struct preisp_hdrae_exp_s *hdrae;
struct rkmodule_dcg_ratio *dcg;
@@ -1552,21 +1962,12 @@
}
ret = os04a10_ioctl(sd, cmd, inf);
- if (!ret)
+ if (!ret) {
ret = copy_to_user(up, inf, sizeof(*inf));
- kfree(inf);
- break;
- case RKMODULE_AWB_CFG:
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
- if (!cfg) {
- ret = -ENOMEM;
- return ret;
+ if (ret)
+ ret = -EFAULT;
}
-
- ret = copy_from_user(cfg, up, sizeof(*cfg));
- if (!ret)
- ret = os04a10_ioctl(sd, cmd, cfg);
- kfree(cfg);
+ kfree(inf);
break;
case RKMODULE_GET_HDR_CFG:
hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
@@ -1576,8 +1977,11 @@
}
ret = os04a10_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:
@@ -1587,9 +1991,10 @@
return ret;
}
- ret = copy_from_user(hdr, up, sizeof(*hdr));
- if (!ret)
- ret = os04a10_ioctl(sd, cmd, hdr);
+ if (copy_from_user(hdr, up, sizeof(*hdr)))
+ return -EFAULT;
+
+ ret = os04a10_ioctl(sd, cmd, hdr);
kfree(hdr);
break;
case PREISP_CMD_SET_HDRAE_EXP:
@@ -1599,20 +2004,23 @@
return ret;
}
- ret = copy_from_user(hdrae, up, sizeof(*hdrae));
- if (!ret)
- ret = os04a10_ioctl(sd, cmd, hdrae);
+ if (copy_from_user(hdrae, up, sizeof(*hdrae)))
+ return -EFAULT;
+
+ ret = os04a10_ioctl(sd, cmd, hdrae);
kfree(hdrae);
break;
case RKMODULE_SET_CONVERSION_GAIN:
- ret = copy_from_user(&cg, up, sizeof(cg));
- if (!ret)
- ret = os04a10_ioctl(sd, cmd, &cg);
+ if (copy_from_user(&cg, up, sizeof(cg)))
+ return -EFAULT;
+
+ ret = os04a10_ioctl(sd, cmd, &cg);
break;
case RKMODULE_SET_QUICK_STREAM:
- ret = copy_from_user(&stream, up, sizeof(u32));
- if (!ret)
- ret = os04a10_ioctl(sd, cmd, &stream);
+ if (copy_from_user(&stream, up, sizeof(u32)))
+ return -EFAULT;
+
+ ret = os04a10_ioctl(sd, cmd, &stream);
break;
case RKMODULE_GET_DCG_RATIO:
dcg = kzalloc(sizeof(*dcg), GFP_KERNEL);
@@ -1622,8 +2030,11 @@
}
ret = os04a10_ioctl(sd, cmd, dcg);
- if (!ret)
+ if (!ret) {
ret = copy_to_user(up, dcg, sizeof(*dcg));
+ if (ret)
+ return -EFAULT;
+ }
kfree(dcg);
break;
default:
@@ -1645,14 +2056,17 @@
OS04A10_REG_HCG_SWITCH,
OS04A10_REG_VALUE_08BIT,
&val);
- val |= 0x70;
+ val &= ~0x70;
+ if (!os04a10->long_hcg)
+ val |= 0x10;
+ if (!os04a10->middle_hcg)
+ val |= 0x20;
+ if (!os04a10->short_hcg)
+ val |= 0x40;
ret |= os04a10_write_reg(client,
OS04A10_REG_HCG_SWITCH,
OS04A10_REG_VALUE_08BIT,
val);
- os04a10->long_hcg = false;
- os04a10->middle_hcg = false;
- os04a10->short_hcg = false;
return ret;
}
@@ -1661,13 +2075,6 @@
int ret;
if (!os04a10->is_thunderboot) {
- ret = os04a10_write_array(os04a10->client, os04a10_global_regs);
- if (ret) {
- dev_err(&os04a10->client->dev,
- "could not set init registers\n");
- return ret;
- }
-
ret = os04a10_write_array(os04a10->client, os04a10->cur_mode->reg_list);
if (ret)
return ret;
@@ -1768,6 +2175,13 @@
OS04A10_REG_VALUE_08BIT,
0x01);
usleep_range(100, 200);
+ ret |= os04a10_write_array(os04a10->client,
+ os04a10->cur_mode->global_reg_list);
+ if (ret) {
+ dev_err(&os04a10->client->dev,
+ "could not set init registers\n");
+ goto unlock_and_return;
+ }
}
os04a10->power_on = true;
@@ -1821,7 +2235,7 @@
dev_err(dev, "Failed to enable regulators\n");
goto disable_clk;
}
-
+ usleep_range(25000, 30000);
if (!IS_ERR(os04a10->reset_gpio))
gpiod_direction_output(os04a10->reset_gpio, 0);
@@ -1881,9 +2295,10 @@
os04a10->is_thunderboot_ng = false;
regulator_bulk_disable(OS04A10_NUM_SUPPLIES, os04a10->supplies);
}
+ usleep_range(30000, 31000);
}
-static int os04a10_runtime_resume(struct device *dev)
+static int __maybe_unused os04a10_runtime_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -1892,7 +2307,7 @@
return __os04a10_power_on(os04a10);
}
-static int os04a10_runtime_suspend(struct device *dev)
+static int __maybe_unused os04a10_runtime_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -1909,7 +2324,7 @@
struct os04a10 *os04a10 = to_os04a10(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_get_try_format(sd, fh->pad, 0);
- const struct os04a10_mode *def_mode = &supported_modes[0];
+ const struct os04a10_mode *def_mode = &os04a10->supported_modes[0];
mutex_lock(&os04a10->mutex);
/* Initialize try_fmt */
@@ -1934,11 +2349,11 @@
if (fie->index >= os04a10->cfg_num)
return -EINVAL;
- fie->code = supported_modes[fie->index].bus_fmt;
- fie->width = supported_modes[fie->index].width;
- fie->height = supported_modes[fie->index].height;
- fie->interval = supported_modes[fie->index].max_fps;
- fie->reserved[0] = supported_modes[fie->index].hdr_mode;
+ fie->code = os04a10->supported_modes[fie->index].bus_fmt;
+ fie->width = os04a10->supported_modes[fie->index].width;
+ fie->height = os04a10->supported_modes[fie->index].height;
+ fie->interval = os04a10->supported_modes[fie->index].max_fps;
+ fie->reserved[0] = os04a10->supported_modes[fie->index].hdr_mode;
return 0;
}
@@ -1964,7 +2379,6 @@
static const struct v4l2_subdev_video_ops os04a10_video_ops = {
.s_stream = os04a10_s_stream,
.g_frame_interval = os04a10_g_frame_interval,
- .g_mbus_config = os04a10_g_mbus_config,
};
static const struct v4l2_subdev_pad_ops os04a10_pad_ops = {
@@ -1973,6 +2387,7 @@
.enum_frame_interval = os04a10_enum_frame_interval,
.get_fmt = os04a10_get_fmt,
.set_fmt = os04a10_set_fmt,
+ .get_mbus_config = os04a10_g_mbus_config,
};
static const struct v4l2_subdev_ops os04a10_subdev_ops = {
@@ -2052,7 +2467,7 @@
val |= MIRROR_BIT_MASK;
else
val &= ~MIRROR_BIT_MASK;
- ret = os04a10_write_reg(os04a10->client, OS04A10_FLIP_REG,
+ ret |= os04a10_write_reg(os04a10->client, OS04A10_FLIP_REG,
OS04A10_REG_VALUE_08BIT,
val);
if (ret == 0)
@@ -2066,7 +2481,7 @@
val |= FLIP_BIT_MASK;
else
val &= ~FLIP_BIT_MASK;
- ret = os04a10_write_reg(os04a10->client, OS04A10_FLIP_REG,
+ ret |= os04a10_write_reg(os04a10->client, OS04A10_FLIP_REG,
OS04A10_REG_VALUE_08BIT,
val);
if (ret == 0)
@@ -2096,6 +2511,7 @@
int ret;
u64 dst_link_freq = 0;
u64 dst_pixel_rate = 0;
+ u8 lanes = os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes;
handler = &os04a10->ctrl_handler;
mode = os04a10->cur_mode;
@@ -2106,23 +2522,18 @@
os04a10->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
V4L2_CID_LINK_FREQ,
- 1, 0, link_freq_menu_items);
+ ARRAY_SIZE(link_freq_menu_items) - 1, 0, link_freq_menu_items);
- if (os04a10->cur_mode->bus_fmt == MEDIA_BUS_FMT_SBGGR10_1X10) {
- dst_link_freq = 0;
- dst_pixel_rate = PIXEL_RATE_WITH_360M;
- } else {
- dst_link_freq = 1;
- dst_pixel_rate = PIXEL_RATE_WITH_648M;
- }
+ dst_link_freq = mode->link_freq_idx;
+ dst_pixel_rate = (u32)link_freq_menu_items[mode->link_freq_idx] /
+ mode->bpp * 2 * lanes;
/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
os04a10->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
V4L2_CID_PIXEL_RATE,
0, PIXEL_RATE_WITH_648M,
1, dst_pixel_rate);
- __v4l2_ctrl_s_ctrl(os04a10->link_freq,
- dst_link_freq);
+ __v4l2_ctrl_s_ctrl(os04a10->link_freq, dst_link_freq);
h_blank = mode->hts_def - mode->width;
os04a10->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
@@ -2170,6 +2581,8 @@
os04a10->long_hcg = false;
os04a10->middle_hcg = false;
os04a10->short_hcg = false;
+ if (!os04a10->is_thunderboot)
+ os04a10->is_thunderboot_ng = true;
return 0;
@@ -2252,6 +2665,7 @@
struct device_node *node = dev->of_node;
struct os04a10 *os04a10;
struct v4l2_subdev *sd;
+ struct device_node *endpoint;
char facing[2];
int ret;
u32 i, hdr_mode = 0;
@@ -2285,10 +2699,33 @@
hdr_mode = NO_HDR;
dev_warn(dev, " Get hdr mode failed! no hdr default\n");
}
- os04a10->cfg_num = ARRAY_SIZE(supported_modes);
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (!endpoint) {
+ dev_err(dev, "Failed to get endpoint\n");
+ return -EINVAL;
+ }
+
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
+ &os04a10->bus_cfg);
+ if (ret) {
+ dev_err(dev, "Failed to get bus config\n");
+ return -EINVAL;
+ }
+ if (os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes == 4) {
+ os04a10->supported_modes = supported_modes;
+ os04a10->cfg_num = ARRAY_SIZE(supported_modes);
+ dev_info(dev, "detect os04a10 lane %d\n",
+ os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes);
+ } else {
+ os04a10->supported_modes = supported_modes_2lane;
+ os04a10->cfg_num = ARRAY_SIZE(supported_modes_2lane);
+ dev_info(dev, "detect os04a10 lane %d\n",
+ os04a10->bus_cfg.bus.mipi_csi2.num_data_lanes);
+ }
+
for (i = 0; i < os04a10->cfg_num; i++) {
if (hdr_mode == supported_modes[i].hdr_mode) {
- os04a10->cur_mode = &supported_modes[i];
+ os04a10->cur_mode = &os04a10->supported_modes[i];
break;
}
}
@@ -2346,7 +2783,10 @@
ret = os04a10_check_sensor_id(os04a10, client);
if (ret)
goto err_power_off;
+
ret = os04a10_get_dcg_ratio(os04a10);
+ if (ret)
+ dev_warn(dev, "get dcg ratio failed\n");
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
sd->internal_ops = &os04a10_internal_ops;
--
Gitblit v1.6.2