[PATCH 2/3] media: ov02c10: Implement get_selection
From: Felipe Calliari
Date: Fri Sep 04 2026 - 23:11:49 EST
The driver does not implement .get_selection, so userspace cannot query
the sensor's native size or active crop rectangle. libcamera reports
"Unable to get rectangle N on pad 0/0: Inappropriate ioctl for device"
and "The sensor kernel driver needs to be fixed" (see
Documentation/sensor_driver_requirements.rst).
Implement .get_selection returning the fixed geometry of the sensor:
- V4L2_SEL_TGT_NATIVE_SIZE / V4L2_SEL_TGT_CROP_BOUNDS: the full
1928x1092 pixel array.
- V4L2_SEL_TGT_CROP / V4L2_SEL_TGT_CROP_DEFAULT: the 1920x1080 active
area, offset by (4, 6), matching the readout window programmed in
sensor_1928x1092_30fps_setting[] (registers 0x3800-0x3807).
The crop is fixed, so sd_state is not consulted.
Signed-off-by: Felipe Calliari <calliarifelipe@xxxxxxxxx>
---
drivers/media/i2c/ov02c10.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
index 6220461fd..114db38c0 100644
--- a/drivers/media/i2c/ov02c10.c
+++ b/drivers/media/i2c/ov02c10.c
@@ -10,6 +10,7 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <media/v4l2-cci.h>
+#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -18,6 +19,13 @@
#define OV02C10_MCLK 19200000
#define OV02C10_RGB_DEPTH 10
+#define OV02C10_NATIVE_WIDTH 1928
+#define OV02C10_NATIVE_HEIGHT 1092
+#define OV02C10_ACTIVE_WIDTH 1920
+#define OV02C10_ACTIVE_HEIGHT 1080
+#define OV02C10_ACTIVE_LEFT 4
+#define OV02C10_ACTIVE_TOP 6
+
#define OV02C10_REG_CHIP_ID CCI_REG16(0x300a)
#define OV02C10_CHIP_ID 0x5602
@@ -767,11 +775,36 @@ static const struct v4l2_subdev_video_ops ov02c10_video_ops = {
.s_stream = v4l2_subdev_s_stream_helper,
};
+static int ov02c10_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ switch (sel->target) {
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = OV02C10_NATIVE_WIDTH;
+ sel->r.height = OV02C10_NATIVE_HEIGHT;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.top = OV02C10_ACTIVE_TOP;
+ sel->r.left = OV02C10_ACTIVE_LEFT;
+ sel->r.width = OV02C10_ACTIVE_WIDTH;
+ sel->r.height = OV02C10_ACTIVE_HEIGHT;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = {
.set_fmt = ov02c10_set_format,
.get_fmt = v4l2_subdev_get_fmt,
.enum_mbus_code = ov02c10_enum_mbus_code,
.enum_frame_size = ov02c10_enum_frame_size,
+ .get_selection = ov02c10_get_selection,
.enable_streams = ov02c10_enable_streams,
.disable_streams = ov02c10_disable_streams,
};
--
2.55.0