]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: mt9m114: Allow set_selection while streaming
authorMathis Foerst <mathis.foerst@mt.com>
Mon, 14 Jul 2025 07:59:26 +0000 (09:59 +0200)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Mon, 25 Aug 2025 13:40:38 +0000 (15:40 +0200)
The current implementation does not apply changes to the crop-
configuration of the sensor immediately if the sensor is in
streaming state. The user has to stop and restart the stream for
the changes to be applied.

This can be undesirable e.g. in a calibration usecase where the user
wants to see the impact of his changes in a live video stream.
Under the condition that the width & height of the cropped image area
does not change, the changed cropping configuration can be applied to
the pixel-array immediately without disturbing the IFP.

Call mt9m114_configure_pa() in mt9m114_pa_set_selection() if the sensor is
in streaming state and the size of the cropping rectangle didn't change,
issue a CONFIG_CHANGE to apply the changes immediately.

Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/i2c/mt9m114.c

index 37fb8052d20f7f31f3992e3f59e80e6584bc2c70..54de62b46f40bbafbfc2ac74223182a37fae5451 100644 (file)
@@ -1287,6 +1287,7 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
        struct mt9m114 *sensor = pa_to_mt9m114(sd);
        struct v4l2_mbus_framefmt *format;
        struct v4l2_rect *crop;
+       int ret = 0;
 
        if (sel->target != V4L2_SEL_TGT_CROP)
                return -EINVAL;
@@ -1302,25 +1303,41 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
         * binning, but binning is configured after setting the selection, so
         * we can't know tell here if it will be used.
         */
-       crop->left = ALIGN(sel->r.left, 4);
-       crop->top = ALIGN(sel->r.top, 2);
-       crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 4),
-                             MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH,
-                             MT9M114_PIXEL_ARRAY_WIDTH - crop->left);
-       crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
-                              MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT,
-                              MT9M114_PIXEL_ARRAY_HEIGHT - crop->top);
-
-       sel->r = *crop;
+       sel->r.left = ALIGN(sel->r.left, 4);
+       sel->r.top = ALIGN(sel->r.top, 2);
+       sel->r.width = clamp_t(unsigned int, ALIGN(sel->r.width, 4),
+                              MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH,
+                              MT9M114_PIXEL_ARRAY_WIDTH - sel->r.left);
+       sel->r.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
+                               MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT,
+                               MT9M114_PIXEL_ARRAY_HEIGHT - sel->r.top);
+
+       /* Changing the selection size is not allowed in streaming state. */
+       if (sensor->streaming &&
+           (sel->r.height != crop->height || sel->r.width != crop->width))
+               return -EBUSY;
+
+       *crop = sel->r;
 
        /* Reset the format. */
        format->width = crop->width;
        format->height = crop->height;
 
-       if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-               mt9m114_pa_ctrl_update_blanking(sensor, format);
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return ret;
 
-       return 0;
+       mt9m114_pa_ctrl_update_blanking(sensor, format);
+
+       /* Apply values immediately if streaming. */
+       if (sensor->streaming) {
+               ret = mt9m114_configure_pa(sensor, state);
+               if (ret)
+                       return ret;
+               /* Changing the cropping config requires a CONFIG_CHANGE. */
+               ret = mt9m114_set_state(sensor,
+                                       MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
+       }
+       return ret;
 }
 
 static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = {