bcm27xx: add support for linux v5.15
[openwrt/staging/ldir.git] / target / linux / bcm27xx / patches-5.15 / 950-0736-media-i2c-ov7251-Separate-modes-from-frame-intervals.patch
1 From 65e773354de288401a6c498d006b47b7f87e0936 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 17 Feb 2022 17:00:27 +0000
4 Subject: [PATCH] media: i2c: ov7251: Separate modes from frame
5 intervals
6
7 The modes and frame intervals are independent, therefore
8 separate them into 2 structures.
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
11 ---
12 drivers/media/i2c/ov7251.c | 85 ++++++++++++++++++--------------------
13 1 file changed, 41 insertions(+), 44 deletions(-)
14
15 --- a/drivers/media/i2c/ov7251.c
16 +++ b/drivers/media/i2c/ov7251.c
17 @@ -79,14 +79,17 @@ struct reg_value {
18 u8 val;
19 };
20
21 +struct ov7251_frame_ival_info {
22 + u16 vts;
23 + struct v4l2_fract timeperframe;
24 +};
25 +
26 struct ov7251_mode_info {
27 u32 width;
28 u32 height;
29 const struct reg_value *data;
30 u32 data_size;
31 u16 exposure_def;
32 - u16 vts;
33 - struct v4l2_fract timeperframe;
34 };
35
36 struct ov7251_pll1_config {
37 @@ -128,6 +131,7 @@ struct ov7251 {
38 struct regulator *analog_regulator;
39
40 const struct ov7251_mode_info *current_mode;
41 + const struct ov7251_frame_ival_info *current_ival;
42
43 struct v4l2_ctrl_handler ctrls;
44 struct v4l2_ctrl *exposure;
45 @@ -343,13 +347,8 @@ static const s64 link_freq[] = {
46 240000000,
47 };
48
49 -static const struct ov7251_mode_info ov7251_mode_info_data[] = {
50 +static const struct ov7251_frame_ival_info ov7251_frame_ival_info_data[] = {
51 {
52 - .width = 640,
53 - .height = 480,
54 - .data = ov7251_setting_vga,
55 - .data_size = ARRAY_SIZE(ov7251_setting_vga),
56 - .exposure_def = 504,
57 .vts = 0x6bc,
58 .timeperframe = {
59 .numerator = 100,
60 @@ -357,11 +356,6 @@ static const struct ov7251_mode_info ov7
61 }
62 },
63 {
64 - .width = 640,
65 - .height = 480,
66 - .data = ov7251_setting_vga,
67 - .data_size = ARRAY_SIZE(ov7251_setting_vga),
68 - .exposure_def = 504,
69 .vts = 0x35c,
70 .timeperframe = {
71 .numerator = 100,
72 @@ -369,11 +363,6 @@ static const struct ov7251_mode_info ov7
73 }
74 },
75 {
76 - .width = 640,
77 - .height = 480,
78 - .data = ov7251_setting_vga,
79 - .data_size = ARRAY_SIZE(ov7251_setting_vga),
80 - .exposure_def = 504,
81 .vts = 0x23c,
82 .timeperframe = {
83 .numerator = 100,
84 @@ -382,6 +371,16 @@ static const struct ov7251_mode_info ov7
85 },
86 };
87
88 +static const struct ov7251_mode_info ov7251_mode_info_data[] = {
89 + {
90 + .width = 640,
91 + .height = 480,
92 + .data = ov7251_setting_vga,
93 + .data_size = ARRAY_SIZE(ov7251_setting_vga),
94 + .exposure_def = 504,
95 + },
96 +};
97 +
98 static int ov7251_regulators_enable(struct ov7251 *ov7251)
99 {
100 int ret;
101 @@ -789,13 +788,13 @@ static int ov7251_enum_frame_ival(struct
102 unsigned int index = fie->index;
103 unsigned int i;
104
105 - for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
106 - if (fie->width != ov7251_mode_info_data[i].width ||
107 - fie->height != ov7251_mode_info_data[i].height)
108 + for (i = 0; i < ARRAY_SIZE(ov7251_frame_ival_info_data); i++) {
109 + if (fie->width != ov7251_mode_info_data[0].width ||
110 + fie->height != ov7251_mode_info_data[0].height)
111 continue;
112
113 if (index-- == 0) {
114 - fie->interval = ov7251_mode_info_data[i].timeperframe;
115 + fie->interval = ov7251_frame_ival_info_data[i].timeperframe;
116 return 0;
117 }
118 }
119 @@ -854,23 +853,18 @@ static inline u32 avg_fps(const struct v
120 return (t->denominator + (t->numerator >> 1)) / t->numerator;
121 }
122
123 -static const struct ov7251_mode_info *
124 -ov7251_find_mode_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe)
125 +static const struct ov7251_frame_ival_info *
126 +ov7251_find_frame_ival_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe)
127 {
128 - const struct ov7251_mode_info *mode = ov7251->current_mode;
129 unsigned int fps_req = avg_fps(timeperframe);
130 unsigned int max_dist_match = (unsigned int) -1;
131 unsigned int i, n = 0;
132
133 - for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) {
134 + for (i = 0; i < ARRAY_SIZE(ov7251_frame_ival_info_data); i++) {
135 unsigned int dist;
136 unsigned int fps_tmp;
137
138 - if (mode->width != ov7251_mode_info_data[i].width ||
139 - mode->height != ov7251_mode_info_data[i].height)
140 - continue;
141 -
142 - fps_tmp = avg_fps(&ov7251_mode_info_data[i].timeperframe);
143 + fps_tmp = avg_fps(&ov7251_frame_ival_info_data[i].timeperframe);
144
145 dist = abs(fps_req - fps_tmp);
146
147 @@ -880,7 +874,7 @@ ov7251_find_mode_by_ival(struct ov7251 *
148 }
149 }
150
151 - return &ov7251_mode_info_data[n];
152 + return &ov7251_frame_ival_info_data[n];
153 }
154
155 static int ov7251_set_format(struct v4l2_subdev *sd,
156 @@ -914,7 +908,8 @@ static int ov7251_set_format(struct v4l2
157 __v4l2_ctrl_s_ctrl(ov7251->hblank, h_blank);
158
159 ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1,
160 - new_mode->vts - OV7251_EXPOSURE_OFFSET,
161 + ov7251->current_ival->vts -
162 + OV7251_EXPOSURE_OFFSET,
163 1, new_mode->exposure_def);
164 if (ret < 0)
165 goto exit;
166 @@ -1036,11 +1031,11 @@ static int ov7251_s_stream(struct v4l2_s
167 goto err_power_down;
168 }
169 ret = ov7251_write_reg(ov7251, OV7251_VTS_HIGH,
170 - ov7251->current_mode->vts >> 8);
171 + ov7251->current_ival->vts >> 8);
172 if (ret)
173 goto err_power_down;
174 ret = ov7251_write_reg(ov7251, OV7251_VTS_LOW,
175 - ov7251->current_mode->vts & 0xff);
176 + ov7251->current_ival->vts & 0xff);
177 if (ret)
178 goto err_power_down;
179 ret = __v4l2_ctrl_handler_setup(&ov7251->ctrls);
180 @@ -1073,7 +1068,7 @@ static int ov7251_get_frame_interval(str
181 struct ov7251 *ov7251 = to_ov7251(subdev);
182
183 mutex_lock(&ov7251->lock);
184 - fi->interval = ov7251->current_mode->timeperframe;
185 + fi->interval = ov7251->current_ival->timeperframe;
186 mutex_unlock(&ov7251->lock);
187
188 return 0;
189 @@ -1083,28 +1078,29 @@ static int ov7251_set_frame_interval(str
190 struct v4l2_subdev_frame_interval *fi)
191 {
192 struct ov7251 *ov7251 = to_ov7251(subdev);
193 - const struct ov7251_mode_info *new_mode;
194 + const struct ov7251_frame_ival_info *new_ival;
195 int ret = 0;
196
197 mutex_lock(&ov7251->lock);
198 - new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval);
199 + new_ival = ov7251_find_frame_ival_by_ival(ov7251, &fi->interval);
200
201 - if (new_mode != ov7251->current_mode) {
202 + if (new_ival != ov7251->current_ival) {
203 ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1,
204 - new_mode->vts - OV7251_EXPOSURE_OFFSET,
205 - 1, new_mode->exposure_def);
206 + new_ival->vts -
207 + OV7251_EXPOSURE_OFFSET,
208 + 1, ov7251->current_mode->exposure_def);
209 if (ret < 0)
210 goto exit;
211
212 ret = __v4l2_ctrl_s_ctrl(ov7251->exposure,
213 - new_mode->exposure_def);
214 + ov7251->current_mode->exposure_def);
215 if (ret < 0)
216 goto exit;
217
218 - ov7251->current_mode = new_mode;
219 + ov7251->current_ival = new_ival;
220 }
221
222 - fi->interval = ov7251->current_mode->timeperframe;
223 + fi->interval = ov7251->current_ival->timeperframe;
224
225 exit:
226 mutex_unlock(&ov7251->lock);
227 @@ -1316,6 +1312,7 @@ static int ov7251_probe(struct i2c_clien
228 mutex_init(&ov7251->lock);
229
230 ov7251->current_mode = &ov7251_mode_info_data[0];
231 + ov7251->current_ival = &ov7251_frame_ival_info_data[0];
232
233 v4l2_ctrl_handler_init(&ov7251->ctrls, 10);
234 ov7251->ctrls.lock = &ov7251->lock;