mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00: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>
This commit is contained in:
committed by
Dom Cobley
parent
d3fe3a8b42
commit
9fecff83db
@@ -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;
|
||||
@@ -115,6 +123,9 @@ struct imx258_mode {
|
||||
u32 link_freq_index;
|
||||
/* Default register values */
|
||||
struct imx258_reg_list reg_list;
|
||||
|
||||
/* Analog crop rectangle. */
|
||||
struct v4l2_rect crop;
|
||||
};
|
||||
|
||||
/* 4208x3120 needs 1267Mbps/lane, 4 lanes. Use that rate on 2 lanes as well */
|
||||
@@ -757,6 +768,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,
|
||||
@@ -768,6 +785,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,
|
||||
@@ -779,6 +802,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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -895,6 +924,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;
|
||||
@@ -902,6 +932,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;
|
||||
}
|
||||
|
||||
@@ -1149,6 +1186,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)
|
||||
{
|
||||
@@ -1318,6 +1407,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