From: Oleg Keri <okerixx@gmail.com>
To: Sakari Ailus <sakari.ailus@linux.intel.com>,
Jimmy Su <jimmy.su@intel.com>,
Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] media: ov08x40: implement get_selection
Date: Tue, 8 Sep 2026 15:08:03 +0200 [thread overview]
Message-ID: <20260908130803.2632-1-okerixx@gmail.com> (raw)
The driver does not implement any pad selection op, so userspace gets
-ENOTTY when asking for the pixel array geometry. libcamera then has to
guess: it defaults PixelArraySize to the output size and
PixelArrayActiveAreas to a zero-sized rectangle, and warns that the driver
needs fixing.
Report the full pixel array and the per-mode analogue crop. The values are
those the register lists already program: X_ADDR_START/END give a 3872
pixel wide array and Y_ADDR_START/END give 2432 lines, with each mode
cropping that window vertically.
Signed-off-by: Oleg Keri <okerixx@gmail.com>
---
drivers/media/i2c/ov08x40.c | 87 +++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index 5eaf454f4763..0299d50222ad 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -151,6 +151,9 @@ struct ov08x40_mode {
/* Exposure calculation */
u16 exposure_margin;
u16 exposure_shift;
+
+ /* Analogue crop programmed by reg_list */
+ struct v4l2_rect crop;
};
static const struct ov08x40_reg ov08x40_global_regs[] = {
@@ -1183,6 +1186,10 @@ static const char * const ov08x40_test_pattern_menu[] = {
#define OV08X40_LINK_FREQ_749MHZ 749000000ULL
#define OV08X40_SCLK_96MHZ 96000000ULL
#define OV08X40_XVCLK 19200000
+
+/* Full pixel array, from X/Y_ADDR_START..END in the register lists */
+#define OV08X40_NATIVE_WIDTH 3872
+#define OV08X40_NATIVE_HEIGHT 2432
#define OV08X40_DATA_LANES 4
/*
@@ -1235,6 +1242,12 @@ static const struct ov08x40_mode supported_modes[] = {
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
.exposure_shift = 1,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
+ .crop = {
+ .left = 0,
+ .top = 0,
+ .width = 3872,
+ .height = 2432,
+ },
},
{
.width = 3856,
@@ -1250,6 +1263,12 @@ static const struct ov08x40_mode supported_modes[] = {
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
.exposure_shift = 1,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
+ .crop = {
+ .left = 0,
+ .top = 112,
+ .width = 3872,
+ .height = 2208,
+ },
},
{
@@ -1266,6 +1285,12 @@ static const struct ov08x40_mode supported_modes[] = {
.link_freq_index = OV08X40_LINK_FREQ_400MHZ_INDEX,
.exposure_shift = 0,
.exposure_margin = OV08X40_EXPOSURE_BIN_MAX_MARGIN,
+ .crop = {
+ .left = 0,
+ .top = 0,
+ .width = 3872,
+ .height = 2432,
+ },
},
{
.width = 3856,
@@ -1281,6 +1306,12 @@ static const struct ov08x40_mode supported_modes[] = {
.link_freq_index = OV08X40_LINK_FREQ_749MHZ_INDEX,
.exposure_shift = 1,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
+ .crop = {
+ .left = 0,
+ .top = 112,
+ .width = 3872,
+ .height = 2208,
+ },
},
{
.width = 1928,
@@ -1296,6 +1327,12 @@ static const struct ov08x40_mode supported_modes[] = {
.link_freq_index = OV08X40_LINK_FREQ_749MHZ_INDEX,
.exposure_shift = 0,
.exposure_margin = OV08X40_EXPOSURE_MAX_MARGIN,
+ .crop = {
+ .left = 0,
+ .top = 120,
+ .width = 3872,
+ .height = 2192,
+ },
},
};
@@ -2055,10 +2092,60 @@ static const struct v4l2_subdev_video_ops ov08x40_video_ops = {
.s_stream = ov08x40_set_stream,
};
+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)
+{
+ const struct v4l2_mbus_framefmt *fmt;
+ const struct ov08x40_mode *mode;
+
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ return &ov08x->cur_mode->crop;
+
+ fmt = v4l2_subdev_state_get_format(sd_state, pad);
+ mode = v4l2_find_nearest_size_conditional(supported_modes,
+ ARRAY_SIZE(supported_modes),
+ width, height,
+ fmt->width, fmt->height,
+ filter_by_mipi_lanes, ov08x);
+
+ return &mode->crop;
+}
+
+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:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = OV08X40_NATIVE_WIDTH;
+ sel->r.height = OV08X40_NATIVE_HEIGHT;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static const struct v4l2_subdev_pad_ops ov08x40_pad_ops = {
.enum_mbus_code = ov08x40_enum_mbus_code,
.get_fmt = ov08x40_get_pad_format,
.set_fmt = ov08x40_set_pad_format,
+ .get_selection = ov08x40_get_selection,
.enum_frame_size = ov08x40_enum_frame_size,
};
--
2.55.0
base-commit: df2908090cda368b01ff43709f51890076c56157
reply other threads:[~2026-09-08 13:08 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260908130803.2632-1-okerixx@gmail.com \
--to=okerixx@gmail.com \
--cc=jimmy.su@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=sakari.ailus@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.