mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 10:20:17 -04:00
media: i2c: imx258: Add get_selection for pixel array information
Libcamera requires the cropping information for each mode, so add this information to the driver. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Luis Garcia <git@luigi311.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
committed by
Hans Verkuil
parent
8eaf1994a4
commit
29e7d3fbc8
@@ -77,6 +77,14 @@
|
||||
#define REG_CONFIG_MIRROR_FLIP 0x03
|
||||
#define REG_CONFIG_FLIP_TEST_PATTERN 0x02
|
||||
|
||||
/* IMX258 native and active pixel array size. */
|
||||
#define IMX258_NATIVE_WIDTH 4224U
|
||||
#define IMX258_NATIVE_HEIGHT 3192U
|
||||
#define IMX258_PIXEL_ARRAY_LEFT 8U
|
||||
#define IMX258_PIXEL_ARRAY_TOP 16U
|
||||
#define IMX258_PIXEL_ARRAY_WIDTH 4208U
|
||||
#define IMX258_PIXEL_ARRAY_HEIGHT 3120U
|
||||
|
||||
struct imx258_reg {
|
||||
u16 address;
|
||||
u8 val;
|
||||
@@ -116,6 +124,9 @@ struct imx258_mode {
|
||||
u32 link_freq_index;
|
||||
/* Default register values */
|
||||
struct imx258_reg_list reg_list;
|
||||
|
||||
/* Analog crop rectangle */
|
||||
struct v4l2_rect crop;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -560,6 +571,12 @@ static const struct imx258_mode supported_modes[] = {
|
||||
.regs = mode_4208x3120_regs,
|
||||
},
|
||||
.link_freq_index = IMX258_LINK_FREQ_1267MBPS,
|
||||
.crop = {
|
||||
.left = IMX258_PIXEL_ARRAY_LEFT,
|
||||
.top = IMX258_PIXEL_ARRAY_TOP,
|
||||
.width = 4208,
|
||||
.height = 3120,
|
||||
},
|
||||
},
|
||||
{
|
||||
.width = 2104,
|
||||
@@ -571,6 +588,12 @@ static const struct imx258_mode supported_modes[] = {
|
||||
.regs = mode_2104_1560_regs,
|
||||
},
|
||||
.link_freq_index = IMX258_LINK_FREQ_640MBPS,
|
||||
.crop = {
|
||||
.left = IMX258_PIXEL_ARRAY_LEFT,
|
||||
.top = IMX258_PIXEL_ARRAY_TOP,
|
||||
.width = 4208,
|
||||
.height = 3120,
|
||||
},
|
||||
},
|
||||
{
|
||||
.width = 1048,
|
||||
@@ -582,6 +605,12 @@ static const struct imx258_mode supported_modes[] = {
|
||||
.regs = mode_1048_780_regs,
|
||||
},
|
||||
.link_freq_index = IMX258_LINK_FREQ_640MBPS,
|
||||
.crop = {
|
||||
.left = IMX258_PIXEL_ARRAY_LEFT,
|
||||
.top = IMX258_PIXEL_ARRAY_TOP,
|
||||
.width = 4208,
|
||||
.height = 3120,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -698,6 +727,7 @@ static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *try_fmt =
|
||||
v4l2_subdev_state_get_format(fh->state, 0);
|
||||
struct v4l2_rect *try_crop;
|
||||
|
||||
/* Initialize try_fmt */
|
||||
try_fmt->width = supported_modes[0].width;
|
||||
@@ -705,6 +735,13 @@ static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
try_fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
|
||||
try_fmt->field = V4L2_FIELD_NONE;
|
||||
|
||||
/* Initialize try_crop */
|
||||
try_crop = v4l2_subdev_state_get_crop(fh->state, 0);
|
||||
try_crop->left = IMX258_PIXEL_ARRAY_LEFT;
|
||||
try_crop->top = IMX258_PIXEL_ARRAY_TOP;
|
||||
try_crop->width = IMX258_PIXEL_ARRAY_WIDTH;
|
||||
try_crop->height = IMX258_PIXEL_ARRAY_HEIGHT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -952,6 +989,58 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_rect *
|
||||
__imx258_get_pad_crop(struct imx258 *imx258,
|
||||
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 &imx258->cur_mode->crop;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int imx258_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 imx258 *imx258 = to_imx258(sd);
|
||||
|
||||
mutex_lock(&imx258->mutex);
|
||||
sel->r = *__imx258_get_pad_crop(imx258, sd_state, sel->pad,
|
||||
sel->which);
|
||||
mutex_unlock(&imx258->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case V4L2_SEL_TGT_NATIVE_SIZE:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
sel->r.width = IMX258_NATIVE_WIDTH;
|
||||
sel->r.height = IMX258_NATIVE_HEIGHT;
|
||||
|
||||
return 0;
|
||||
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.left = IMX258_PIXEL_ARRAY_LEFT;
|
||||
sel->r.top = IMX258_PIXEL_ARRAY_TOP;
|
||||
sel->r.width = IMX258_PIXEL_ARRAY_WIDTH;
|
||||
sel->r.height = IMX258_PIXEL_ARRAY_HEIGHT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Start streaming */
|
||||
static int imx258_start_streaming(struct imx258 *imx258)
|
||||
{
|
||||
@@ -1128,6 +1217,7 @@ static const struct v4l2_subdev_pad_ops imx258_pad_ops = {
|
||||
.get_fmt = imx258_get_pad_format,
|
||||
.set_fmt = imx258_set_pad_format,
|
||||
.enum_frame_size = imx258_enum_frame_size,
|
||||
.get_selection = imx258_get_selection,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops imx258_subdev_ops = {
|
||||
|
||||
Reference in New Issue
Block a user