[PATCH 03/13] media: i2c: os05b10: split common and mode-specific init registers
From: Tarang Raval
Date: Fri Mar 06 2026 - 07:39:12 EST
Separate common initialization registers from mode-specific settings.
Move resolution-dependent registers into a per-mode register list and
program them during stream enable.
Signed-off-by: Tarang Raval <tarang.raval@xxxxxxxxxxxxxxxxx>
---
drivers/media/i2c/os05b10.c | 118 ++++++++++++++++++++++--------------
1 file changed, 74 insertions(+), 44 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 89a564f70818..b1d9eaa473e4 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -122,37 +122,34 @@ static const char * const os05b10_supply_name[] = {
};
static const struct cci_reg_sequence os05b10_common_regs[] = {
- { OS05B10_REG_PLL_CTRL_01, 0x44 },
- { OS05B10_REG_PLL_CTRL_03, 0x02 },
- { OS05B10_REG_PLL_CTRL_05, 0x32 },
- { OS05B10_REG_PLL_CTRL_06, 0x00 },
- { OS05B10_REG_PLL_CTRL_25, 0x3b },
+ { OS05B10_REG_PLL_CTRL_01, 0x44 },
+ { OS05B10_REG_PLL_CTRL_03, 0x02 },
+ { OS05B10_REG_PLL_CTRL_05, 0x32 },
+ { OS05B10_REG_PLL_CTRL_06, 0x00 },
+ { OS05B10_REG_PLL_CTRL_25, 0x3b },
+ { OS05B10_REG_MIPI_SC_CTRL, 0x72 },
+ { OS05B10_REG_MIPI_SC_CTRL_1, 0x01 },
+ { OS05B10_REG_DIGITAL_GAIN, 0x0400 },
+ { OS05B10_REG_ANALOG_GAIN_SHORT, 0x0080 },
+ { OS05B10_REG_DIGITAL_GAIN_SHORT, 0x0400 },
+ { OS05B10_REG_EXPOSURE_SHORT, 0x000020 },
{ CCI_REG8(0x3002), 0x21 },
- { OS05B10_REG_MIPI_SC_CTRL, 0x72 },
{ CCI_REG8(0x301e), 0xb4 },
{ CCI_REG8(0x301f), 0xd0 },
{ CCI_REG8(0x3021), 0x03 },
- { OS05B10_REG_MIPI_SC_CTRL_1, 0x01 },
{ CCI_REG8(0x3107), 0xa1 },
{ CCI_REG8(0x3108), 0x7d },
{ CCI_REG8(0x3109), 0xfc },
{ CCI_REG8(0x3503), 0x88 },
- { OS05B10_REG_DIGITAL_GAIN, 0x0400 },
- { OS05B10_REG_ANALOG_GAIN_SHORT, 0x0080 },
- { OS05B10_REG_DIGITAL_GAIN_SHORT, 0x0400 },
- { OS05B10_REG_EXPOSURE_SHORT, 0x000020 },
{ CCI_REG8(0x3600), 0x4d },
{ CCI_REG8(0x3601), 0x08 },
- { CCI_REG8(0x3610), 0x87 },
{ CCI_REG8(0x3611), 0x24 },
{ CCI_REG8(0x3614), 0x4c },
- { CCI_REG8(0x3620), 0x0c },
{ CCI_REG8(0x3632), 0x80 },
{ CCI_REG8(0x3633), 0x00 },
{ CCI_REG8(0x3636), 0xcc },
{ CCI_REG8(0x3637), 0x27 },
{ CCI_REG8(0x3660), 0x00 },
- { CCI_REG8(0x3662), 0x10 },
{ CCI_REG8(0x3665), 0x00 },
{ CCI_REG8(0x3666), 0x00 },
{ CCI_REG8(0x366a), 0x14 },
@@ -236,7 +233,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x370f), 0x1c },
{ CCI_REG8(0x3710), 0x00 },
{ CCI_REG8(0x3713), 0x00 },
- { CCI_REG8(0x3714), 0x24 },
{ CCI_REG8(0x3716), 0x24 },
{ CCI_REG8(0x371a), 0x1e },
{ CCI_REG8(0x3724), 0x09 },
@@ -245,7 +241,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x3730), 0xe1 },
{ CCI_REG8(0x3735), 0x80 },
{ CCI_REG8(0x3739), 0x10 },
- { CCI_REG8(0x373f), 0xb0 },
{ CCI_REG8(0x3740), 0x28 },
{ CCI_REG8(0x3741), 0x21 },
{ CCI_REG8(0x3742), 0x21 },
@@ -291,8 +286,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x37ac), 0xa0 },
{ CCI_REG8(0x37be), 0x0a },
{ CCI_REG8(0x37bb), 0x02 },
- { CCI_REG8(0x37bf), 0x05 },
- { CCI_REG8(0x37c2), 0x04 },
{ CCI_REG8(0x37c4), 0x11 },
{ CCI_REG8(0x37c5), 0x80 },
{ CCI_REG8(0x37c6), 0x14 },
@@ -301,7 +294,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x37cd), 0x17 },
{ CCI_REG8(0x37ce), 0x01 },
{ CCI_REG8(0x37d8), 0x02 },
- { CCI_REG8(0x37d9), 0x08 },
{ CCI_REG8(0x37dc), 0x01 },
{ CCI_REG8(0x37e0), 0x0c },
{ CCI_REG8(0x37e1), 0x20 },
@@ -314,25 +306,10 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x37f5), 0x00 },
{ CCI_REG8(0x37f6), 0x00 },
{ CCI_REG8(0x37f7), 0x00 },
- { OS05B10_REG_X_ADDR_START, 0x0130 },
- { OS05B10_REG_Y_ADDR_START, 0x0000 },
- { OS05B10_REG_X_ADDR_END, 0x0b5f },
- { OS05B10_REG_Y_ADDR_END, 0x07a7 },
- { OS05B10_REG_X_OUTPUT_SIZE, 0x0a20 },
- { OS05B10_REG_Y_OUTPUT_SIZE, 0x0798 },
- { OS05B10_REG_HTS, 0x06d0 },
- { OS05B10_REG_ISP_X_WIN, 0x0008 },
- { OS05B10_REG_ISP_Y_WIN, 0x0008 },
- { OS05B10_REG_X_INC_ODD, 0x01 },
- { OS05B10_REG_X_INC_EVEN, 0x01 },
- { OS05B10_REG_Y_INC_ODD, 0x01 },
- { OS05B10_REG_Y_INC_EVEN, 0x01 },
{ CCI_REG8(0x3818), 0x00 },
{ CCI_REG8(0x3819), 0x00 },
{ CCI_REG8(0x381a), 0x00 },
{ CCI_REG8(0x381b), 0x01 },
- { OS05B10_REG_FORMAT1, 0x88 },
- { OS05B10_REG_FORMAT2, 0x00 },
{ CCI_REG8(0x3822), 0x12 },
{ CCI_REG8(0x3823), 0x08 },
{ CCI_REG8(0x3824), 0x00 },
@@ -342,7 +319,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x3829), 0x03 },
{ CCI_REG8(0x382a), 0x00 },
{ CCI_REG8(0x382b), 0x00 },
- { CCI_REG8(0x3832), 0x08 },
{ CCI_REG8(0x3838), 0x00 },
{ CCI_REG8(0x3839), 0x00 },
{ CCI_REG8(0x383a), 0x00 },
@@ -363,26 +339,19 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x38a7), 0x04 },
{ CCI_REG8(0x38b8), 0x02 },
{ CCI_REG8(0x3c80), 0x3e },
- { CCI_REG8(0x3c86), 0x01 },
{ CCI_REG8(0x3c87), 0x02 },
{ CCI_REG8(0x389c), 0x00 },
{ CCI_REG8(0x3ca2), 0x0c },
{ CCI_REG8(0x3d85), 0x1b },
- { CCI_REG8(0x3d8c), 0x01 },
{ CCI_REG8(0x3d8d), 0xe2 },
{ CCI_REG8(0x3f00), 0xcb },
- { CCI_REG8(0x3f03), 0x08 },
{ CCI_REG8(0x3f9e), 0x07 },
{ CCI_REG8(0x3f9f), 0x04 },
{ CCI_REG8(0x4000), 0xf3 },
{ CCI_REG8(0x4002), 0x00 },
{ CCI_REG8(0x4003), 0x40 },
- { CCI_REG8(0x4008), 0x02 },
- { CCI_REG8(0x4009), 0x0d },
- { CCI_REG8(0x400a), 0x01 },
{ CCI_REG8(0x400b), 0x00 },
{ CCI_REG8(0x4040), 0x00 },
- { CCI_REG8(0x4041), 0x07 },
{ CCI_REG8(0x4090), 0x14 },
{ CCI_REG8(0x40b0), 0x01 },
{ CCI_REG8(0x40b1), 0x01 },
@@ -402,7 +371,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x4305), 0x83 },
{ CCI_REG8(0x4306), 0x21 },
{ CCI_REG8(0x430d), 0x00 },
- { CCI_REG8(0x4505), 0xc4 },
{ CCI_REG8(0x4506), 0x00 },
{ CCI_REG8(0x4507), 0x60 },
{ CCI_REG8(0x4803), 0x00 },
@@ -414,7 +382,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x481f), 0x30 },
{ CCI_REG8(0x4825), 0x34 },
{ CCI_REG8(0x4829), 0x64 },
- { CCI_REG8(0x4837), 0x12 },
{ CCI_REG8(0x484b), 0x07 },
{ CCI_REG8(0x4883), 0x36 },
{ CCI_REG8(0x4885), 0x03 },
@@ -447,6 +414,42 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x3222), 0x03 },
};
+static const struct cci_reg_sequence mode_2592_1944_regs[] = {
+ { OS05B10_REG_X_ADDR_START, 0x0130 },
+ { OS05B10_REG_Y_ADDR_START, 0x0000 },
+ { OS05B10_REG_X_ADDR_END, 0x0b5f },
+ { OS05B10_REG_Y_ADDR_END, 0x07a7 },
+ { OS05B10_REG_X_OUTPUT_SIZE, 0x0a20 },
+ { OS05B10_REG_Y_OUTPUT_SIZE, 0x0798 },
+ { OS05B10_REG_HTS, 0x06d0 },
+ { OS05B10_REG_ISP_X_WIN, 0x0008 },
+ { OS05B10_REG_ISP_Y_WIN, 0x0008 },
+ { OS05B10_REG_X_INC_ODD, 0x01 },
+ { OS05B10_REG_X_INC_EVEN, 0x01 },
+ { OS05B10_REG_Y_INC_ODD, 0x01 },
+ { OS05B10_REG_Y_INC_EVEN, 0x01 },
+ { OS05B10_REG_FORMAT1, 0x88 },
+ { OS05B10_REG_FORMAT2, 0x00 },
+ { CCI_REG8(0x3610), 0x87 },
+ { CCI_REG8(0x3620), 0x0c },
+ { CCI_REG8(0x3662), 0x10 },
+ { CCI_REG8(0x3714), 0x24 },
+ { CCI_REG8(0x373f), 0xb0 },
+ { CCI_REG8(0x37bf), 0x05 },
+ { CCI_REG8(0x37c2), 0x04 },
+ { CCI_REG8(0x37d9), 0x08 },
+ { CCI_REG8(0x3832), 0x08 },
+ { CCI_REG8(0x3c86), 0x01 },
+ { CCI_REG8(0x3d8c), 0x01 },
+ { CCI_REG8(0x3f03), 0x08 },
+ { CCI_REG8(0x4008), 0x02 },
+ { CCI_REG8(0x4009), 0x0d },
+ { CCI_REG8(0x400a), 0x01 },
+ { CCI_REG8(0x4041), 0x07 },
+ { CCI_REG8(0x4505), 0xc4 },
+ { CCI_REG8(0x4837), 0x12 },
+};
+
struct os05b10 {
struct device *dev;
struct regmap *cci;
@@ -469,6 +472,11 @@ struct os05b10 {
u32 data_lanes;
};
+struct os05b10_reg_list {
+ u32 num_of_regs;
+ const struct cci_reg_sequence *regs;
+};
+
struct os05b10_mode {
u32 width;
u32 height;
@@ -476,6 +484,7 @@ struct os05b10_mode {
u32 hts;
u32 exp;
u8 bpp;
+ struct os05b10_reg_list reg_list;
};
static const struct os05b10_mode supported_modes_10bit[] = {
@@ -486,6 +495,10 @@ static const struct os05b10_mode supported_modes_10bit[] = {
.hts = 1744,
.exp = 1944,
.bpp = 10,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_2592_1944_regs),
+ .regs = mode_2592_1944_regs,
+ },
},
};
@@ -655,8 +668,16 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
u32 pad, u64 streams_mask)
{
struct os05b10 *os05b10 = to_os05b10(sd);
+ const struct os05b10_reg_list *reg_list;
+ const struct v4l2_mbus_framefmt *fmt;
+ const struct os05b10_mode *mode;
int ret;
+ fmt = v4l2_subdev_state_get_format(state, 0);
+ mode = v4l2_find_nearest_size(supported_modes_10bit,
+ ARRAY_SIZE(supported_modes_10bit), width,
+ height, fmt->width, fmt->height);
+
ret = pm_runtime_resume_and_get(os05b10->dev);
if (ret < 0)
return ret;
@@ -669,6 +690,15 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
goto err_rpm_put;
}
+ /* Write sensor mode registers */
+ reg_list = &mode->reg_list;
+ ret = cci_multi_reg_write(os05b10->cci, reg_list->regs,
+ reg_list->num_of_regs, NULL);
+ if (ret) {
+ dev_err(os05b10->dev, "fail to write initial registers\n");
+ goto err_rpm_put;
+ }
+
/* Apply customized user controls */
ret = __v4l2_ctrl_handler_setup(os05b10->sd.ctrl_handler);
if (ret)
--
2.34.1