1 From 940cac315aaeca33483bffcf09a235195e3f5272 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Wed, 29 Apr 2020 11:46:07 +0100
4 Subject: [PATCH] media: i2c: ov5647: Add support for g_selection to
5 reflect cropping/binning
7 In order to apply lens shading correctly the client needs to know how
8 each mode crops or scales the image compared to the full sensor array.
9 Implement this (based on the imx219 equivalent).
11 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
13 drivers/media/i2c/ov5647.c | 119 ++++++++++++++++++++++++++++++-------
14 1 file changed, 96 insertions(+), 23 deletions(-)
16 --- a/drivers/media/i2c/ov5647.c
17 +++ b/drivers/media/i2c/ov5647.c
20 #define REG_DLY 0xffff
22 -#define OV5647_ROW_START 0x01
23 -#define OV5647_ROW_START_MIN 0
24 -#define OV5647_ROW_START_MAX 2004
25 -#define OV5647_ROW_START_DEF 54
27 -#define OV5647_COLUMN_START 0x02
28 -#define OV5647_COLUMN_START_MIN 0
29 -#define OV5647_COLUMN_START_MAX 2750
30 -#define OV5647_COLUMN_START_DEF 16
32 -#define OV5647_WINDOW_HEIGHT 0x03
33 -#define OV5647_WINDOW_HEIGHT_MIN 2
34 -#define OV5647_WINDOW_HEIGHT_MAX 2006
35 -#define OV5647_WINDOW_HEIGHT_DEF 1944
37 -#define OV5647_WINDOW_WIDTH 0x04
38 -#define OV5647_WINDOW_WIDTH_MIN 2
39 -#define OV5647_WINDOW_WIDTH_MAX 2752
40 -#define OV5647_WINDOW_WIDTH_DEF 2592
41 +/* OV5647 native and active pixel array size */
42 +#define OV5647_NATIVE_WIDTH 2624U
43 +#define OV5647_NATIVE_HEIGHT 1956U
45 +#define OV5647_PIXEL_ARRAY_LEFT 16U
46 +#define OV5647_PIXEL_ARRAY_TOP 16U
47 +#define OV5647_PIXEL_ARRAY_WIDTH 2592U
48 +#define OV5647_PIXEL_ARRAY_HEIGHT 1944U
52 @@ -97,6 +86,9 @@ struct regval_list {
55 struct v4l2_mbus_framefmt format;
56 + /* Analog crop rectangle. */
57 + struct v4l2_rect crop;
59 struct regval_list *reg_list;
60 unsigned int num_regs;
62 @@ -603,6 +595,12 @@ static struct ov5647_mode supported_mode
73 ARRAY_SIZE(ov5647_640x480_8bit)
75 @@ -620,6 +618,12 @@ static struct ov5647_mode supported_mode
85 ov5647_2592x1944_10bit,
86 ARRAY_SIZE(ov5647_2592x1944_10bit)
88 @@ -635,6 +639,12 @@ static struct ov5647_mode supported_mode
99 ARRAY_SIZE(ov5647_1080p30_10bit)
101 @@ -649,6 +659,12 @@ static struct ov5647_mode supported_mode
111 ov5647_2x2binned_10bit,
112 ARRAY_SIZE(ov5647_2x2binned_10bit)
114 @@ -664,6 +680,12 @@ static struct ov5647_mode supported_mode
124 ov5647_640x480_10bit,
125 ARRAY_SIZE(ov5647_640x480_10bit)
127 @@ -971,6 +993,56 @@ static const struct v4l2_subdev_core_ops
131 +static const struct v4l2_rect *
132 +__ov5647_get_pad_crop(struct ov5647 *ov5647, struct v4l2_subdev_pad_config *cfg,
133 + unsigned int pad, enum v4l2_subdev_format_whence which)
136 + case V4L2_SUBDEV_FORMAT_TRY:
137 + return v4l2_subdev_get_try_crop(&ov5647->sd, cfg, pad);
138 + case V4L2_SUBDEV_FORMAT_ACTIVE:
139 + return &ov5647->mode->crop;
145 +static int ov5647_get_selection(struct v4l2_subdev *sd,
146 + struct v4l2_subdev_pad_config *cfg,
147 + struct v4l2_subdev_selection *sel)
149 + switch (sel->target) {
150 + case V4L2_SEL_TGT_CROP: {
151 + struct ov5647 *state = to_state(sd);
153 + mutex_lock(&state->lock);
154 + sel->r = *__ov5647_get_pad_crop(state, cfg, sel->pad,
156 + mutex_unlock(&state->lock);
161 + case V4L2_SEL_TGT_NATIVE_SIZE:
164 + sel->r.width = OV5647_NATIVE_WIDTH;
165 + sel->r.height = OV5647_NATIVE_HEIGHT;
169 + case V4L2_SEL_TGT_CROP_DEFAULT:
170 + sel->r.top = OV5647_PIXEL_ARRAY_TOP;
171 + sel->r.left = OV5647_PIXEL_ARRAY_LEFT;
172 + sel->r.width = OV5647_PIXEL_ARRAY_WIDTH;
173 + sel->r.height = OV5647_PIXEL_ARRAY_HEIGHT;
181 static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
183 struct ov5647 *state = to_state(sd);
184 @@ -1122,6 +1194,7 @@ static const struct v4l2_subdev_pad_ops
185 .enum_mbus_code = ov5647_enum_mbus_code,
186 .set_fmt = ov5647_set_fmt,
187 .get_fmt = ov5647_get_fmt,
188 + .get_selection = ov5647_get_selection,
189 .enum_frame_size = ov5647_enum_frame_size,
192 @@ -1170,10 +1243,10 @@ static int ov5647_open(struct v4l2_subde
193 v4l2_subdev_get_try_crop(sd, fh->pad, 0);
194 struct ov5647 *state = to_state(sd);
196 - crop->left = OV5647_COLUMN_START_DEF;
197 - crop->top = OV5647_ROW_START_DEF;
198 - crop->width = OV5647_WINDOW_WIDTH_DEF;
199 - crop->height = OV5647_WINDOW_HEIGHT_DEF;
200 + crop->left = OV5647_PIXEL_ARRAY_LEFT;
201 + crop->top = OV5647_PIXEL_ARRAY_TOP;
202 + crop->width = OV5647_PIXEL_ARRAY_WIDTH;
203 + crop->height = OV5647_PIXEL_ARRAY_HEIGHT;
205 /* Set the default format to the same as the sensor. */
206 *format = state->mode->format;