* [PATCH] media: i2c: ov08x40: implement crop selection
@ 2026-08-16 20:42 James Alexander
0 siblings, 0 replies; only message in thread
From: James Alexander @ 2026-08-16 20:42 UTC (permalink / raw)
To: Jimmy Su, Sakari Ailus, Mauro Carvalho Chehab; +Cc: linux-media, linux-kernel
libcamera asks raw sensor drivers for crop bounds and the active crop.
The ov08x40 driver currently has no selection operation. This causes camera
setup to fail with rectangle ioctl errors on the tested HP Spectre.
Record the crop used by each mode and return native size, crop bounds and
the active crop through get_selection(). Initialise the try crop when the
subdevice is opened as well.
Compile-tested against Linux base fd923b32d761. Hardware-tested with the
full patch set across 25 consecutive reboots on an HP Spectre x360
14-eu0xxx running Ubuntu 7.0.0-29-generic.
Signed-off-by: James Alexander <opensource@inspiredexperts.com>
---
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index 5eaf454f4..785157587 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -38,6 +38,13 @@
#define OV08X40_REG_CHIP_ID 0x300a
#define OV08X40_CHIP_ID 0x560858
+#define OV08X40_NATIVE_WIDTH 3856U
+#define OV08X40_NATIVE_HEIGHT 2416U
+#define OV08X40_PIXEL_ARRAY_LEFT 0U
+#define OV08X40_PIXEL_ARRAY_TOP 0U
+#define OV08X40_PIXEL_ARRAY_WIDTH 3856U
+#define OV08X40_PIXEL_ARRAY_HEIGHT 2416U
+
/* V_TIMING internal */
#define OV08X40_REG_VTS 0x380e
#define OV08X40_VTS_30FPS 0x09c4 /* the VTS need to be half in normal mode */
@@ -147,6 +154,7 @@ struct ov08x40_mode {
u32 link_freq_index;
/* Default register values */
struct ov08x40_reg_list reg_list;
+ struct v4l2_rect crop;
/* Exposure calculation */
u16 exposure_margin;
@@ -1233,6 +1241,12 @@ static const struct ov08x40_mode supported_modes[] = {
.regs = mode_3856x2416_regs,
},
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
+ .crop = {
+ .left = OV08X40_PIXEL_ARRAY_LEFT,
+ .top = OV08X40_PIXEL_ARRAY_TOP,
+ .width = OV08X40_PIXEL_ARRAY_WIDTH,
+ .height = OV08X40_PIXEL_ARRAY_HEIGHT,
+ },
.exposure_shift = 1,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
},
@@ -1248,6 +1262,12 @@ static const struct ov08x40_mode supported_modes[] = {
.regs = mode_3856x2176_regs_800mbps,
},
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
+ .crop = {
+ .left = OV08X40_PIXEL_ARRAY_LEFT,
+ .top = 120,
+ .width = OV08X40_PIXEL_ARRAY_WIDTH,
+ .height = 2176,
+ },
.exposure_shift = 1,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
},
@@ -1264,6 +1284,12 @@ static const struct ov08x40_mode supported_modes[] = {
.regs = mode_1928x1208_regs,
},
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
+ .crop = {
+ .left = OV08X40_PIXEL_ARRAY_LEFT,
+ .top = OV08X40_PIXEL_ARRAY_TOP,
+ .width = OV08X40_PIXEL_ARRAY_WIDTH,
+ .height = OV08X40_PIXEL_ARRAY_HEIGHT,
+ },
.exposure_shift = 0,
.exposure_margin = OV08X40_EXPOSURE_BIN_MAX_MARGIN,
},
@@ -1279,6 +1305,12 @@ static const struct ov08x40_mode supported_modes[] = {
.regs = mode_3856x2176_regs_1500mbps,
},
.link_freq_index = OV08X40_LINK_FREQ_749MHZ_INDEX,
+ .crop = {
+ .left = OV08X40_PIXEL_ARRAY_LEFT,
+ .top = 120,
+ .width = OV08X40_PIXEL_ARRAY_WIDTH,
+ .height = 2176,
+ },
.exposure_shift = 1,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
},
@@ -1294,6 +1326,12 @@ static const struct ov08x40_mode supported_modes[] = {
.regs = mode_1928x1088_regs_1500mbps,
},
.link_freq_index = OV08X40_LINK_FREQ_749MHZ_INDEX,
+ .crop = {
+ .left = OV08X40_PIXEL_ARRAY_LEFT,
+ .top = 120,
+ .width = OV08X40_PIXEL_ARRAY_WIDTH,
+ .height = 2176,
+ },
.exposure_shift = 0,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
},
@@ -1547,6 +1585,7 @@ static int ov08x40_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
struct ov08x40 *ov08x = to_ov08x40(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_state_get_format(fh->state, 0);
+ struct v4l2_rect *try_crop;
mutex_lock(&ov08x->mutex);
@@ -1556,7 +1595,9 @@ static int ov08x40_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
try_fmt->field = V4L2_FIELD_NONE;
- /* No crop or compose */
+ try_crop = v4l2_subdev_state_get_crop(fh->state, 0);
+ *try_crop = default_mode->crop;
+
mutex_unlock(&ov08x->mutex);
return 0;
@@ -1842,6 +1883,54 @@ static int ov08x40_get_pad_format(struct v4l2_subdev *sd,
return ret;
}
+static const struct v4l2_rect *
+ov08x40_get_pad_crop(struct ov08x40 *ov08x,
+ struct v4l2_subdev_state *sd_state,
+ unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ return v4l2_subdev_state_get_crop(sd_state, pad);
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ return &ov08x->cur_mode->crop;
+ }
+
+ return NULL;
+}
+
+static int ov08x40_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ struct ov08x40 *ov08x = to_ov08x40(sd);
+
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ mutex_lock(&ov08x->mutex);
+ sel->r = *ov08x40_get_pad_crop(ov08x, sd_state, sel->pad,
+ sel->which);
+ mutex_unlock(&ov08x->mutex);
+ return 0;
+
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = OV08X40_NATIVE_WIDTH;
+ sel->r.height = OV08X40_NATIVE_HEIGHT;
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.left = OV08X40_PIXEL_ARRAY_LEFT;
+ sel->r.top = OV08X40_PIXEL_ARRAY_TOP;
+ sel->r.width = OV08X40_PIXEL_ARRAY_WIDTH;
+ sel->r.height = OV08X40_PIXEL_ARRAY_HEIGHT;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static int
ov08x40_set_pad_format(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
@@ -2060,6 +2149,7 @@ static const struct v4l2_subdev_pad_ops ov08x40_pad_ops = {
.get_fmt = ov08x40_get_pad_format,
.set_fmt = ov08x40_set_pad_format,
.enum_frame_size = ov08x40_enum_frame_size,
+ .get_selection = ov08x40_get_selection,
};
static const struct v4l2_subdev_ops ov08x40_subdev_ops = {
--
2.46.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-16 20:49 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-16 20:42 [PATCH] media: i2c: ov08x40: implement crop selection James Alexander
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox