]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: i2c: imx334: Fix power management and control handling
authorTarang Raval <tarang.raval@siliconsignals.io>
Sat, 29 Mar 2025 05:43:27 +0000 (11:13 +0530)
committerHans Verkuil <hverkuil@xs4all.nl>
Fri, 25 Apr 2025 08:15:37 +0000 (10:15 +0200)
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>
drivers/media/i2c/imx334.c

index 561ed2c8700588c2b4f41717058af60f385c56bf..e8422d2fadfd359d2c61538229c1494f72ef9f7a 100644 (file)
@@ -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;
 }