[PATCH] media: i2c: imx471: return 0 for V4L2_SEL_TGT_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 broke out of the switch and returned -EINVAL, so libcamera logged: Unable to get rectangle 0 on pad 0/0: Invalid argument Failed to retrieve the sensor crop rectangle Match imx219: return 0 after CROP. Also store the analog crop window from X/Y_ADD_STA/END in the subdev state when the mode is selected, so the CROP rectangle is not an uninitialized 0x0 box. Analog crop for the 1928x1088 2x2-binned mode is the programmed analog window 8,408 / 4640x2644 (native array coordinates). Tested on ThinkPad X9-15 Gen 1 (SONY471A / IPU7), Fedora 44 kernel 7.1.8-200.fc44. After loading this module: VIDIOC_SUBDEV_G_SELECTION CROP → 8,408 4640x2644 VIDIOC_SUBDEV_G_SELECTION CROP_BOUNDS → 8,8 4656x3496 VIDIOC_SUBDEV_G_SELECTION NATIVE_SIZE → 0,0 4672x3512 libcamera no longer logs "Unable to get rectangle 0 on pad 0/0". Link: https://bugzilla.redhat.com/show_bug.cgi?id=2454119 Signed-off-by: John Cronin <[email protected]> --- drivers/media/i2c/imx471.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx471.c b/drivers/media/i2c/imx471.c index ae0e4d4..18b81aa 100644 --- a/drivers/media/i2c/imx471.c +++ b/drivers/media/i2c/imx471.c @@ -131,6 +131,9 @@ struct imx471_mode { /* H-timing */ u32 llp; + /* Analog crop window in native array coordinates */ + struct v4l2_rect crop; + const struct cci_reg_sequence *default_mode_regs; unsigned int default_mode_regs_length; }; @@ -283,6 +286,13 @@ static const struct imx471_mode imx471_modes[] = { .fll_def = 1308, .fll_min = 1308, .llp = 2328, + /* X/Y_ADD_STA/END: 8..4647 x 408..3051 */ + .crop = { + .left = 8, + .top = 408, + .width = 4640, + .height = 2644, + }, .default_mode_regs = mode_1928x1088_regs, .default_mode_regs_length = ARRAY_SIZE(mode_1928x1088_regs), }, @@ -430,6 +440,7 @@ 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; + *v4l2_subdev_state_get_crop(sd_state, fmt->pad) = mode->crop; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) return 0; @@ -461,7 +472,7 @@ static int imx471_get_selection(struct v4l2_subdev *sd, switch (sel->target) { case V4L2_SEL_TGT_CROP: sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad); - break; + return 0; case V4L2_SEL_TGT_NATIVE_SIZE: sel->r.top = 0; -- 2.55.0