diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch b/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch new file mode 100644 index 0000000000..86680af234 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0886-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch @@ -0,0 +1,156 @@ +From a191c6d6e5180f54ecf16adda61988a16ce9fe48 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Tue, 7 Jul 2020 11:23:48 +0100 +Subject: [PATCH] media: i2c: imx290: Add support for g_selection to + report cropping + +Userspace needs to know the cropping arrangements for each mode, +so expose this through g_selection. + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/media/i2c/imx290.c | 84 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 84 insertions(+) + +--- a/drivers/media/i2c/imx290.c ++++ b/drivers/media/i2c/imx290.c +@@ -61,6 +61,13 @@ enum imx290_clk_index { + #define IMX290_PGCTRL_THRU BIT(1) + #define IMX290_PGCTRL_MODE(n) ((n) << 4) + ++#define IMX290_NATIVE_WIDTH 1945U ++#define IMX290_NATIVE_HEIGHT 1109U ++#define IMX290_PIXEL_ARRAY_LEFT 4U ++#define IMX290_PIXEL_ARRAY_TOP 12U ++#define IMX290_PIXEL_ARRAY_WIDTH 1937U ++#define IMX290_PIXEL_ARRAY_HEIGHT 1097U ++ + static const char * const imx290_supply_name[] = { + "vdda", + "vddd", +@@ -80,6 +87,7 @@ struct imx290_mode { + u32 hmax; + u32 vmax; + u8 link_freq_index; ++ struct v4l2_rect crop; + + const struct imx290_regval *data; + u32 data_size; +@@ -384,6 +392,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x1130, + .vmax = 0x0465, + .link_freq_index = FREQ_INDEX_1080P, ++ .crop = { ++ .left = 4 + 8, ++ .top = 12 + 8, ++ .width = 1920, ++ .height = 1080, ++ }, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), + .clk_data = { +@@ -398,6 +412,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x19c8, + .vmax = 0x02ee, + .link_freq_index = FREQ_INDEX_720P, ++ .crop = { ++ .left = 4 + 8 + 320, ++ .top = 12 + 8 + 180, ++ .width = 1280, ++ .height = 720, ++ }, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), + .clk_data = { +@@ -415,6 +435,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x0898, + .vmax = 0x0465, + .link_freq_index = FREQ_INDEX_1080P, ++ .crop = { ++ .left = 4 + 8, ++ .top = 12 + 8, ++ .width = 1920, ++ .height = 1080, ++ }, + .data = imx290_1080p_settings, + .data_size = ARRAY_SIZE(imx290_1080p_settings), + .clk_data = { +@@ -429,6 +455,12 @@ static const struct imx290_mode imx290_m + .hmax = 0x0ce4, + .vmax = 0x02ee, + .link_freq_index = FREQ_INDEX_720P, ++ .crop = { ++ .left = 4 + 8 + 320, ++ .top = 12 + 8 + 180, ++ .width = 1280, ++ .height = 720, ++ }, + .data = imx290_720p_settings, + .data_size = ARRAY_SIZE(imx290_720p_settings), + .clk_data = { +@@ -875,6 +907,57 @@ static int imx290_write_current_format(s + return 0; + } + ++static const struct v4l2_rect * ++__imx290_get_pad_crop(struct imx290 *imx290, struct v4l2_subdev_pad_config *cfg, ++ unsigned int pad, enum v4l2_subdev_format_whence which) ++{ ++ switch (which) { ++ case V4L2_SUBDEV_FORMAT_TRY: ++ return v4l2_subdev_get_try_crop(&imx290->sd, cfg, pad); ++ case V4L2_SUBDEV_FORMAT_ACTIVE: ++ return &imx290->current_mode->crop; ++ } ++ ++ return NULL; ++} ++ ++static int imx290_get_selection(struct v4l2_subdev *sd, ++ struct v4l2_subdev_pad_config *cfg, ++ struct v4l2_subdev_selection *sel) ++{ ++ switch (sel->target) { ++ case V4L2_SEL_TGT_CROP: { ++ struct imx290 *imx290 = to_imx290(sd); ++ ++ mutex_lock(&imx290->lock); ++ sel->r = *__imx290_get_pad_crop(imx290, cfg, sel->pad, ++ sel->which); ++ mutex_unlock(&imx290->lock); ++ ++ return 0; ++ } ++ ++ case V4L2_SEL_TGT_NATIVE_SIZE: ++ sel->r.top = 0; ++ sel->r.left = 0; ++ sel->r.width = IMX290_NATIVE_WIDTH; ++ sel->r.height = IMX290_NATIVE_HEIGHT; ++ ++ return 0; ++ ++ case V4L2_SEL_TGT_CROP_DEFAULT: ++ case V4L2_SEL_TGT_CROP_BOUNDS: ++ sel->r.top = IMX290_PIXEL_ARRAY_TOP; ++ sel->r.left = IMX290_PIXEL_ARRAY_LEFT; ++ sel->r.width = IMX290_PIXEL_ARRAY_WIDTH; ++ sel->r.height = IMX290_PIXEL_ARRAY_HEIGHT; ++ ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ + /* Start streaming */ + static int imx290_start_streaming(struct imx290 *imx290) + { +@@ -1073,6 +1156,7 @@ static const struct v4l2_subdev_pad_ops + .enum_frame_size = imx290_enum_frame_size, + .get_fmt = imx290_get_fmt, + .set_fmt = imx290_set_fmt, ++ .get_selection = imx290_get_selection, + }; + + static const struct v4l2_subdev_ops imx290_subdev_ops = { |