summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTarang Raval <tarang.raval@siliconsignals.io>2025-03-29 11:13:27 +0530
committerHans Verkuil <hverkuil@xs4all.nl>2025-04-25 10:15:37 +0200
commita6dde677b93795a04f43f90427723bb4c2a50e5e (patch)
treeed3995ad243fef57eefc8ec07c3d82934c9c0447
parent9e089a649a229fb08942ada75b0f1c7f5814e065 (diff)
media: i2c: imx334: Fix power management and control handling
Some controls may need the sensor to be powered on to update their values. Currently, only the exposure control does this. To ensure proper handling, the power-up sequence is moved outside the switch-case. Additionally, VBLANK control is now processed earlier so its changes can correctly affect other controls. Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
-rw-r--r--drivers/media/i2c/imx334.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c
index 561ed2c870058..e8422d2fadfd3 100644
--- a/drivers/media/i2c/imx334.c
+++ b/drivers/media/i2c/imx334.c
@@ -578,8 +578,7 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl)
u32 exposure;
int ret;
- switch (ctrl->id) {
- case V4L2_CID_VBLANK:
+ if (ctrl->id == V4L2_CID_VBLANK) {
imx334->vblank = imx334->vblank_ctrl->val;
dev_dbg(imx334->dev, "Received vblank %u, new lpfr %u\n",
@@ -592,13 +591,24 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl)
imx334->cur_mode->height -
IMX334_EXPOSURE_OFFSET,
1, IMX334_EXPOSURE_DEFAULT);
+ if (ret)
+ return ret;
+ }
+
+ /* Set controls only if sensor is in power on state */
+ if (!pm_runtime_get_if_in_use(imx334->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_VBLANK:
+ exposure = imx334->exp_ctrl->val;
+ analog_gain = imx334->again_ctrl->val;
+
+ ret = imx334_update_exp_gain(imx334, exposure, analog_gain);
+
break;
case V4L2_CID_EXPOSURE:
- /* Set controls only if sensor is in power on state */
- if (!pm_runtime_get_if_in_use(imx334->dev))
- return 0;
-
exposure = ctrl->val;
analog_gain = imx334->again_ctrl->val;
@@ -607,8 +617,6 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl)
ret = imx334_update_exp_gain(imx334, exposure, analog_gain);
- pm_runtime_put(imx334->dev);
-
break;
case V4L2_CID_PIXEL_RATE:
case V4L2_CID_LINK_FREQ:
@@ -640,6 +648,8 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl)
ret = -EINVAL;
}
+ pm_runtime_put(imx334->dev);
+
return ret;
}