media: imx355: Add support for get_selection

Provide all the cropping information via get_selection.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
This commit is contained in:
Dave Stevenson
2026-07-15 12:43:25 +01:00
committed by Sakari Ailus
parent ac2d97c65d
commit 8a52937cae

View File

@@ -86,6 +86,11 @@
/* number of data lanes */
#define IMX355_DATA_LANES 4
#define IMX355_PIXEL_ARRAY_TOP 0
#define IMX355_PIXEL_ARRAY_LEFT 0
#define IMX355_PIXEL_ARRAY_WIDTH 3280
#define IMX355_PIXEL_ARRAY_HEIGHT 2464
struct imx355_reg {
u16 address;
u8 val;
@@ -677,6 +682,7 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
struct imx355 *imx355 = to_imx355(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_state_get_format(fh->state, 0);
struct v4l2_rect *crop = v4l2_subdev_state_get_crop(fh->state, 0);
mutex_lock(&imx355->mutex);
@@ -686,6 +692,8 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
try_fmt->code = imx355_get_format_code(imx355);
try_fmt->field = V4L2_FIELD_NONE;
*crop = imx355->cur_mode->crop;
mutex_unlock(&imx355->mutex);
return 0;
@@ -849,6 +857,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
struct imx355 *imx355 = to_imx355(sd);
const struct imx355_mode *mode;
struct v4l2_mbus_framefmt *framefmt;
struct v4l2_rect *crop;
s32 vblank_def;
s64 h_blank;
u32 height;
@@ -869,6 +878,12 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
crop = v4l2_subdev_state_get_crop(sd_state, 0);
crop->width = mode->crop.width;
crop->height = mode->crop.height;
crop->left = mode->crop.left;
crop->top = mode->crop.top;
} else {
imx355->cur_mode = mode;
/* Update limits and set FPS to default */
@@ -892,6 +907,50 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
return 0;
}
static void
__imx355_get_pad_crop(struct imx355 *imx355,
struct v4l2_subdev_state *sd_state, unsigned int pad,
enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
*r = *v4l2_subdev_state_get_crop(sd_state, pad);
break;
case V4L2_SUBDEV_FORMAT_ACTIVE:
*r = imx355->cur_mode->crop;
break;
}
}
static int imx355_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_selection *sel)
{
switch (sel->target) {
case V4L2_SEL_TGT_CROP: {
struct imx355 *imx355 = to_imx355(sd);
mutex_lock(&imx355->mutex);
__imx355_get_pad_crop(imx355, sd_state, sel->pad, sel->which,
&sel->r);
mutex_unlock(&imx355->mutex);
return 0;
}
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_NATIVE_SIZE:
sel->r.top = IMX355_PIXEL_ARRAY_TOP;
sel->r.left = IMX355_PIXEL_ARRAY_LEFT;
sel->r.width = IMX355_PIXEL_ARRAY_WIDTH;
sel->r.height = IMX355_PIXEL_ARRAY_HEIGHT;
return 0;
}
return -EINVAL;
}
/* Start streaming */
static int imx355_start_streaming(struct imx355 *imx355)
{
@@ -1066,6 +1125,7 @@ static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
.get_fmt = imx355_get_pad_format,
.set_fmt = imx355_set_pad_format,
.enum_frame_size = imx355_enum_frame_size,
.get_selection = imx355_get_selection,
};
static const struct v4l2_subdev_ops imx355_subdev_ops = {