diff options
author | Hans de Goede <hansg@kernel.org> | 2025-07-06 11:53:53 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2025-07-08 08:43:30 +0200 |
commit | bddd68a844f5a1c5ecc2f0409e7a2e7789169477 (patch) | |
tree | 2a072fa264b80d2f7b293b6bc24e27ab3d0a59dc | |
parent | c9524e6b90824ccfb96eac2e88f377f50c6d13ce (diff) |
media: atomisp: gc0310: Limit max exposure value to mode-height + vblank
When an exposure value > (mode-height + vblank) gets set the sensor will
automatically increase vblank, lowering the framerate.
This is not desirable, limit exposure the maximum exposure to mode-height +
vblank to avoid the unwanted framerate slowdown.
Signed-off-by: Hans de Goede <hansg@kernel.org>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://lore.kernel.org/r/20250517114106.43494-11-hdegoede@redhat.com
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r-- | drivers/staging/media/atomisp/i2c/atomisp-gc0310.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index d0e7f0f8452b..3e94414be6c7 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -306,12 +306,27 @@ static int gc0310_gain_set(struct gc0310_device *sensor, u32 gain) return ret; } +static int gc0310_exposure_update_range(struct gc0310_device *sensor) +{ + int exp_max = GC0310_NATIVE_HEIGHT + sensor->ctrls.vblank->val; + + return __v4l2_ctrl_modify_range(sensor->ctrls.exposure, 0, exp_max, + 1, exp_max); +} + static int gc0310_s_ctrl(struct v4l2_ctrl *ctrl) { struct gc0310_device *sensor = container_of(ctrl->handler, struct gc0310_device, ctrls.handler); int ret; + /* Update exposure range on vblank changes */ + if (ctrl->id == V4L2_CID_VBLANK) { + ret = gc0310_exposure_update_range(sensor); + if (ret) + return ret; + } + /* Only apply changes to the controls if the device is powered up */ if (!pm_runtime_get_if_in_use(sensor->sd.dev)) return 0; @@ -584,7 +599,7 @@ static int gc0310_init_controls(struct gc0310_device *sensor) struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd); struct v4l2_ctrl_handler *hdl = &sensor->ctrls.handler; struct v4l2_fwnode_device_properties props; - int ret; + int exp_max, ret; v4l2_ctrl_handler_init(hdl, 8); @@ -592,8 +607,10 @@ static int gc0310_init_controls(struct gc0310_device *sensor) hdl->lock = &sensor->input_lock; sensor->sd.ctrl_handler = hdl; + exp_max = GC0310_NATIVE_HEIGHT + GC0310_V_BLANK_DEFAULT; sensor->ctrls.exposure = - v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, 4095, 1, 1023); + v4l2_ctrl_new_std(hdl, &ctrl_ops, V4L2_CID_EXPOSURE, 0, + exp_max, 1, exp_max); /* 32 steps at base gain 1 + 64 half steps at base gain 2 */ sensor->ctrls.gain = |