kernel: bump 5.4 to 5.4.48
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0684-media-i2c-ov5647-Add-support-for-g_selection-to-refl.patch
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
6
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).
10
11 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
12 ---
13  drivers/media/i2c/ov5647.c | 119 ++++++++++++++++++++++++++++++-------
14  1 file changed, 96 insertions(+), 23 deletions(-)
15
16 --- a/drivers/media/i2c/ov5647.c
17 +++ b/drivers/media/i2c/ov5647.c
18 @@ -70,25 +70,14 @@
19  #define VAL_TERM 0xfe
20  #define REG_DLY  0xffff
21  
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
26 -
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
31 -
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
36 -
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
44 +
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
49  
50  struct regval_list {
51         u16 addr;
52 @@ -97,6 +86,9 @@ struct regval_list {
53  
54  struct ov5647_mode {
55         struct v4l2_mbus_framefmt       format;
56 +       /* Analog crop rectangle. */
57 +       struct v4l2_rect crop;
58 +
59         struct regval_list              *reg_list;
60         unsigned int                    num_regs;
61  };
62 @@ -603,6 +595,12 @@ static struct ov5647_mode supported_mode
63                         .width = 640,
64                         .height = 480
65                 },
66 +               .crop = {
67 +                       .left = 0,
68 +                       .top = 0,
69 +                       .width = 1280,
70 +                       .height = 960,
71 +               },
72                 ov5647_640x480_8bit,
73                 ARRAY_SIZE(ov5647_640x480_8bit)
74         },
75 @@ -620,6 +618,12 @@ static struct ov5647_mode supported_mode
76                         .width = 2592,
77                         .height = 1944
78                 },
79 +               .crop = {
80 +                       .left = 0,
81 +                       .top = 0,
82 +                       .width = 2592,
83 +                       .height = 1944
84 +               },
85                 ov5647_2592x1944_10bit,
86                 ARRAY_SIZE(ov5647_2592x1944_10bit)
87         },
88 @@ -635,6 +639,12 @@ static struct ov5647_mode supported_mode
89                         .width = 1920,
90                         .height = 1080
91                 },
92 +               .crop = {
93 +                       .left = 348,
94 +                       .top = 434,
95 +                       .width = 1928,
96 +                       .height = 1080,
97 +               },
98                 ov5647_1080p30_10bit,
99                 ARRAY_SIZE(ov5647_1080p30_10bit)
100         },
101 @@ -649,6 +659,12 @@ static struct ov5647_mode supported_mode
102                         .width = 1296,
103                         .height = 972
104                 },
105 +               .crop = {
106 +                       .left = 0,
107 +                       .top = 0,
108 +                       .width = 2592,
109 +                       .height = 1944,
110 +               },
111                 ov5647_2x2binned_10bit,
112                 ARRAY_SIZE(ov5647_2x2binned_10bit)
113         },
114 @@ -664,6 +680,12 @@ static struct ov5647_mode supported_mode
115                         .width = 640,
116                         .height = 480
117                 },
118 +               .crop = {
119 +                       .left = 16,
120 +                       .top = 0,
121 +                       .width = 2560,
122 +                       .height = 1920,
123 +               },
124                 ov5647_640x480_10bit,
125                 ARRAY_SIZE(ov5647_640x480_10bit)
126         },
127 @@ -971,6 +993,56 @@ static const struct v4l2_subdev_core_ops
128  #endif
129  };
130  
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)
134 +{
135 +       switch (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;
140 +       }
141 +
142 +       return NULL;
143 +}
144 +
145 +static int ov5647_get_selection(struct v4l2_subdev *sd,
146 +                               struct v4l2_subdev_pad_config *cfg,
147 +                               struct v4l2_subdev_selection *sel)
148 +{
149 +       switch (sel->target) {
150 +       case V4L2_SEL_TGT_CROP: {
151 +               struct ov5647 *state = to_state(sd);
152 +
153 +               mutex_lock(&state->lock);
154 +               sel->r = *__ov5647_get_pad_crop(state, cfg, sel->pad,
155 +                                               sel->which);
156 +               mutex_unlock(&state->lock);
157 +
158 +               return 0;
159 +       }
160 +
161 +       case V4L2_SEL_TGT_NATIVE_SIZE:
162 +               sel->r.top = 0;
163 +               sel->r.left = 0;
164 +               sel->r.width = OV5647_NATIVE_WIDTH;
165 +               sel->r.height = OV5647_NATIVE_HEIGHT;
166 +
167 +               return 0;
168 +
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;
174 +
175 +               return 0;
176 +       }
177 +
178 +       return -EINVAL;
179 +}
180 +
181  static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
182  {
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,
190  };
191  
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);
195  
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;
204  
205         /* Set the default format to the same as the sensor. */
206         *format = state->mode->format;