media: i2c: ov5675: add .get_selection support
authorQuentin Schulz <quentin.schulz@theobroma-systems.com>
Wed, 8 Jun 2022 13:44:20 +0000 (15:44 +0200)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 6 Feb 2023 07:45:05 +0000 (08:45 +0100)
The sensor has 2592*1944 active pixels, surrounded by 16 active dummy
pixels and there are an additional 24 black rows "at the bottom".

                     [2624]
        +-----+------------------+-----+
        |     |     16 dummy     |     |
        +-----+------------------+-----+
        |     |                  |     |
        |     |     [2592]       |     |
        |     |                  |     |
        |16   |      valid       | 16  |[2000]
        |dummy|                  |dummy|
        |     |            [1944]|     |
        |     |                  |     |
        +-----+------------------+-----+
        |     |     16 dummy     |     |
        +-----+------------------+-----+
        |     |  24 black lines  |     |
        +-----+------------------+-----+

The top-left coordinate is gotten from the registers specified in the
modes which are identical for both currently supported modes.

There are currently two modes supported by this driver: 2592*1944 and
1296*972. The second mode is obtained thanks to subsampling while
keeping the same field of view (FoV). No cropping involved, hence the
harcoded values.

Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/i2c/ov5675.c

index b1ed437..d55180b 100644 (file)
@@ -1123,6 +1123,31 @@ static int ov5675_get_format(struct v4l2_subdev *sd,
        return 0;
 }
 
+static int ov5675_get_selection(struct v4l2_subdev *sd,
+                               struct v4l2_subdev_state *state,
+                               struct v4l2_subdev_selection *sel)
+{
+       if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+               return -EINVAL;
+
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.top = 0;
+               sel->r.left = 0;
+               sel->r.width = 2624;
+               sel->r.height = 2000;
+               return 0;
+       case V4L2_SEL_TGT_CROP:
+       case V4L2_SEL_TGT_CROP_DEFAULT:
+               sel->r.top = 16;
+               sel->r.left = 16;
+               sel->r.width = 2592;
+               sel->r.height = 1944;
+               return 0;
+       }
+       return -EINVAL;
+}
+
 static int ov5675_enum_mbus_code(struct v4l2_subdev *sd,
                                 struct v4l2_subdev_state *sd_state,
                                 struct v4l2_subdev_mbus_code_enum *code)
@@ -1172,6 +1197,7 @@ static const struct v4l2_subdev_video_ops ov5675_video_ops = {
 static const struct v4l2_subdev_pad_ops ov5675_pad_ops = {
        .set_fmt = ov5675_set_format,
        .get_fmt = ov5675_get_format,
+       .get_selection = ov5675_get_selection,
        .enum_mbus_code = ov5675_enum_mbus_code,
        .enum_frame_size = ov5675_enum_frame_size,
 };