* [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features
@ 2026-03-06 12:32 Tarang Raval
2026-03-06 12:32 ` [PATCH 01/13] media: i2c: os05b10: drop unused group-hold programming Tarang Raval
` (12 more replies)
0 siblings, 13 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
This series improves the OS05B10 sensor driver with cleanup,
refactoring, additional controls, and support for new modes.
Patches 1–3 perform initial cleanup and refactoring. Unused
group-hold programming is removed, register definitions are
introduced, and the initialization tables are reorganized by
splitting common and mode-specific registers.
Patches 4–6 add additional V4L2 controls including digital gain,
horizontal/vertical flip, and test pattern support.
Patches 7–9 extend the driver with 12-bit RAW support, update
pixel rate handling when switching between 10-bit and 12-bit
modes, and add new operating modes including 1080p and 2x2
binned 720p.
Patches 10–12 improve control handling and internal logic by
keeping vblank and exposure in sync on mode changes, updating
the active format before adjusting framing controls, and
renaming the vmax variable used by the VBLANK control.
Patch 13 adds support for 2-lane MIPI CSI-2 operation.
All patches were tested on the Debix Model A board running
Linux kernel v7.0-rc2.
Tarang Raval (13):
media: i2c: os05b10: drop unused group-hold programming
media: i2c: os05b10: add register definitions and use them in init
table
media: i2c: os05b10: split common and mode-specific init registers
media: i2c: os05b10: add V4L2 digital gain control
media: i2c: os05b10: Add H/V flip support
media: i2c: os05b10: Add test pattern options
media: i2c: os05b10: add 12-bit RAW mode support
media: i2c: os05b10: update pixel rate on 10/12-bit mode switch
media: i2c: os05b10: Add 1080p and 2x2 binning 720p modes
media: i2c: os05b10: keep vblank/exposure in sync on mode switch
media: i2c: os05b10: Update active format before adjusting framing
controls
media: i2c: os05b10: Rename vmax variable in VBLANK control
media: i2c: os05b10: add 2-lane support
drivers/media/i2c/os05b10.c | 676 ++++++++++++++++++++++++++++--------
1 file changed, 531 insertions(+), 145 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 01/13] media: i2c: os05b10: drop unused group-hold programming
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 02/13] media: i2c: os05b10: add register definitions and use them in init table Tarang Raval
` (11 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Register table included group-hold (0x3208) sequences for
groups 6/7/8/9 that only stage alternative tuning values in SRAM but are
never launched by the driver. Remove these group-hold blocks.
Also remove a duplicate register entry for 0x37bf.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 37 -------------------------------------
1 file changed, 37 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index e0453c988e4a..7f32e3b1e7bd 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -250,7 +250,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x37ab), 0x0e },
{ CCI_REG8(0x37ac), 0xa0 },
{ CCI_REG8(0x37be), 0x0a },
- { CCI_REG8(0x37bf), 0x05 },
{ CCI_REG8(0x37bb), 0x02 },
{ CCI_REG8(0x37bf), 0x05 },
{ CCI_REG8(0x37c2), 0x04 },
@@ -415,42 +414,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x5820), 0x00 },
{ CCI_REG8(0x5821), 0x00 },
{ CCI_REG8(0x3222), 0x03 },
- { CCI_REG8(0x3208), 0x06 },
- { CCI_REG8(0x3701), 0x1d },
- { CCI_REG8(0x37ab), 0x01 },
- { CCI_REG8(0x3790), 0x21 },
- { CCI_REG8(0x38be), 0x00 },
- { CCI_REG8(0x3791), 0x5a },
- { CCI_REG8(0x37bf), 0x1c },
- { CCI_REG8(0x3610), 0x37 },
- { CCI_REG8(0x3208), 0x16 },
- { CCI_REG8(0x3208), 0x07 },
- { CCI_REG8(0x3701), 0x1d },
- { CCI_REG8(0x37ab), 0x0e },
- { CCI_REG8(0x3790), 0x21 },
- { CCI_REG8(0x38be), 0x00 },
- { CCI_REG8(0x3791), 0x5a },
- { CCI_REG8(0x37bf), 0x0a },
- { CCI_REG8(0x3610), 0x87 },
- { CCI_REG8(0x3208), 0x17 },
- { CCI_REG8(0x3208), 0x08 },
- { CCI_REG8(0x3701), 0x1d },
- { CCI_REG8(0x37ab), 0x0e },
- { CCI_REG8(0x3790), 0x21 },
- { CCI_REG8(0x38be), 0x00 },
- { CCI_REG8(0x3791), 0x5a },
- { CCI_REG8(0x37bf), 0x0a },
- { CCI_REG8(0x3610), 0x87 },
- { CCI_REG8(0x3208), 0x18 },
- { CCI_REG8(0x3208), 0x09 },
- { CCI_REG8(0x3701), 0x1d },
- { CCI_REG8(0x37ab), 0x0e },
- { CCI_REG8(0x3790), 0x28 },
- { CCI_REG8(0x38be), 0x00 },
- { CCI_REG8(0x3791), 0x63 },
- { CCI_REG8(0x37bf), 0x0a },
- { CCI_REG8(0x3610), 0x87 },
- { CCI_REG8(0x3208), 0x19 },
};
struct os05b10 {
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 02/13] media: i2c: os05b10: add register definitions and use them in init table
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
2026-03-06 12:32 ` [PATCH 01/13] media: i2c: os05b10: drop unused group-hold programming Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 03/13] media: i2c: os05b10: split common and mode-specific init registers Tarang Raval
` (10 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Define named register macros for OS05B10 and replace raw register
addresses in the common initialization array with the new definitions.
This improves readability and maintainability without changing
functionality.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 111 +++++++++++++++++++++++-------------
1 file changed, 71 insertions(+), 40 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 7f32e3b1e7bd..89a564f70818 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -38,6 +38,20 @@
#define OS05B10_MODE_STANDBY 0x00
#define OS05B10_MODE_STREAMING 0x01
+#define OS05B10_REG_PLL_CTRL_01 CCI_REG8(0x0301)
+#define OS05B10_REG_PLL_CTRL_03 CCI_REG8(0x0303)
+#define OS05B10_REG_PLL_CTRL_05 CCI_REG8(0x0305)
+#define OS05B10_REG_PLL_CTRL_06 CCI_REG8(0x0306)
+#define OS05B10_REG_PLL_CTRL_25 CCI_REG8(0x0325)
+
+#define OS05B10_REG_MIPI_SC_CTRL CCI_REG8(0x3016)
+#define OS05B10_4_LANE_MODE 0x72
+#define OS05B10_2_LANE_MODE 0x32
+
+#define OS05B10_REG_MIPI_SC_CTRL_1 CCI_REG8(0x3022)
+#define OS05B10_10BIT_MODE 0x01
+#define OS05B10_12BIT_MODE 0x61
+
#define OS05B10_REG_EXPOSURE CCI_REG24(0x3500)
#define OS05B10_EXPOSURE_MIN 2
#define OS05B10_EXPOSURE_STEP 1
@@ -49,11 +63,42 @@
#define OS05B10_ANALOG_GAIN_STEP 1
#define OS05B10_ANALOG_GAIN_DEFAULT 0x80
+#define OS05B10_REG_DIGITAL_GAIN CCI_REG16(0x350a)
+#define OS05B10_DIGITAL_GAIN_MIN 0x400
+#define OS05B10_DIGITAL_GAIN_MAX 0x3fff
+#define OS05B10_DIGITAL_GAIN_STEP 16
+#define OS05B10_DIGITAL_GAIN_DEFAULT 0x400
+
+#define OS05B10_REG_ANALOG_GAIN_SHORT CCI_REG16(0x350c)
+#define OS05B10_REG_DIGITAL_GAIN_SHORT CCI_REG16(0x350e)
+#define OS05B10_REG_EXPOSURE_SHORT CCI_REG24(0x3510)
+
+#define OS05B10_REG_X_ADDR_START CCI_REG16(0x3800)
+#define OS05B10_REG_Y_ADDR_START CCI_REG16(0x3802)
+#define OS05B10_REG_X_ADDR_END CCI_REG16(0x3804)
+#define OS05B10_REG_Y_ADDR_END CCI_REG16(0x3806)
+#define OS05B10_REG_X_OUTPUT_SIZE CCI_REG16(0x3808)
+#define OS05B10_REG_Y_OUTPUT_SIZE CCI_REG16(0x380a)
+
#define OS05B10_REG_HTS CCI_REG16(0x380c)
#define OS05B10_REG_VTS CCI_REG16(0x380e)
#define OS05B10_VTS_MAX 0x7fff
+#define OS05B10_REG_ISP_X_WIN CCI_REG16(0x3810)
+#define OS05B10_REG_ISP_Y_WIN CCI_REG16(0x3812)
+#define OS05B10_REG_X_INC_ODD CCI_REG8(0x3814)
+#define OS05B10_REG_X_INC_EVEN CCI_REG8(0x3815)
+#define OS05B10_REG_Y_INC_ODD CCI_REG8(0x3816)
+#define OS05B10_REG_Y_INC_EVEN CCI_REG8(0x3817)
+
+#define OS05B10_REG_FORMAT1 CCI_REG8(0x3820)
+#define OS05B10_MIRROR BIT(3)
+#define OS05B10_FLIP GENMASK(5, 4)
+
+#define OS05B10_REG_FORMAT2 CCI_REG8(0x3821)
+#define OS05B10_HDR_ENABLE 0x04
+
#define OS05B10_LINK_FREQ_600MHZ (600 * HZ_PER_MHZ)
static const struct v4l2_rect os05b10_native_area = {
@@ -77,30 +122,25 @@ static const char * const os05b10_supply_name[] = {
};
static const struct cci_reg_sequence os05b10_common_regs[] = {
- { CCI_REG8(0x0301), 0x44 },
- { CCI_REG8(0x0303), 0x02 },
- { CCI_REG8(0x0305), 0x32 },
- { CCI_REG8(0x0306), 0x00 },
- { CCI_REG8(0x0325), 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 },
{ CCI_REG8(0x3002), 0x21 },
- { CCI_REG8(0x3016), 0x72 },
+ { OS05B10_REG_MIPI_SC_CTRL, 0x72 },
{ CCI_REG8(0x301e), 0xb4 },
{ CCI_REG8(0x301f), 0xd0 },
{ CCI_REG8(0x3021), 0x03 },
- { CCI_REG8(0x3022), 0x01 },
+ { OS05B10_REG_MIPI_SC_CTRL_1, 0x01 },
{ CCI_REG8(0x3107), 0xa1 },
{ CCI_REG8(0x3108), 0x7d },
{ CCI_REG8(0x3109), 0xfc },
{ CCI_REG8(0x3503), 0x88 },
- { CCI_REG8(0x350a), 0x04 },
- { CCI_REG8(0x350b), 0x00 },
- { CCI_REG8(0x350c), 0x00 },
- { CCI_REG8(0x350d), 0x80 },
- { CCI_REG8(0x350e), 0x04 },
- { CCI_REG8(0x350f), 0x00 },
- { CCI_REG8(0x3510), 0x00 },
- { CCI_REG8(0x3511), 0x00 },
- { CCI_REG8(0x3512), 0x20 },
+ { 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 },
@@ -274,34 +314,25 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x37f5), 0x00 },
{ CCI_REG8(0x37f6), 0x00 },
{ CCI_REG8(0x37f7), 0x00 },
- { CCI_REG8(0x3800), 0x01 },
- { CCI_REG8(0x3801), 0x30 },
- { CCI_REG8(0x3802), 0x00 },
- { CCI_REG8(0x3803), 0x00 },
- { CCI_REG8(0x3804), 0x0b },
- { CCI_REG8(0x3805), 0x5f },
- { CCI_REG8(0x3806), 0x07 },
- { CCI_REG8(0x3807), 0xa7 },
- { CCI_REG8(0x3808), 0x0a },
- { CCI_REG8(0x3809), 0x20 },
- { CCI_REG8(0x380a), 0x07 },
- { CCI_REG8(0x380b), 0x98 },
- { CCI_REG8(0x380c), 0x06 },
- { CCI_REG8(0x380d), 0xd0 },
- { CCI_REG8(0x3810), 0x00 },
- { CCI_REG8(0x3811), 0x08 },
- { CCI_REG8(0x3812), 0x00 },
- { CCI_REG8(0x3813), 0x08 },
- { CCI_REG8(0x3814), 0x01 },
- { CCI_REG8(0x3815), 0x01 },
- { CCI_REG8(0x3816), 0x01 },
- { CCI_REG8(0x3817), 0x01 },
+ { 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 },
- { CCI_REG8(0x3820), 0x88 },
- { CCI_REG8(0x3821), 0x00 },
+ { OS05B10_REG_FORMAT1, 0x88 },
+ { OS05B10_REG_FORMAT2, 0x00 },
{ CCI_REG8(0x3822), 0x12 },
{ CCI_REG8(0x3823), 0x08 },
{ CCI_REG8(0x3824), 0x00 },
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 03/13] media: i2c: os05b10: split common and mode-specific init registers
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
2026-03-06 12:32 ` [PATCH 01/13] media: i2c: os05b10: drop unused group-hold programming Tarang Raval
2026-03-06 12:32 ` [PATCH 02/13] media: i2c: os05b10: add register definitions and use them in init table Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 04/13] media: i2c: os05b10: add V4L2 digital gain control Tarang Raval
` (9 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
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@siliconsignals.io>
---
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
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 04/13] media: i2c: os05b10: add V4L2 digital gain control
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (2 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 03/13] media: i2c: os05b10: split common and mode-specific init registers Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 05/13] media: i2c: os05b10: Add H/V flip support Tarang Raval
` (8 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Stop programming digital gain in the common register sequence and expose it as
a V4L2_CID_DIGITAL_GAIN control. Initialize the new control and handle writes
in the ctrl callback.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index b1d9eaa473e4..a9a8000a8154 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -129,7 +129,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ 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 },
@@ -550,6 +549,10 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
ret = cci_write(os05b10->cci, OS05B10_REG_ANALOG_GAIN,
ctrl->val, NULL);
break;
+ case V4L2_CID_DIGITAL_GAIN:
+ ret = cci_write(os05b10->cci, OS05B10_REG_DIGITAL_GAIN,
+ ctrl->val, NULL);
+ break;
case V4L2_CID_EXPOSURE:
ret = cci_write(os05b10->cci, OS05B10_REG_EXPOSURE,
ctrl->val, NULL);
@@ -926,7 +929,7 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
int ret;
ctrl_hdlr = &os05b10->handler;
- v4l2_ctrl_handler_init(ctrl_hdlr, 8);
+ v4l2_ctrl_handler_init(ctrl_hdlr, 9);
pixel_rate = os05b10_pixel_rate(os05b10, mode);
v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops, V4L2_CID_PIXEL_RATE,
@@ -968,6 +971,10 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
OS05B10_ANALOG_GAIN_STEP,
OS05B10_ANALOG_GAIN_DEFAULT);
+ v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+ OS05B10_DIGITAL_GAIN_MIN, OS05B10_DIGITAL_GAIN_MAX,
+ OS05B10_DIGITAL_GAIN_STEP,OS05B10_DIGITAL_GAIN_DEFAULT);
+
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
dev_err(os05b10->dev, "control init failed (%d)\n", ret);
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 05/13] media: i2c: os05b10: Add H/V flip support
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (3 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 04/13] media: i2c: os05b10: add V4L2 digital gain control Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 06/13] media: i2c: os05b10: Add test pattern options Tarang Raval
` (7 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Add HFLIP and VFLIP controls, lock them while streaming,
and update the reported Bayer format based on the flip state.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 58 ++++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index a9a8000a8154..009097a00eff 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -96,6 +96,10 @@
#define OS05B10_MIRROR BIT(3)
#define OS05B10_FLIP GENMASK(5, 4)
+#define OS05B10_REG_ANALOG_FLIP CCI_REG8(0x3716)
+#define OS05B10_FLIP_ENABLE 0x04
+#define OS05B10_FLIP_DISABLE 0x24
+
#define OS05B10_REG_FORMAT2 CCI_REG8(0x3821)
#define OS05B10_HDR_ENABLE 0x04
@@ -232,7 +236,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x370f), 0x1c },
{ CCI_REG8(0x3710), 0x00 },
{ CCI_REG8(0x3713), 0x00 },
- { CCI_REG8(0x3716), 0x24 },
{ CCI_REG8(0x371a), 0x1e },
{ CCI_REG8(0x3724), 0x09 },
{ CCI_REG8(0x3725), 0xb2 },
@@ -466,6 +469,8 @@ struct os05b10 {
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *gain;
struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *hflip;
u32 link_freq_index;
u32 data_lanes;
@@ -514,6 +519,18 @@ static inline struct os05b10 *to_os05b10(struct v4l2_subdev *sd)
return container_of_const(sd, struct os05b10, sd);
};
+static u32 os05b10_get_format_code(struct os05b10 *os05b10)
+{
+ static const u32 codes[2][2] = {
+ { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, },
+ };
+
+ u32 code = codes[os05b10->vflip->val][os05b10->hflip->val];
+
+ return code;
+}
+
static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct os05b10 *os05b10 = container_of_const(ctrl->handler,
@@ -557,6 +574,20 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
ret = cci_write(os05b10->cci, OS05B10_REG_EXPOSURE,
ctrl->val, NULL);
break;
+ case V4L2_CID_HFLIP:
+ case V4L2_CID_VFLIP:
+ ret = cci_update_bits(os05b10->cci, OS05B10_REG_FORMAT1,
+ GENMASK(5,3), os05b10->hflip->val << 3 |
+ os05b10->vflip->val << 5 |
+ os05b10->vflip->val << 4, NULL);
+ if (ret)
+ return ret;
+
+ ret = cci_write(os05b10->cci, OS05B10_REG_ANALOG_FLIP,
+ (os05b10->vflip->val ==1) ?
+ OS05B10_FLIP_ENABLE : OS05B10_FLIP_DISABLE,
+ NULL);
+ break;
default:
ret = -EINVAL;
break;
@@ -571,10 +602,12 @@ static int os05b10_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
+ struct os05b10 *os05b10 = to_os05b10(sd);
+
if (code->index >= ARRAY_SIZE(os05b10_mbus_codes))
return -EINVAL;
- code->code = os05b10_mbus_codes[code->index];
+ code->code = os05b10_get_format_code(os05b10);
return 0;
}
@@ -713,6 +746,9 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
if (ret)
goto err_rpm_put;
+ __v4l2_ctrl_grab(os05b10->vflip, true);
+ __v4l2_ctrl_grab(os05b10->hflip, true);
+
return 0;
err_rpm_put:
@@ -733,6 +769,9 @@ static int os05b10_disable_streams(struct v4l2_subdev *sd,
if (ret)
dev_err(os05b10->dev, "failed to set stream off\n");
+ __v4l2_ctrl_grab(os05b10->vflip, false);
+ __v4l2_ctrl_grab(os05b10->hflip, false);
+
pm_runtime_put(os05b10->dev);
return 0;
@@ -741,6 +780,7 @@ static int os05b10_disable_streams(struct v4l2_subdev *sd,
static int os05b10_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
+ struct os05b10 *os05b10 = to_os05b10(sd);
struct v4l2_mbus_framefmt *format;
const struct os05b10_mode *mode;
@@ -748,7 +788,7 @@ static int os05b10_init_state(struct v4l2_subdev *sd,
format = v4l2_subdev_state_get_format(state, 0);
mode = &supported_modes_10bit[0];
- format->code = MEDIA_BUS_FMT_SBGGR10_1X10;
+ format->code = os05b10_get_format_code(os05b10);
/* Update image pad formate */
format->width = mode->width;
@@ -929,7 +969,7 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
int ret;
ctrl_hdlr = &os05b10->handler;
- v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+ v4l2_ctrl_handler_init(ctrl_hdlr, 11);
pixel_rate = os05b10_pixel_rate(os05b10, mode);
v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops, V4L2_CID_PIXEL_RATE,
@@ -975,6 +1015,16 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
OS05B10_DIGITAL_GAIN_MIN, OS05B10_DIGITAL_GAIN_MAX,
OS05B10_DIGITAL_GAIN_STEP,OS05B10_DIGITAL_GAIN_DEFAULT);
+ os05b10->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ if (os05b10->hflip)
+ os05b10->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+ os05b10->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ if (os05b10->vflip)
+ os05b10->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
dev_err(os05b10->dev, "control init failed (%d)\n", ret);
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 06/13] media: i2c: os05b10: Add test pattern options
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (4 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 05/13] media: i2c: os05b10: Add H/V flip support Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 07/13] media: i2c: os05b10: add 12-bit RAW mode support Tarang Raval
` (6 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Add V4L2_CID_TEST_PATTERN support with multiple sensor test-pattern modes
and program them via register 0x5080. Drop the fixed 0x5080 setting from the
common register sequence so the pattern is selected only through the control.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 55 +++++++++++++++++++++++++++++++++++--
1 file changed, 53 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 009097a00eff..fbc191e1d505 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -103,6 +103,17 @@
#define OS05B10_REG_FORMAT2 CCI_REG8(0x3821)
#define OS05B10_HDR_ENABLE 0x04
+#define OS05B10_REG_PRE_ISP_20_0 CCI_REG8(0x5080)
+#define OS05B10_DISABLED 0x00
+#define OS05B10_COLOR_BAR_1 0x80
+#define OS05B10_COLOR_BAR_2 0x84
+#define OS05B10_COLOR_BAR_3 0x88
+#define OS05B10_COLOR_BAR_4 0x8c
+#define OS05B10_COLOR_SQUARE 0x82
+#define OS05B10_BW_SQUARE 0x92
+#define OS05B10_TRANSPARENT_EFFECT 0xa0
+#define OS05B10_ROLLING_BAR_EFFECT 0xc0
+
#define OS05B10_LINK_FREQ_600MHZ (600 * HZ_PER_MHZ)
static const struct v4l2_rect os05b10_native_area = {
@@ -396,7 +407,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ CCI_REG8(0x5004), 0x00 },
{ CCI_REG8(0x5005), 0x0e },
{ CCI_REG8(0x5036), 0x00 },
- { CCI_REG8(0x5080), 0x04 },
{ CCI_REG8(0x5082), 0x00 },
{ CCI_REG8(0x5180), 0x00 },
{ CCI_REG8(0x5181), 0x10 },
@@ -514,6 +524,30 @@ static const u32 os05b10_mbus_codes[] = {
MEDIA_BUS_FMT_SBGGR10_1X10,
};
+static const char * const os05b10_test_pattern_menu[] = {
+ "Disabled",
+ "colour bar type 1",
+ "colour bar type 2",
+ "colour bar type 3",
+ "colour bar type 4",
+ "color square",
+ "black-white square",
+ "transparent effect",
+ "rolling bar effect",
+};
+
+static const int os05b10_tp_val[] = {
+ OS05B10_DISABLED,
+ OS05B10_COLOR_BAR_1,
+ OS05B10_COLOR_BAR_2,
+ OS05B10_COLOR_BAR_3,
+ OS05B10_COLOR_BAR_4,
+ OS05B10_COLOR_SQUARE,
+ OS05B10_BW_SQUARE,
+ OS05B10_TRANSPARENT_EFFECT,
+ OS05B10_ROLLING_BAR_EFFECT,
+};
+
static inline struct os05b10 *to_os05b10(struct v4l2_subdev *sd)
{
return container_of_const(sd, struct os05b10, sd);
@@ -531,6 +565,15 @@ static u32 os05b10_get_format_code(struct os05b10 *os05b10)
return code;
}
+static int os05b10_update_test_pattern(struct os05b10 *os05b10, u32 pattern)
+{
+ if (pattern >= ARRAY_SIZE(os05b10_test_pattern_menu))
+ return -EINVAL;
+
+ return cci_write(os05b10->cci, OS05B10_REG_PRE_ISP_20_0,
+ os05b10_tp_val[pattern], NULL);
+}
+
static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct os05b10 *os05b10 = container_of_const(ctrl->handler,
@@ -588,6 +631,9 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
OS05B10_FLIP_ENABLE : OS05B10_FLIP_DISABLE,
NULL);
break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = os05b10_update_test_pattern(os05b10, ctrl->val);
+ break;
default:
ret = -EINVAL;
break;
@@ -969,7 +1015,7 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
int ret;
ctrl_hdlr = &os05b10->handler;
- v4l2_ctrl_handler_init(ctrl_hdlr, 11);
+ v4l2_ctrl_handler_init(ctrl_hdlr, 12);
pixel_rate = os05b10_pixel_rate(os05b10, mode);
v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops, V4L2_CID_PIXEL_RATE,
@@ -1025,6 +1071,11 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
if (os05b10->vflip)
os05b10->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &os05b10_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(os05b10_test_pattern_menu) - 1,
+ 0, 0, os05b10_test_pattern_menu);
+
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
dev_err(os05b10->dev, "control init failed (%d)\n", ret);
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 07/13] media: i2c: os05b10: add 12-bit RAW mode support
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (5 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 06/13] media: i2c: os05b10: Add test pattern options Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 08/13] media: i2c: os05b10: update pixel rate on 10/12-bit mode switch Tarang Raval
` (5 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Expose a 12-bit Bayer output option in the OS05B10 V4L2 sub-device driver.
Add a 12-bit mode table alongside the existing 10-bit mode, extend the
enumerated mbus codes to include RAW12, and select the correct mode table
based on the requested mbus format in enum_frame_size and stream enable.
Also move OS05B10_REG_MIPI_SC_CTRL_1 programming out of the common register
list and program it at stream-on depending on the selected mode bpp (10/12).
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 97 +++++++++++++++++++++++++++++++------
1 file changed, 81 insertions(+), 16 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index fbc191e1d505..d51b7d18d28a 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -143,7 +143,6 @@ static const struct cci_reg_sequence os05b10_common_regs[] = {
{ 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_ANALOG_GAIN_SHORT, 0x0080 },
{ OS05B10_REG_DIGITAL_GAIN_SHORT, 0x0400 },
{ OS05B10_REG_EXPOSURE_SHORT, 0x000020 },
@@ -501,6 +500,21 @@ struct os05b10_mode {
struct os05b10_reg_list reg_list;
};
+static const struct os05b10_mode supported_modes_12bit[] = {
+ {
+ .width = 2592,
+ .height = 1944,
+ .vts = 2007,
+ .hts = 1744,
+ .exp = 1900,
+ .bpp = 12,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_2592_1944_regs),
+ .regs = mode_2592_1944_regs,
+ },
+ },
+};
+
static const struct os05b10_mode supported_modes_10bit[] = {
{
.width = 2592,
@@ -522,6 +536,7 @@ static const s64 link_frequencies[] = {
static const u32 os05b10_mbus_codes[] = {
MEDIA_BUS_FMT_SBGGR10_1X10,
+ MEDIA_BUS_FMT_SBGGR12_1X12,
};
static const char * const os05b10_test_pattern_menu[] = {
@@ -553,12 +568,19 @@ static inline struct os05b10 *to_os05b10(struct v4l2_subdev *sd)
return container_of_const(sd, struct os05b10, sd);
};
-static u32 os05b10_get_format_code(struct os05b10 *os05b10)
+static u32 os05b10_get_format_code(struct os05b10 *os05b10, u8 bpp)
{
- static const u32 codes[2][2] = {
- { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, },
- { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, },
- };
+ static const u32 codes_12[2][2] = {
+ { MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SGBRG12_1X12, },
+ { MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SRGGB12_1X12, },
+ };
+
+ static const u32 codes_10[2][2] = {
+ { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, },
+ };
+
+ const u32 (*codes)[2] = (bpp == 12) ? codes_12 : codes_10;
u32 code = codes[os05b10->vflip->val][os05b10->hflip->val];
@@ -653,8 +675,8 @@ static int os05b10_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index >= ARRAY_SIZE(os05b10_mbus_codes))
return -EINVAL;
- code->code = os05b10_get_format_code(os05b10);
-
+ code->code = os05b10_get_format_code(os05b10,
+ (code->index == 1) ? 12 : 10);
return 0;
}
@@ -683,15 +705,42 @@ static int os05b10_set_framing_limits(struct os05b10 *os05b10,
OS05B10_EXPOSURE_STEP, mode->exp);
}
+static inline void get_mode_table(unsigned int code,
+ const struct os05b10_mode **mode_list,
+ unsigned int *num_modes)
+{
+ switch (code) {
+ case MEDIA_BUS_FMT_SBGGR12_1X12:
+ *mode_list = supported_modes_12bit;
+ *num_modes = ARRAY_SIZE(supported_modes_12bit);
+ break;
+
+ case MEDIA_BUS_FMT_SBGGR10_1X10:
+ *mode_list = supported_modes_10bit;
+ *num_modes = ARRAY_SIZE(supported_modes_10bit);
+ break;
+ default:
+ *mode_list = NULL;
+ *num_modes = 0;
+ break;
+ }
+}
+
static int os05b10_set_pad_format(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{
- const struct os05b10_mode *mode = &supported_modes_10bit[0];
struct os05b10 *os05b10 = to_os05b10(sd);
+ const struct os05b10_mode *mode_list;
struct v4l2_mbus_framefmt *format;
+ const struct os05b10_mode *mode;
+ unsigned int num_modes;
int ret;
+ get_mode_table(fmt->format.code, &mode_list, &num_modes);
+ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
+ fmt->format.width, fmt->format.height);
+
fmt->format.width = mode->width;
fmt->format.height = mode->height;
fmt->format.field = V4L2_FIELD_NONE;
@@ -730,16 +779,22 @@ static int os05b10_get_selection(struct v4l2_subdev *sd,
}
}
+
static int os05b10_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse)
{
- if (fse->index >= ARRAY_SIZE(supported_modes_10bit))
+ const struct os05b10_mode *mode_list;
+ unsigned int num_modes;
+
+ get_mode_table(fse->code, &mode_list, &num_modes);
+
+ if (fse->index >= num_modes)
return -EINVAL;
- fse->min_width = supported_modes_10bit[fse->index].width;
+ fse->min_width = mode_list[fse->index].width;
fse->max_width = fse->min_width;
- fse->min_height = supported_modes_10bit[fse->index].height;
+ fse->min_height = mode_list[fse->index].height;
fse->max_height = fse->min_height;
return 0;
@@ -752,13 +807,15 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
struct os05b10 *os05b10 = to_os05b10(sd);
const struct os05b10_reg_list *reg_list;
const struct v4l2_mbus_framefmt *fmt;
+ const struct os05b10_mode *mode_list;
const struct os05b10_mode *mode;
+ unsigned int num_modes;
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);
+ get_mode_table(fmt->code, &mode_list, &num_modes);
+ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
+ fmt->width, fmt->height);
ret = pm_runtime_resume_and_get(os05b10->dev);
if (ret < 0)
@@ -772,6 +829,14 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
goto err_rpm_put;
}
+ ret = cci_write(os05b10->cci, OS05B10_REG_MIPI_SC_CTRL_1,
+ (mode->bpp == 12) ? OS05B10_12BIT_MODE :
+ OS05B10_10BIT_MODE, NULL);
+ if (ret) {
+ dev_err(os05b10->dev, "failed to write pixel bit registers\n");
+ goto err_rpm_put;
+ }
+
/* Write sensor mode registers */
reg_list = &mode->reg_list;
ret = cci_multi_reg_write(os05b10->cci, reg_list->regs,
@@ -834,7 +899,7 @@ static int os05b10_init_state(struct v4l2_subdev *sd,
format = v4l2_subdev_state_get_format(state, 0);
mode = &supported_modes_10bit[0];
- format->code = os05b10_get_format_code(os05b10);
+ format->code = os05b10_get_format_code(os05b10, 10);
/* Update image pad formate */
format->width = mode->width;
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 08/13] media: i2c: os05b10: update pixel rate on 10/12-bit mode switch
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (6 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 07/13] media: i2c: os05b10: add 12-bit RAW mode support Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:32 ` [PATCH 09/13] media: i2c: os05b10: Add 1080p and 2x2 binning 720p modes Tarang Raval
` (4 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
After adding 12-bit RAW support, the pixel rate depends on the selected
mode bpp. Store the V4L2_CID_PIXEL_RATE control pointer and update its
range/value when the mode changes so 10/12-bit switching reports the
correct pixel rate.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 41 ++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index d51b7d18d28a..5ffc7aef0ed1 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -474,6 +474,7 @@ struct os05b10 {
/* V4L2 Controls */
struct v4l2_ctrl_handler handler;
struct v4l2_ctrl *link_freq;
+ struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *gain;
@@ -680,12 +681,35 @@ static int os05b10_enum_mbus_code(struct v4l2_subdev *sd,
return 0;
}
+static u64 os05b10_pixel_rate(struct os05b10 *os05b10,
+ const struct os05b10_mode *mode)
+{
+ u64 link_freq = link_frequencies[os05b10->link_freq_index];
+ u64 pixel_rate = div_u64(link_freq * 2 * os05b10->data_lanes, mode->bpp);
+
+ dev_dbg(os05b10->dev,
+ "link_freq=%llu bpp=%u lanes=%u pixel_rate=%llu\n",
+ link_freq, mode->bpp, os05b10->data_lanes, pixel_rate);
+
+ return pixel_rate;
+}
+
static int os05b10_set_framing_limits(struct os05b10 *os05b10,
const struct os05b10_mode *mode)
{
+ u64 pixel_rate = os05b10_pixel_rate(os05b10, mode);
u32 hblank, vblank, vblank_max, max_exp;
int ret;
+ ret = __v4l2_ctrl_modify_range(os05b10->pixel_rate, pixel_rate,
+ pixel_rate, 1, pixel_rate);
+ if (ret)
+ return ret;
+
+ ret = __v4l2_ctrl_s_ctrl_int64(os05b10->pixel_rate, pixel_rate);
+ if (ret)
+ return ret;
+
hblank = mode->hts - mode->width;
ret = __v4l2_ctrl_modify_range(os05b10->hblank, hblank, hblank, 1,
hblank);
@@ -1058,18 +1082,6 @@ static int os05b10_parse_endpoint(struct os05b10 *os05b10)
return ret;
}
-static u64 os05b10_pixel_rate(struct os05b10 *os05b10,
- const struct os05b10_mode *mode)
-{
- u64 link_freq = link_frequencies[os05b10->link_freq_index];
- u64 pixel_rate = div_u64(link_freq * 2 * os05b10->data_lanes, mode->bpp);
-
- dev_dbg(os05b10->dev,
- "link_freq=%llu bpp=%u lanes=%u pixel_rate=%llu\n",
- link_freq, mode->bpp, os05b10->data_lanes, pixel_rate);
-
- return pixel_rate;
-}
static int os05b10_init_controls(struct os05b10 *os05b10)
{
@@ -1083,8 +1095,9 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
v4l2_ctrl_handler_init(ctrl_hdlr, 12);
pixel_rate = os05b10_pixel_rate(os05b10, mode);
- v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops, V4L2_CID_PIXEL_RATE,
- pixel_rate, pixel_rate, 1, pixel_rate);
+ os05b10->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &os05b10_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, pixel_rate,
+ pixel_rate, 1, pixel_rate);
os05b10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &os05b10_ctrl_ops,
V4L2_CID_LINK_FREQ,
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 09/13] media: i2c: os05b10: Add 1080p and 2x2 binning 720p modes
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (7 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 08/13] media: i2c: os05b10: update pixel rate on 10/12-bit mode switch Tarang Raval
@ 2026-03-06 12:32 ` Tarang Raval
2026-03-06 12:33 ` [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch Tarang Raval
` (3 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:32 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Add support for 1920x1080 and 1280x720 resolutions.
The 1280x720 mode uses 2x2 binning.
Both 10-bit and 12-bit pixel formats are supported.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 121 ++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 5ffc7aef0ed1..d8d776de5f35 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -461,6 +461,78 @@ static const struct cci_reg_sequence mode_2592_1944_regs[] = {
{ CCI_REG8(0x4837), 0x12 },
};
+static const struct cci_reg_sequence mode_1920_1080_regs[] = {
+ { OS05B10_REG_X_ADDR_START, 0x0280 },
+ { OS05B10_REG_Y_ADDR_START, 0x01b4 },
+ { OS05B10_REG_X_ADDR_END, 0x0a0f },
+ { OS05B10_REG_Y_ADDR_END, 0x05f3 },
+ { OS05B10_REG_X_OUTPUT_SIZE, 0x0780 },
+ { OS05B10_REG_Y_OUTPUT_SIZE, 0x0438 },
+ { 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), 0x03 },
+ { CCI_REG8(0x3d8c), 0x71 },
+ { CCI_REG8(0x3f03), 0x08 },
+ { CCI_REG8(0x4008), 0x02 },
+ { CCI_REG8(0x4009), 0x0d },
+ { CCI_REG8(0x400a), 0x02 },
+ { CCI_REG8(0x4041), 0x07 },
+ { CCI_REG8(0x4505), 0xc4 },
+ { CCI_REG8(0x4837), 0x0d },
+};
+
+static const struct cci_reg_sequence mode_1280_720_regs[] = {
+ { OS05B10_REG_X_ADDR_START, 0x0140 },
+ { OS05B10_REG_Y_ADDR_START, 0x00fc },
+ { OS05B10_REG_X_ADDR_END, 0x0b4f },
+ { OS05B10_REG_Y_ADDR_END, 0x06ab },
+ { OS05B10_REG_X_OUTPUT_SIZE, 0x0500 },
+ { OS05B10_REG_Y_OUTPUT_SIZE, 0x02d0 },
+ { OS05B10_REG_HTS, 0x0368 },
+ { OS05B10_REG_ISP_X_WIN, 0x0004 },
+ { OS05B10_REG_ISP_Y_WIN, 0x0004 },
+ { OS05B10_REG_X_INC_ODD, 0x03 },
+ { OS05B10_REG_X_INC_EVEN, 0x01 },
+ { OS05B10_REG_Y_INC_ODD, 0x03 },
+ { OS05B10_REG_Y_INC_EVEN, 0x01 },
+ { OS05B10_REG_FORMAT1, 0x8b },
+ { OS05B10_REG_FORMAT2, 0x00 },
+ { CCI_REG8(0x3610), 0x57 },
+ { CCI_REG8(0x3620), 0x01 },
+ { CCI_REG8(0x3662), 0x08 },
+ { CCI_REG8(0x3714), 0x28 },
+ { CCI_REG8(0x373f), 0xa0 },
+ { CCI_REG8(0x37bf), 0x05 },
+ { CCI_REG8(0x37c2), 0x14 },
+ { CCI_REG8(0x37d9), 0x04 },
+ { CCI_REG8(0x3832), 0x00 },
+ { CCI_REG8(0x3c86), 0x03 },
+ { CCI_REG8(0x3d8c), 0x71 },
+ { CCI_REG8(0x3f03), 0x1d },
+ { CCI_REG8(0x4008), 0x01 },
+ { CCI_REG8(0x4009), 0x06 },
+ { CCI_REG8(0x400a), 0x02 },
+ { CCI_REG8(0x4041), 0x03 },
+ { CCI_REG8(0x4505), 0xe4 },
+ { CCI_REG8(0x4837), 0x0d },
+};
+
struct os05b10 {
struct device *dev;
struct regmap *cci;
@@ -514,6 +586,31 @@ static const struct os05b10_mode supported_modes_12bit[] = {
.regs = mode_2592_1944_regs,
},
},
+ { /* 40 fps */
+ .width = 1920,
+ .height = 1080,
+ .vts = 1504,
+ .hts = 1744,
+ .exp = 1472,
+ .bpp = 12,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
+ .regs = mode_1920_1080_regs,
+ },
+ },
+ { /* 2x2 binning 120 fps */
+ .width = 1280,
+ .height = 720,
+ .vts = 1003,
+ .hts = 872,
+ .exp = 970,
+ .bpp = 12,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_1280_720_regs),
+ .regs = mode_1280_720_regs,
+ },
+ },
+
};
static const struct os05b10_mode supported_modes_10bit[] = {
@@ -529,6 +626,30 @@ static const struct os05b10_mode supported_modes_10bit[] = {
.regs = mode_2592_1944_regs,
},
},
+ { /* 40 fps */
+ .width = 1920,
+ .height = 1080,
+ .vts = 1504,
+ .hts = 1744,
+ .exp = 1472,
+ .bpp = 10,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
+ .regs = mode_1920_1080_regs,
+ },
+ },
+ { /* 2x2 binning 120 fps */
+ .width = 1280,
+ .height = 720,
+ .vts = 1003,
+ .hts = 872,
+ .exp = 970,
+ .bpp = 10,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mode_1280_720_regs),
+ .regs = mode_1280_720_regs,
+ },
+ },
};
static const s64 link_frequencies[] = {
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (8 preceding siblings ...)
2026-03-06 12:32 ` [PATCH 09/13] media: i2c: os05b10: Add 1080p and 2x2 binning 720p modes Tarang Raval
@ 2026-03-06 12:33 ` Tarang Raval
2026-03-06 13:35 ` Sakari Ailus
2026-03-06 12:33 ` [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls Tarang Raval
` (2 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:33 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
When switching sensor modes, V4L2 updates the vblank range/default but
keeps the previous current value, leaving vertical blanking unchanged.
Update the vblank and exposure control values to the new mode defaults
after adjusting the ranges.
Clamp the exposure default value to the new maximum to prevent -ERANGE
during format changes.
Also use pm_runtime_get_if_active() in set_ctrl() to avoid touching the
sensor when runtime suspended.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index d8d776de5f35..4601e33b7e8f 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -732,16 +732,15 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->id == V4L2_CID_VBLANK) {
/* Honour the VBLANK limits when setting exposure. */
s64 max = fmt->height + ctrl->val - OS05B10_EXPOSURE_MARGIN;
-
+ s64 def = min_t (s64, max, os05b10->exposure->default_value);
ret = __v4l2_ctrl_modify_range(os05b10->exposure,
os05b10->exposure->minimum, max,
- os05b10->exposure->step,
- os05b10->exposure->default_value);
+ os05b10->exposure->step, def);
if (ret)
return ret;
}
- if (pm_runtime_get_if_in_use(os05b10->dev) == 0)
+ if (pm_runtime_get_if_active(os05b10->dev) == 0)
return 0;
switch (ctrl->id) {
@@ -844,10 +843,18 @@ static int os05b10_set_framing_limits(struct os05b10 *os05b10,
if (ret)
return ret;
+ ret = __v4l2_ctrl_s_ctrl(os05b10->vblank, vblank);
+ if (ret)
+ return ret;
+
max_exp = mode->vts - OS05B10_EXPOSURE_MARGIN;
- return __v4l2_ctrl_modify_range(os05b10->exposure,
- OS05B10_EXPOSURE_MIN, max_exp,
- OS05B10_EXPOSURE_STEP, mode->exp);
+ ret = __v4l2_ctrl_modify_range(os05b10->exposure,
+ OS05B10_EXPOSURE_MIN, max_exp,
+ OS05B10_EXPOSURE_STEP, mode->exp);
+ if (ret)
+ return ret;
+
+ return __v4l2_ctrl_s_ctrl(os05b10->exposure, mode->exp);
}
static inline void get_mode_table(unsigned int code,
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (9 preceding siblings ...)
2026-03-06 12:33 ` [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch Tarang Raval
@ 2026-03-06 12:33 ` Tarang Raval
2026-03-06 13:36 ` Sakari Ailus
2026-03-24 16:31 ` Tarang Raval
2026-03-06 12:33 ` [PATCH 12/13] media: i2c: os05b10: Rename vmax variable in VBLANK control Tarang Raval
2026-03-06 12:33 ` [PATCH 13/13] media: i2c: os05b10: add 2-lane support Tarang Raval
12 siblings, 2 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:33 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
the ACTIVE format. As a result, the VBLANK control handler uses the old
height when recalculating exposure limits, causing -ERANGE when switching
to a larger resolution.
Update the ACTIVE format before adjusting framing controls so control
callbacks use the correct dimensions.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 4601e33b7e8f..476dbcb49351 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
format = v4l2_subdev_state_get_format(sd_state, 0);
+ *format = fmt->format;
+
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
ret = os05b10_set_framing_limits(os05b10, mode);
if (ret)
return ret;
}
- *format = fmt->format;
-
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 12/13] media: i2c: os05b10: Rename vmax variable in VBLANK control
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (10 preceding siblings ...)
2026-03-06 12:33 ` [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls Tarang Raval
@ 2026-03-06 12:33 ` Tarang Raval
2026-03-06 12:33 ` [PATCH 13/13] media: i2c: os05b10: add 2-lane support Tarang Raval
12 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:33 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
The VBLANK control programs the sensor VTS register. Rename the local
variable from vmax to vts to match the register meaning and improve
readability.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 476dbcb49351..1393c7b5d860 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -724,7 +724,7 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
struct os05b10, handler);
struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *fmt;
- int vmax, ret;
+ int vts, ret;
state = v4l2_subdev_get_locked_active_state(&os05b10->sd);
fmt = v4l2_subdev_state_get_format(state, 0);
@@ -745,8 +745,8 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_VBLANK:
- vmax = fmt->height + ctrl->val;
- ret = cci_write(os05b10->cci, OS05B10_REG_VTS, vmax, NULL);
+ vts = fmt->height + ctrl->val;
+ ret = cci_write(os05b10->cci, OS05B10_REG_VTS, vts, NULL);
break;
case V4L2_CID_ANALOGUE_GAIN:
ret = cci_write(os05b10->cci, OS05B10_REG_ANALOG_GAIN,
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 13/13] media: i2c: os05b10: add 2-lane support
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
` (11 preceding siblings ...)
2026-03-06 12:33 ` [PATCH 12/13] media: i2c: os05b10: Rename vmax variable in VBLANK control Tarang Raval
@ 2026-03-06 12:33 ` Tarang Raval
2026-03-07 1:56 ` kernel test robot
12 siblings, 1 reply; 23+ messages in thread
From: Tarang Raval @ 2026-03-06 12:33 UTC (permalink / raw)
To: sakari.ailus
Cc: mehdi.djait, Tarang Raval, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Add support for 2-lane.
Update link-frequency handling to select 750 MHz for 2-lane and 600 MHz for
4-lane, and adjust pixel rate computation accordingly. Extend endpoint
parsing to accept 2 or 4 data lanes.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
---
drivers/media/i2c/os05b10.c | 94 ++++++++++++++++++++++++++++---------
1 file changed, 71 insertions(+), 23 deletions(-)
diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 1393c7b5d860..7107a69157e8 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -114,7 +114,8 @@
#define OS05B10_TRANSPARENT_EFFECT 0xa0
#define OS05B10_ROLLING_BAR_EFFECT 0xc0
-#define OS05B10_LINK_FREQ_600MHZ (600 * HZ_PER_MHZ)
+#define OS05B10_LINK_FREQ_4LANE (600 * HZ_PER_MHZ)
+#define OS05B10_LINK_FREQ_2LANE (750 * HZ_PER_MHZ)
static const struct v4l2_rect os05b10_native_area = {
.top = 0,
@@ -137,12 +138,6 @@ 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_MIPI_SC_CTRL, 0x72 },
{ OS05B10_REG_ANALOG_GAIN_SHORT, 0x0080 },
{ OS05B10_REG_DIGITAL_GAIN_SHORT, 0x0400 },
{ OS05B10_REG_EXPOSURE_SHORT, 0x000020 },
@@ -533,6 +528,24 @@ static const struct cci_reg_sequence mode_1280_720_regs[] = {
{ CCI_REG8(0x4837), 0x0d },
};
+static const struct cci_reg_sequence os05b10_2lane_regs[] = {
+ { OS05B10_REG_PLL_CTRL_01, 0x44 },
+ { OS05B10_REG_PLL_CTRL_03, 0x02 },
+ { OS05B10_REG_PLL_CTRL_05, 0x64 },
+ { OS05B10_REG_PLL_CTRL_06, 0x00 },
+ { OS05B10_REG_PLL_CTRL_25, 0x3b },
+ { OS05B10_REG_MIPI_SC_CTRL, OS05B10_2_LANE_MODE },
+};
+
+static const struct cci_reg_sequence os05b10_4lane_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_MIPI_SC_CTRL, OS05B10_4_LANE_MODE },
+};
+
struct os05b10 {
struct device *dev;
struct regmap *cci;
@@ -652,8 +665,12 @@ static const struct os05b10_mode supported_modes_10bit[] = {
},
};
-static const s64 link_frequencies[] = {
- OS05B10_LINK_FREQ_600MHZ,
+static const s64 link_frequencies_4lane[] = {
+ OS05B10_LINK_FREQ_4LANE,
+};
+
+static const s64 link_frequencies_2lane[] = {
+ OS05B10_LINK_FREQ_2LANE,
};
static const u32 os05b10_mbus_codes[] = {
@@ -804,7 +821,9 @@ static int os05b10_enum_mbus_code(struct v4l2_subdev *sd,
static u64 os05b10_pixel_rate(struct os05b10 *os05b10,
const struct os05b10_mode *mode)
{
- u64 link_freq = link_frequencies[os05b10->link_freq_index];
+ u64 link_freq = (os05b10->data_lanes == 2) ?
+ link_frequencies_2lane[os05b10->link_freq_index] :
+ link_frequencies_4lane[os05b10->link_freq_index];
u64 pixel_rate = div_u64(link_freq * 2 * os05b10->data_lanes, mode->bpp);
dev_dbg(os05b10->dev,
@@ -972,6 +991,17 @@ static int os05b10_enable_streams(struct v4l2_subdev *sd,
ret = pm_runtime_resume_and_get(os05b10->dev);
if (ret < 0)
return ret;
+ /* Set pll & mipi lane configuration */
+ if (os05b10->data_lanes == 2)
+ cci_multi_reg_write(os05b10->cci, os05b10_2lane_regs,
+ ARRAY_SIZE(os05b10_2lane_regs), &ret);
+ else
+ cci_multi_reg_write(os05b10->cci, os05b10_4lane_regs,
+ ARRAY_SIZE(os05b10_4lane_regs), &ret);
+ if (ret) {
+ dev_err(os05b10->dev, "failed to write pll & mipi lane registers\n");
+ goto err_rpm_put;
+ }
/* Write common registers */
ret = cci_multi_reg_write(os05b10->cci, os05b10_common_regs,
@@ -1184,22 +1214,39 @@ static int os05b10_parse_endpoint(struct os05b10 *os05b10)
if (ret)
return ret;
- if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4 &&
+ bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
ret = dev_err_probe(os05b10->dev, -EINVAL,
- "only 4 data lanes are supported\n");
+ "4 and 2 data lanes are supported\n");
goto error_out;
}
os05b10->data_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
- ret = v4l2_link_freq_to_bitmap(os05b10->dev, bus_cfg.link_frequencies,
- bus_cfg.nr_of_link_frequencies,
- link_frequencies,
- ARRAY_SIZE(link_frequencies),
- &link_freq_bitmap);
- if (ret) {
- dev_err(os05b10->dev, "only 600MHz frequency is available\n");
- goto error_out;
+ if (os05b10->data_lanes == 2) {
+ ret = v4l2_link_freq_to_bitmap(os05b10->dev,
+ bus_cfg.link_frequencies_2lane,
+ bus_cfg.nr_of_link_frequencies_2lane,
+ link_frequencies_2lane,
+ ARRAY_SIZE(link_frequencies_2lane),
+ &link_freq_bitmap);
+ if (ret) {
+ dev_err(os05b10->dev,
+ "For 2 lane 750MHz frequency is available\n");
+ goto error_out;
+ }
+ } else {
+ ret = v4l2_link_freq_to_bitmap(os05b10->dev,
+ bus_cfg.link_frequencies_4lane,
+ bus_cfg.nr_of_link_frequencies_4lane,
+ link_frequencies_4lane,
+ ARRAY_SIZE(link_frequencies_4lane),
+ &link_freq_bitmap);
+ if (ret) {
+ dev_err(os05b10->dev,
+ "For 4 lane 600MHz frequency is available\n");
+ goto error_out;
+ }
}
os05b10->link_freq_index = __ffs(link_freq_bitmap);
@@ -1229,10 +1276,11 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
os05b10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &os05b10_ctrl_ops,
V4L2_CID_LINK_FREQ,
- ARRAY_SIZE(link_frequencies) - 1,
+ ARRAY_SIZE(link_frequencies_4lane) - 1,
os05b10->link_freq_index,
- link_frequencies);
-
+ (os05b10->data_lanes == 2) ?
+ link_frequencies_2lane :
+ link_frequencies_4lane);
if (os05b10->link_freq)
os05b10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
--
2.34.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch
2026-03-06 12:33 ` [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch Tarang Raval
@ 2026-03-06 13:35 ` Sakari Ailus
2026-03-07 5:28 ` Tarang Raval
0 siblings, 1 reply; 23+ messages in thread
From: Sakari Ailus @ 2026-03-06 13:35 UTC (permalink / raw)
To: Tarang Raval
Cc: mehdi.djait, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Hi Tarang,
On Fri, Mar 06, 2026 at 06:03:00PM +0530, Tarang Raval wrote:
> When switching sensor modes, V4L2 updates the vblank range/default but
> keeps the previous current value, leaving vertical blanking unchanged.
> Update the vblank and exposure control values to the new mode defaults
> after adjusting the ranges.
>
> Clamp the exposure default value to the new maximum to prevent -ERANGE
> during format changes.
>
> Also use pm_runtime_get_if_active() in set_ctrl() to avoid touching the
> sensor when runtime suspended.
>
> Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> ---
> drivers/media/i2c/os05b10.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> index d8d776de5f35..4601e33b7e8f 100644
> --- a/drivers/media/i2c/os05b10.c
> +++ b/drivers/media/i2c/os05b10.c
> @@ -732,16 +732,15 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
> if (ctrl->id == V4L2_CID_VBLANK) {
> /* Honour the VBLANK limits when setting exposure. */
> s64 max = fmt->height + ctrl->val - OS05B10_EXPOSURE_MARGIN;
> -
> + s64 def = min_t (s64, max, os05b10->exposure->default_value);
> ret = __v4l2_ctrl_modify_range(os05b10->exposure,
> os05b10->exposure->minimum, max,
> - os05b10->exposure->step,
> - os05b10->exposure->default_value);
> + os05b10->exposure->step, def);
> if (ret)
> return ret;
> }
>
> - if (pm_runtime_get_if_in_use(os05b10->dev) == 0)
> + if (pm_runtime_get_if_active(os05b10->dev) == 0)
This actually appears to be a bugfix: it was possible to set controls
without them being applied on hardware if the use count was 0 but the
device was still active. I'd consider doing the bugfix separately before
the rest of the patches.
> return 0;
>
> switch (ctrl->id) {
> @@ -844,10 +843,18 @@ static int os05b10_set_framing_limits(struct os05b10 *os05b10,
> if (ret)
> return ret;
>
> + ret = __v4l2_ctrl_s_ctrl(os05b10->vblank, vblank);
> + if (ret)
> + return ret;
> +
> max_exp = mode->vts - OS05B10_EXPOSURE_MARGIN;
> - return __v4l2_ctrl_modify_range(os05b10->exposure,
> - OS05B10_EXPOSURE_MIN, max_exp,
> - OS05B10_EXPOSURE_STEP, mode->exp);
> + ret = __v4l2_ctrl_modify_range(os05b10->exposure,
> + OS05B10_EXPOSURE_MIN, max_exp,
> + OS05B10_EXPOSURE_STEP, mode->exp);
> + if (ret)
> + return ret;
> +
> + return __v4l2_ctrl_s_ctrl(os05b10->exposure, mode->exp);
> }
>
> static inline void get_mode_table(unsigned int code,
--
Kind regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-06 12:33 ` [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls Tarang Raval
@ 2026-03-06 13:36 ` Sakari Ailus
2026-03-07 5:22 ` Tarang Raval
2026-03-24 16:31 ` Tarang Raval
1 sibling, 1 reply; 23+ messages in thread
From: Sakari Ailus @ 2026-03-06 13:36 UTC (permalink / raw)
To: Tarang Raval
Cc: mehdi.djait, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media, linux-kernel
Hi Tarang,
On Fri, Mar 06, 2026 at 06:03:01PM +0530, Tarang Raval wrote:
> os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
> the ACTIVE format. As a result, the VBLANK control handler uses the old
> height when recalculating exposure limits, causing -ERANGE when switching
> to a larger resolution.
>
> Update the ACTIVE format before adjusting framing controls so control
> callbacks use the correct dimensions.
>
> Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> ---
> drivers/media/i2c/os05b10.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> index 4601e33b7e8f..476dbcb49351 100644
> --- a/drivers/media/i2c/os05b10.c
> +++ b/drivers/media/i2c/os05b10.c
> @@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
>
> format = v4l2_subdev_state_get_format(sd_state, 0);
>
> + *format = fmt->format;
> +
> if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> ret = os05b10_set_framing_limits(os05b10, mode);
Does it take a driver bug for this to happen? Presumably? I guess the
result would be somewhat inconsistent state in any case.
> if (ret)
> return ret;
> }
>
> - *format = fmt->format;
> -
> return 0;
> }
>
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 13/13] media: i2c: os05b10: add 2-lane support
2026-03-06 12:33 ` [PATCH 13/13] media: i2c: os05b10: add 2-lane support Tarang Raval
@ 2026-03-07 1:56 ` kernel test robot
0 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2026-03-07 1:56 UTC (permalink / raw)
To: Tarang Raval, sakari.ailus
Cc: oe-kbuild-all, mehdi.djait, Tarang Raval, Himanshu Bhavani,
Elgin Perumbilly, Mauro Carvalho Chehab, linux-media,
linux-kernel
Hi Tarang,
kernel test robot noticed the following build errors:
[auto build test ERROR on sailus-media-tree/master]
[also build test ERROR on linus/master v7.0-rc2 next-20260306]
[cannot apply to sailus-media-tree/streams]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Tarang-Raval/media-i2c-os05b10-drop-unused-group-hold-programming/20260306-212656
base: git://linuxtv.org/sailus/media_tree.git master
patch link: https://lore.kernel.org/r/20260306123304.76722-14-tarang.raval%40siliconsignals.io
patch subject: [PATCH 13/13] media: i2c: os05b10: add 2-lane support
config: openrisc-randconfig-r071-20260307 (https://download.01.org/0day-ci/archive/20260307/202603070920.GtWqPt5Q-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 15.2.0
smatch: v0.5.0-9004-gb810ac53
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260307/202603070920.GtWqPt5Q-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603070920.GtWqPt5Q-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/media/i2c/os05b10.c: In function 'os05b10_parse_endpoint':
>> drivers/media/i2c/os05b10.c:1228:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'link_frequencies_2lane'; did you mean 'link_frequencies'?
1228 | bus_cfg.link_frequencies_2lane,
| ^~~~~~~~~~~~~~~~~~~~~~
| link_frequencies
>> drivers/media/i2c/os05b10.c:1229:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'nr_of_link_frequencies_2lane'; did you mean 'nr_of_link_frequencies'?
1229 | bus_cfg.nr_of_link_frequencies_2lane,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| nr_of_link_frequencies
>> drivers/media/i2c/os05b10.c:1240:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'link_frequencies_4lane'; did you mean 'link_frequencies'?
1240 | bus_cfg.link_frequencies_4lane,
| ^~~~~~~~~~~~~~~~~~~~~~
| link_frequencies
>> drivers/media/i2c/os05b10.c:1241:56: error: 'struct v4l2_fwnode_endpoint' has no member named 'nr_of_link_frequencies_4lane'; did you mean 'nr_of_link_frequencies'?
1241 | bus_cfg.nr_of_link_frequencies_4lane,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| nr_of_link_frequencies
vim +1228 drivers/media/i2c/os05b10.c
1196
1197 static int os05b10_parse_endpoint(struct os05b10 *os05b10)
1198 {
1199 struct v4l2_fwnode_endpoint bus_cfg = {
1200 .bus_type = V4L2_MBUS_CSI2_DPHY
1201 };
1202 unsigned long link_freq_bitmap;
1203 struct fwnode_handle *ep;
1204 int ret;
1205
1206 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(os05b10->dev), 0, 0, 0);
1207 if (!ep) {
1208 dev_err(os05b10->dev, "Failed to get next endpoint\n");
1209 return -EINVAL;
1210 }
1211
1212 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1213 fwnode_handle_put(ep);
1214 if (ret)
1215 return ret;
1216
1217 if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4 &&
1218 bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
1219 ret = dev_err_probe(os05b10->dev, -EINVAL,
1220 "4 and 2 data lanes are supported\n");
1221 goto error_out;
1222 }
1223
1224 os05b10->data_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
1225
1226 if (os05b10->data_lanes == 2) {
1227 ret = v4l2_link_freq_to_bitmap(os05b10->dev,
> 1228 bus_cfg.link_frequencies_2lane,
> 1229 bus_cfg.nr_of_link_frequencies_2lane,
1230 link_frequencies_2lane,
1231 ARRAY_SIZE(link_frequencies_2lane),
1232 &link_freq_bitmap);
1233 if (ret) {
1234 dev_err(os05b10->dev,
1235 "For 2 lane 750MHz frequency is available\n");
1236 goto error_out;
1237 }
1238 } else {
1239 ret = v4l2_link_freq_to_bitmap(os05b10->dev,
> 1240 bus_cfg.link_frequencies_4lane,
> 1241 bus_cfg.nr_of_link_frequencies_4lane,
1242 link_frequencies_4lane,
1243 ARRAY_SIZE(link_frequencies_4lane),
1244 &link_freq_bitmap);
1245 if (ret) {
1246 dev_err(os05b10->dev,
1247 "For 4 lane 600MHz frequency is available\n");
1248 goto error_out;
1249 }
1250 }
1251
1252 os05b10->link_freq_index = __ffs(link_freq_bitmap);
1253
1254 error_out:
1255 v4l2_fwnode_endpoint_free(&bus_cfg);
1256
1257 return ret;
1258 }
1259
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-06 13:36 ` Sakari Ailus
@ 2026-03-07 5:22 ` Tarang Raval
2026-03-09 8:19 ` Tarang Raval
0 siblings, 1 reply; 23+ messages in thread
From: Tarang Raval @ 2026-03-07 5:22 UTC (permalink / raw)
To: Sakari Ailus
Cc: mehdi.djait@linux.intel.com, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Sakari,
> On Fri, Mar 06, 2026 at 06:03:01PM +0530, Tarang Raval wrote:
> > os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
> > the ACTIVE format. As a result, the VBLANK control handler uses the old
> > height when recalculating exposure limits, causing -ERANGE when switching
> > to a larger resolution.
> >
> > Update the ACTIVE format before adjusting framing controls so control
> > callbacks use the correct dimensions.
> >
> > Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > ---
> > drivers/media/i2c/os05b10.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> > index 4601e33b7e8f..476dbcb49351 100644
> > --- a/drivers/media/i2c/os05b10.c
> > +++ b/drivers/media/i2c/os05b10.c
> > @@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
> >
> > format = v4l2_subdev_state_get_format(sd_state, 0);
> >
> > + *format = fmt->format;
> > +
> > if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> > ret = os05b10_set_framing_limits(os05b10, mode);
>
> Does it take a driver bug for this to happen? Presumably? I guess the
> result would be somewhat inconsistent state in any case.
In the current driver only a single mode is present, so the issue is not
observed because no resolution change occurs.
This issue became visible while adding a new mode. During a mode switch
(from a smaller resolution to a larger one) the limits are calculated
using the previous format, which results in -ERANGE and the new mode is
not applied.
Updating *format = fmt->format before adjusting the framing controls
ensures the control handlers see the correct dimensions.
Best Regards,
Tarang
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch
2026-03-06 13:35 ` Sakari Ailus
@ 2026-03-07 5:28 ` Tarang Raval
0 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-07 5:28 UTC (permalink / raw)
To: Sakari Ailus
Cc: mehdi.djait@linux.intel.com, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Sakari,
> On Fri, Mar 06, 2026 at 06:03:00PM +0530, Tarang Raval wrote:
> > When switching sensor modes, V4L2 updates the vblank range/default but
> > keeps the previous current value, leaving vertical blanking unchanged.
> > Update the vblank and exposure control values to the new mode defaults
> > after adjusting the ranges.
> >
> > Clamp the exposure default value to the new maximum to prevent -ERANGE
> > during format changes.
> >
> > Also use pm_runtime_get_if_active() in set_ctrl() to avoid touching the
> > sensor when runtime suspended.
> >
> > Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > ---
> > drivers/media/i2c/os05b10.c | 21 ++++++++++++++-------
> > 1 file changed, 14 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> > index d8d776de5f35..4601e33b7e8f 100644
> > --- a/drivers/media/i2c/os05b10.c
> > +++ b/drivers/media/i2c/os05b10.c
> > @@ -732,16 +732,15 @@ static int os05b10_set_ctrl(struct v4l2_ctrl *ctrl)
> > if (ctrl->id == V4L2_CID_VBLANK) {
> > /* Honour the VBLANK limits when setting exposure. */
> > s64 max = fmt->height + ctrl->val - OS05B10_EXPOSURE_MARGIN;
> > -
> > + s64 def = min_t (s64, max, os05b10->exposure->default_value);
> > ret = __v4l2_ctrl_modify_range(os05b10->exposure,
> > os05b10->exposure->minimum, max,
> > - os05b10->exposure->step,
> > - os05b10->exposure->default_value);
> > + os05b10->exposure->step, def);
> > if (ret)
> > return ret;
> > }
> >
> > - if (pm_runtime_get_if_in_use(os05b10->dev) == 0)
> > + if (pm_runtime_get_if_active(os05b10->dev) == 0)
>
> This actually appears to be a bugfix: it was possible to set controls
> without them being applied on hardware if the use count was 0 but the
> device was still active. I'd consider doing the bugfix separately before
> the rest of the patches.
Sure, I will send this as a separate bugfix patch. I will also add a Fixes tag
and CC the stable kernel list.
Best Regards,
Tarang
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-07 5:22 ` Tarang Raval
@ 2026-03-09 8:19 ` Tarang Raval
0 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-09 8:19 UTC (permalink / raw)
To: Sakari Ailus
Cc: mehdi.djait@linux.intel.com, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Sakari,
> > On Fri, Mar 06, 2026 at 06:03:01PM +0530, Tarang Raval wrote:
> > > os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
> > > the ACTIVE format. As a result, the VBLANK control handler uses the old
> > > height when recalculating exposure limits, causing -ERANGE when switching
> > > to a larger resolution.
> > >
> > > Update the ACTIVE format before adjusting framing controls so control
> > > callbacks use the correct dimensions.
> > >
> > > Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > > ---
> > > drivers/media/i2c/os05b10.c | 4 ++--
> > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> > > index 4601e33b7e8f..476dbcb49351 100644
> > > --- a/drivers/media/i2c/os05b10.c
> > > +++ b/drivers/media/i2c/os05b10.c
> > > @@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
> > >
> > > format = v4l2_subdev_state_get_format(sd_state, 0);
> > >
> > > + *format = fmt->format;
> > > +
> > > if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> > > ret = os05b10_set_framing_limits(os05b10, mode);
> >
> > Does it take a driver bug for this to happen? Presumably? I guess the
> > result would be somewhat inconsistent state in any case.
>
> In the current driver only a single mode is present, so the issue is not
> observed because no resolution change occurs.
>
> This issue became visible while adding a new mode. During a mode switch
> (from a smaller resolution to a larger one) the limits are calculated
> using the previous format, which results in -ERANGE and the new mode is
> not applied.
>
> Updating *format = fmt->format before adjusting the framing controls
> ensures the control handlers see the correct dimensions.
During testing I messed up.
Sorry for the confusion. With patch 10 the -ERANGE error is already resolved.
During a mode change, os05b10_set_framing_limits() receives the selected
mode as an argument, so it already uses the new resolution when calculating
the limits.
Also, the control handlers are only triggered when streaming starts, so
there is no practical difference whether *format = fmt->format is updated
before or after adjusting the framing controls.
Given this, the change proposed in this patch is not necessary.
I will drop this patch.
Best Regards,
Tarang
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-06 12:33 ` [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls Tarang Raval
2026-03-06 13:36 ` Sakari Ailus
@ 2026-03-24 16:31 ` Tarang Raval
2026-03-25 8:56 ` sakari.ailus
1 sibling, 1 reply; 23+ messages in thread
From: Tarang Raval @ 2026-03-24 16:31 UTC (permalink / raw)
To: sakari.ailus@linux.intel.com
Cc: mehdi.djait@linux.intel.com, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 1615 bytes --]
Hi Sakari,
> os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
> the ACTIVE format. As a result, the VBLANK control handler uses the old
> height when recalculating exposure limits, causing -ERANGE when switching
> to a larger resolution.
>
> Update the ACTIVE format before adjusting framing controls so control
> callbacks use the correct dimensions.
>
> Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> ---
> drivers/media/i2c/os05b10.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> index 4601e33b7e8f..476dbcb49351 100644
> --- a/drivers/media/i2c/os05b10.c
> +++ b/drivers/media/i2c/os05b10.c
> @@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
>
> format = v4l2_subdev_state_get_format(sd_state, 0);
>
> + *format = fmt->format;
> +
This is the final analysis without this patch.
Please check the logs in the attached file.
When switching the resolution from 1280x720 to 2592x1944, the logs show that
while configuring the 1280 mode from the 2592 mode, the maximum exposure value
is calculated as 2219 (fmt->height + ctrl->val - exposure margin).
However, after switching to the 2592 mode, the maximum exposure value is 774.
From both cases, it is evident that fmt->height is being calculated incorrectly
It is still using the previous height instead of updating to the new resolution.
Please share your thoughts. Am I heading in the right direction?
Best Regards,
Tarang
[-- Attachment #2: active_format_logs.txt --]
[-- Type: text/plain, Size: 3659 bytes --]
######################## 2592x1944 --> 1280x720 ########################
debix@imx8mp-debix:~$
->'csis-32e40000.csi':0[1]"-ctl --device /dev/media0 --links "'os05b10 1-0036':0
r:none ycbcr:601 quantization:full-range]"
media-ctl -v -d /dev/media0 -V "'csis-32e40000.csi':1 [fmt:SBGGR12_1X12/1280x720 field:none colorspace:rec709 xfer:none ycbcr:601 quantization:full-range]"
media-ctl -d /dev/media0 -V '"rkisp1_isp":0 [crop:(0,0)/1280x720]'
media-ctl -d /dev/media0 -V '"rkisp1_isp":2 [crop:(0,0)/1280x720]'
media-ctl -d /dev/media0 -V '"rkisp1_isp":2 [fmt:YUYV8_2X8/1280x720]'
media-ctl -d /dev/media0 -V '"rkisp1_resizer_mainpath":0 [crop:(0,0)/1280x720]'debix@imx8mp-debix:~$ media-ctl -v -d /dev/media0 -V "'os05b10 1-0036':0 [fmt:SBGGR12_1X12/12"
Opening media device /dev/media0
Enumerating entities
l[ 146.666065] TDEBUG max: 2219, exp: 1944
ooking up device: 81:3
looking up device: 81:4
looking up device: 81:0
looking up device: 81:1
looking up device: 81:2
looking up device: 81:5
looking up device: 81:6
Found 7 entities
Enumerating pads and links
Setting up format SBGGR12_1X12 1280x720 on pad os05b10 1-0036/0/0
Format set: SBGGR12_1X12 1280x720
Setting up format SBGGR12_1X12 1280x720 on pad csis-32e40000.csi/0/0
Format set: SBGGR12_1X12 1280x720
debix@imx8mp-debix:~$ media-ctl -v -d /dev/media0 -V "'csis-32e40000.csi':1 [fmt:SBGGR12_1X12/1280x720 field:none colorspace:rec709 xfer:none ycbcr:601 quantization:full-ra"
Opening media device /dev/media0
Enumerating entities
looking up device: 81:3
looking up device: 81:4
looking up device: 81:0
looking up device: 81:1
looking up device: 81:2
looking up device: 81:5
looking up device: 81:6
Found 7 entities
Enumerating pads and links
Setting up format SBGGR12_1X12 1280x720 on pad csis-32e40000.csi/1/0
Format set: SBGGR12_1X12 1280x720
Setting up format SBGGR12_1X12 1280x720 on pad rkisp1_isp/0/0
Format set: SBGGR12_1X12 1280x720
debix@imx8mp-debix:~$ media-ctl -d /dev/media0 -V '"rkisp1_isp":0 [crop:(0,0)/1280x720]'
debix@imx8mp-debix:~$ media-ctl -d /dev/media0 -V '"rkisp1_isp":2 [crop:(0,0)/1280x720]'
debix@imx8mp-debix:~$ media-ctl -d /dev/media0 -V '"rkisp1_isp":2 [fmt:YUYV8_2X8/1280x720]'
debix@imx8mp-debix:~$ media-ctl -d /dev/media0 -V '"rkisp1_resizer_mainpath":0 [crop:(0,0)/1280x720]'
debix@imx8mp-debix:~$
debix@imx8mp-debix:~$
debix@imx8mp-debix:~$
debix@imx8mp-debix:~$
######################## 1280x720 --> 2592x1944 ########################
debix@imx8mp-debix:~$
->'csis-32e40000.csi':0[1]"-ctl --device /dev/media0 --links "'os05b10 1-0036':0
:none colorspace:raw xfer:none ycbcr:601 quantization:full-range]"
media-ctl -v -d /dev/media0 -V "'csis-32e40000.csi':1 [fmt:SBGGR10_1X10/2592x1944 field:none colorspace:raw xfer:none ycbcr:601 quantization:full-range]"
media-ctl -d /dev/media0 -V '"rkisp1_isp":0 [crop:(0,0)/2592x1944]'
media-ctl -d /dev/media0 -V '"rkisp1_isp":2 [crop:(0,0)/2592x1944]'
media-ctl -d /dev/media0 -V '"rkisp1_isp":2 [fmt:YUYV8_2X8/2592x1944]'
media-ctl -d /dev/media0 -V '"rkisp1_resizer_mainpath":0 [crop:(0,0)/2592x1944]'debix@imx8mp-debix:~$ media-ctl -v -d /dev/media0 -V "'os05b10 1-0036':0 [fmt:SBGGR10_1X10/2"
[ 172.714562] TDEBUG max: 774, exp: 970
Enumerating entities
looking up[ 172.714590] TDEBUG vblank: 62, vblank_max: 30823
device: 81:3
looking up device: 81:4
looking up device: 81:0
looking up device: 81:1
looking up device: 81:2
looking up device: 81:5
looking up device: 81:6
Found 7 entities
Enumerating pads and links
Setting up format SBGGR10_1X10 2592x1944 on pad os05b10 1-0036/0/0
Unable to set format: Numerical result out of range (-34)
Unable to setup formats: Numerical result out of range (34)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-24 16:31 ` Tarang Raval
@ 2026-03-25 8:56 ` sakari.ailus
2026-03-25 9:05 ` Tarang Raval
0 siblings, 1 reply; 23+ messages in thread
From: sakari.ailus @ 2026-03-25 8:56 UTC (permalink / raw)
To: Tarang Raval
Cc: mehdi.djait@linux.intel.com, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Tarang,
On Tue, Mar 24, 2026 at 04:31:02PM +0000, Tarang Raval wrote:
>
> Hi Sakari,
>
> > os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
> > the ACTIVE format. As a result, the VBLANK control handler uses the old
> > height when recalculating exposure limits, causing -ERANGE when switching
> > to a larger resolution.
> >
> > Update the ACTIVE format before adjusting framing controls so control
> > callbacks use the correct dimensions.
> >
> > Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > ---
> > drivers/media/i2c/os05b10.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> > index 4601e33b7e8f..476dbcb49351 100644
> > --- a/drivers/media/i2c/os05b10.c
> > +++ b/drivers/media/i2c/os05b10.c
> > @@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
> >
> > format = v4l2_subdev_state_get_format(sd_state, 0);
> >
> > + *format = fmt->format;
> > +
>
> This is the final analysis without this patch.
>
> Please check the logs in the attached file.
>
> When switching the resolution from 1280x720 to 2592x1944, the logs show that
> while configuring the 1280 mode from the 2592 mode, the maximum exposure value
> is calculated as 2219 (fmt->height + ctrl->val - exposure margin).
>
> However, after switching to the 2592 mode, the maximum exposure value is 774.
>
> From both cases, it is evident that fmt->height is being calculated incorrectly
> It is still using the previous height instead of updating to the new resolution.
>
> Please share your thoughts. Am I heading in the right direction?
I think the patch is reasonable. It'd be still nice to get reviews from
others before merging this.
--
Kind regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls
2026-03-25 8:56 ` sakari.ailus
@ 2026-03-25 9:05 ` Tarang Raval
0 siblings, 0 replies; 23+ messages in thread
From: Tarang Raval @ 2026-03-25 9:05 UTC (permalink / raw)
To: sakari.ailus@linux.intel.com
Cc: mehdi.djait@linux.intel.com, Himanshu Bhavani, Elgin Perumbilly,
Mauro Carvalho Chehab, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org
Hi Sakari,
> On Tue, Mar 24, 2026 at 04:31:02PM +0000, Tarang Raval wrote:
> >
> > Hi Sakari,
> >
> > > os05b10_set_pad_format() calls os05b10_set_framing_limits() before updating
> > > the ACTIVE format. As a result, the VBLANK control handler uses the old
> > > height when recalculating exposure limits, causing -ERANGE when switching
> > > to a larger resolution.
> > >
> > > Update the ACTIVE format before adjusting framing controls so control
> > > callbacks use the correct dimensions.
> > >
> > > Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > > ---
> > > drivers/media/i2c/os05b10.c | 4 ++--
> > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
> > > index 4601e33b7e8f..476dbcb49351 100644
> > > --- a/drivers/media/i2c/os05b10.c
> > > +++ b/drivers/media/i2c/os05b10.c
> > > @@ -902,14 +902,14 @@ static int os05b10_set_pad_format(struct v4l2_subdev *sd,
> > >
> > > format = v4l2_subdev_state_get_format(sd_state, 0);
> > >
> > > + *format = fmt->format;
> > > +
> >
> > This is the final analysis without this patch.
> >
> > Please check the logs in the attached file.
> >
> > When switching the resolution from 1280x720 to 2592x1944, the logs show that
> > while configuring the 1280 mode from the 2592 mode, the maximum exposure value
> > is calculated as 2219 (fmt->height + ctrl->val - exposure margin).
> >
> > However, after switching to the 2592 mode, the maximum exposure value is 774.
> >
> > From both cases, it is evident that fmt->height is being calculated incorrectly
> > It is still using the previous height instead of updating to the new resolution.
> >
> > Please share your thoughts. Am I heading in the right direction?
>
> I think the patch is reasonable. It'd be still nice to get reviews from
> others before merging this.
Yes, I will send a V2 of this series shortly. You can review that version.
Best Regards,
Tarang
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-03-25 9:05 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-06 12:32 [PATCH 00/13] media: i2c: os05b10: Refactor driver and Add new features Tarang Raval
2026-03-06 12:32 ` [PATCH 01/13] media: i2c: os05b10: drop unused group-hold programming Tarang Raval
2026-03-06 12:32 ` [PATCH 02/13] media: i2c: os05b10: add register definitions and use them in init table Tarang Raval
2026-03-06 12:32 ` [PATCH 03/13] media: i2c: os05b10: split common and mode-specific init registers Tarang Raval
2026-03-06 12:32 ` [PATCH 04/13] media: i2c: os05b10: add V4L2 digital gain control Tarang Raval
2026-03-06 12:32 ` [PATCH 05/13] media: i2c: os05b10: Add H/V flip support Tarang Raval
2026-03-06 12:32 ` [PATCH 06/13] media: i2c: os05b10: Add test pattern options Tarang Raval
2026-03-06 12:32 ` [PATCH 07/13] media: i2c: os05b10: add 12-bit RAW mode support Tarang Raval
2026-03-06 12:32 ` [PATCH 08/13] media: i2c: os05b10: update pixel rate on 10/12-bit mode switch Tarang Raval
2026-03-06 12:32 ` [PATCH 09/13] media: i2c: os05b10: Add 1080p and 2x2 binning 720p modes Tarang Raval
2026-03-06 12:33 ` [PATCH 10/13] media: i2c: os05b10: keep vblank/exposure in sync on mode switch Tarang Raval
2026-03-06 13:35 ` Sakari Ailus
2026-03-07 5:28 ` Tarang Raval
2026-03-06 12:33 ` [PATCH 11/13] media: i2c: os05b10: Update active format before adjusting framing controls Tarang Raval
2026-03-06 13:36 ` Sakari Ailus
2026-03-07 5:22 ` Tarang Raval
2026-03-09 8:19 ` Tarang Raval
2026-03-24 16:31 ` Tarang Raval
2026-03-25 8:56 ` sakari.ailus
2026-03-25 9:05 ` Tarang Raval
2026-03-06 12:33 ` [PATCH 12/13] media: i2c: os05b10: Rename vmax variable in VBLANK control Tarang Raval
2026-03-06 12:33 ` [PATCH 13/13] media: i2c: os05b10: add 2-lane support Tarang Raval
2026-03-07 1:56 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox