[PATCH v3 15/17] media: i2c: os05b10: fix negative hblank calculation

From: Tarang Raval

Date: Sat Jul 18 2026 - 16:15:11 EST


hblank is computed as "mode->hts - mode->width", but both are u32.
For every mode hts < width (e.g. 1744 vs 2592 for 2592x1944), so the
subtraction wraps in unsigned 32-bit arithmetic instead of going
negative. That wrapped value ends up in the control's s64 min/max,
which v4l2-compliance flags as out of range:

fail: v4l2-test-controls.cpp(413): returned control value out of range
fail: v4l2-test-controls.cpp(476): invalid control 009e0902

and v4l2-ctl shows:

horizontal_blanking 0x009e0902 (int): min=4294966448 max=4294966448
step=1 default=4294966448 value=-848 flags=read-only, has-min-max

The same bug exists in os05b10_init_controls(), which sets the
control's default before os05b10_set_framing_limits() runs.

Fix both sites by casting to a signed type before subtracting, so the
real (possibly negative) value is computed directly.

Fixes: 3aa9296a23ec4 ("media: i2c: add os05b10 image sensor driver")
Signed-off-by: Tarang Raval <tarang.raval@xxxxxxxxxxxxxxxxx>
---
drivers/media/i2c/os05b10.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/os05b10.c b/drivers/media/i2c/os05b10.c
index 6d91a9660660..59097eb96561 100644
--- a/drivers/media/i2c/os05b10.c
+++ b/drivers/media/i2c/os05b10.c
@@ -871,7 +871,8 @@ 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;
+ u32 vblank, vblank_max;
+ s32 hblank;
int ret;

ret = __v4l2_ctrl_modify_range(os05b10->pixel_rate, pixel_rate,
@@ -883,7 +884,7 @@ static int os05b10_set_framing_limits(struct os05b10 *os05b10,
if (ret)
return ret;

- hblank = mode->hts - mode->width;
+ hblank = (s32)mode->hts - (s32)mode->width;
ret = __v4l2_ctrl_modify_range(os05b10->hblank, hblank, hblank, 1,
hblank);
if (ret)
@@ -1272,9 +1273,10 @@ static int os05b10_parse_endpoint(struct os05b10 *os05b10)
static int os05b10_init_controls(struct os05b10 *os05b10)
{
const struct os05b10_mode *mode = &supported_modes_10bit[0];
- u64 hblank_def, vblank_def, exp_max, pixel_rate;
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
+ u64 vblank_def, exp_max, pixel_rate;
+ s64 hblank_def;
int ret;

ctrl_hdlr = &os05b10->handler;
@@ -1295,7 +1297,7 @@ static int os05b10_init_controls(struct os05b10 *os05b10)
if (os05b10->link_freq)
os05b10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;

- hblank_def = mode->hts - mode->width;
+ hblank_def = (s64)mode->hts -(s64)mode->width;
os05b10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_HBLANK,
hblank_def, hblank_def,
1, hblank_def);
--
2.34.1