[PATCH v2] media: i2c: imx471: return 0 from get_selection after filling crop
John Cronin <[email protected]>
| Newsgroups | org.kernel.vger.linux-media |
|---|---|
| Message-ID | <[email protected]> |
libcamera issues VIDIOC_SUBDEV_G_SELECTION with target CROP (rectangle 0) during CameraSensorLegacy bring-up. imx471_get_selection filled the rectangle then fell out of the switch and returned -EINVAL. Fill every supported target, break, and return 0 after the switch (default: -EINVAL), as Kate Hsuan suggested. Compute analog crop in set_pad_format instead of storing a static window on the mode: 2x binning, centered in the native array, same idea as imx219. IMX471 2x2-binned 1928x1088 then reports CROP as 3856x2176 centered in 4672x3512. Tested on ThinkPad X9-15 Gen 1 (SONY471A / IPU7), Fedora 44 kernel 7.1.8-200.fc44. Link: https://bugzilla.redhat.com/show_bug.cgi?id=2454119 Signed-off-by: John Cronin <[email protected]> --- drivers/media/i2c/imx471.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/imx471.c b/drivers/media/i2c/imx471.c index a0d7d7f..cab9797 100644 --- a/drivers/media/i2c/imx471.c +++ b/drivers/media/i2c/imx471.c @@ -430,6 +430,22 @@ static int imx471_set_pad_format(struct v4l2_subdev *sd, imx471_update_pad_format(sensor, mode, fmt); *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; + + /* Analog crop: 2x bin, centered in the native array (same idea as imx219). */ + { + struct v4l2_rect *crop; + u8 bin_h, bin_v, binning; + + crop = v4l2_subdev_state_get_crop(sd_state, fmt->pad); + bin_h = min_t(u32, IMX471_PIXEL_ARRAY_WIDTH / fmt->format.width, 2); + bin_v = min_t(u32, IMX471_PIXEL_ARRAY_HEIGHT / fmt->format.height, 2); + binning = min(bin_h, bin_v); + crop->width = fmt->format.width * binning; + crop->height = fmt->format.height * binning; + crop->left = (IMX471_NATIVE_WIDTH - crop->width) / 2; + crop->top = (IMX471_NATIVE_HEIGHT - crop->height) / 2; + } + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) return 0; @@ -467,7 +483,7 @@ static int imx471_get_selection(struct v4l2_subdev *sd, sel->r.left = 0; sel->r.width = IMX471_NATIVE_WIDTH; sel->r.height = IMX471_NATIVE_HEIGHT; - return 0; + break; case V4L2_SEL_TGT_CROP_DEFAULT: case V4L2_SEL_TGT_CROP_BOUNDS: @@ -475,10 +491,13 @@ static int imx471_get_selection(struct v4l2_subdev *sd, sel->r.left = IMX471_PIXEL_ARRAY_LEFT; sel->r.width = IMX471_PIXEL_ARRAY_WIDTH; sel->r.height = IMX471_PIXEL_ARRAY_HEIGHT; - return 0; + break; + + default: + return -EINVAL; } - return -EINVAL; + return 0; } static int imx471_init_state(struct v4l2_subdev *sd, -- 2.55.0