c8c8abf070242cea0242cd94cdab23c0af3a1a50
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0173-V4L2-Initial-pass-at-scene-modes.patch
1 From ba09044961948d93db7aa166f2829d46e81e875a Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dsteve@broadcom.com>
3 Date: Fri, 14 Feb 2014 17:12:08 +0000
4 Subject: [PATCH 173/174] V4L2: Initial pass at scene modes.
5
6 Only supports exposure mode and metering modes.
7
8 Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
9 ---
10 drivers/media/platform/bcm2835/bcm2835-camera.h | 10 +-
11 drivers/media/platform/bcm2835/controls.c | 225 ++++++++++++++++++++----
12 2 files changed, 199 insertions(+), 36 deletions(-)
13
14 --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
15 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
16 @@ -15,7 +15,7 @@
17 * core driver device
18 */
19
20 -#define V4L2_CTRL_COUNT 24 /* number of v4l controls */
21 +#define V4L2_CTRL_COUNT 25 /* number of v4l controls */
22
23 enum {
24 MMAL_COMPONENT_CAMERA = 0,
25 @@ -45,11 +45,15 @@ struct bm2835_mmal_dev {
26 /* controls */
27 struct v4l2_ctrl_handler ctrl_handler;
28 struct v4l2_ctrl *ctrls[V4L2_CTRL_COUNT];
29 + enum v4l2_scene_mode scene_mode;
30 struct mmal_colourfx colourfx;
31 int hflip;
32 int vflip;
33 - enum mmal_parameter_exposuremode exposure_mode;
34 - enum v4l2_exposure_auto_type exposure_mode_v4l2;
35 + enum mmal_parameter_exposuremode exposure_mode_user;
36 + enum v4l2_exposure_auto_type exposure_mode_v4l2_user;
37 + /* active exposure mode may differ if selected via a scene mode */
38 + enum mmal_parameter_exposuremode exposure_mode_active;
39 + enum mmal_parameter_exposuremeteringmode metering_mode;
40 unsigned int manual_shutter_speed;
41 bool exp_auto_priority;
42
43 --- a/drivers/media/platform/bcm2835/controls.c
44 +++ b/drivers/media/platform/bcm2835/controls.c
45 @@ -145,6 +145,25 @@ static const struct v4l2_to_mmal_effects
46 1, 1, 0, 0, 0, {0, 0, 0, 0, 0} }
47 };
48
49 +struct v4l2_mmal_scene_config {
50 + enum v4l2_scene_mode v4l2_scene;
51 + enum mmal_parameter_exposuremode exposure_mode;
52 + enum mmal_parameter_exposuremeteringmode metering_mode;
53 +};
54 +
55 +static const struct v4l2_mmal_scene_config scene_configs[] = {
56 + /* V4L2_SCENE_MODE_NONE automatically added */
57 + {
58 + V4L2_SCENE_MODE_NIGHT,
59 + MMAL_PARAM_EXPOSUREMODE_NIGHT,
60 + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
61 + },
62 + {
63 + V4L2_SCENE_MODE_SPORTS,
64 + MMAL_PARAM_EXPOSUREMODE_SPORTS,
65 + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
66 + },
67 +};
68
69 /* control handlers*/
70
71 @@ -296,7 +315,7 @@ static int ctrl_set_exposure(struct bm28
72 struct v4l2_ctrl *ctrl,
73 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
74 {
75 - enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode;
76 + enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user;
77 u32 shutter_speed = 0;
78 struct vchiq_mmal_port *control;
79 int ret = 0;
80 @@ -317,31 +336,32 @@ static int ctrl_set_exposure(struct bm28
81 case V4L2_EXPOSURE_MANUAL:
82 exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF;
83 break;
84 -
85 - case V4L2_EXPOSURE_SHUTTER_PRIORITY:
86 - exp_mode = MMAL_PARAM_EXPOSUREMODE_SPORTS;
87 - break;
88 -
89 - case V4L2_EXPOSURE_APERTURE_PRIORITY:
90 - exp_mode = MMAL_PARAM_EXPOSUREMODE_NIGHT;
91 - break;
92 -
93 }
94 - dev->exposure_mode = exp_mode;
95 - dev->exposure_mode_v4l2 = ctrl->val;
96 + dev->exposure_mode_user = exp_mode;
97 + dev->exposure_mode_v4l2_user = ctrl->val;
98 } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) {
99 dev->exp_auto_priority = ctrl->val;
100 }
101
102 - if (dev->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
103 - shutter_speed = dev->manual_shutter_speed;
104 + if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
105 + if (exp_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
106 + shutter_speed = dev->manual_shutter_speed;
107
108 - ret = vchiq_mmal_port_parameter_set(dev->instance, control,
109 - MMAL_PARAMETER_SHUTTER_SPEED,
110 - &shutter_speed, sizeof(shutter_speed));
111 - ret += vchiq_mmal_port_parameter_set(dev->instance, control,
112 - MMAL_PARAMETER_EXPOSURE_MODE,
113 - &exp_mode, sizeof(u32));
114 + ret = vchiq_mmal_port_parameter_set(dev->instance,
115 + control,
116 + MMAL_PARAMETER_SHUTTER_SPEED,
117 + &shutter_speed,
118 + sizeof(shutter_speed));
119 + ret += vchiq_mmal_port_parameter_set(dev->instance,
120 + control,
121 + MMAL_PARAMETER_EXPOSURE_MODE,
122 + &exp_mode,
123 + sizeof(u32));
124 + dev->exposure_mode_active = exp_mode;
125 + }
126 + /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should
127 + * always apply irrespective of scene mode.
128 + */
129 ret += set_framerate_params(dev);
130
131 return ret;
132 @@ -351,35 +371,38 @@ static int ctrl_set_metering_mode(struct
133 struct v4l2_ctrl *ctrl,
134 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
135 {
136 - u32 u32_value;
137 - struct vchiq_mmal_port *control;
138 -
139 - control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
140 -
141 switch (ctrl->val) {
142 case V4L2_EXPOSURE_METERING_AVERAGE:
143 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
144 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
145 break;
146
147 case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
148 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
149 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
150 break;
151
152 case V4L2_EXPOSURE_METERING_SPOT:
153 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
154 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
155 break;
156
157 /* todo matrix weighting not added to Linux API till 3.9
158 case V4L2_EXPOSURE_METERING_MATRIX:
159 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
160 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
161 break;
162 */
163
164 }
165
166 - return vchiq_mmal_port_parameter_set(dev->instance, control,
167 + if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
168 + struct vchiq_mmal_port *control;
169 + u32 u32_value = dev->metering_mode;
170 +
171 + control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
172 +
173 + return vchiq_mmal_port_parameter_set(dev->instance, control,
174 mmal_ctrl->mmal_id,
175 &u32_value, sizeof(u32_value));
176 + } else
177 + return 0;
178 }
179
180 static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev,
181 @@ -738,6 +761,113 @@ static int ctrl_set_video_encode_profile
182 return ret;
183 }
184
185 +static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev,
186 + struct v4l2_ctrl *ctrl,
187 + const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
188 +{
189 + int ret = 0;
190 + int shutter_speed;
191 + struct vchiq_mmal_port *control;
192 +
193 + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
194 + "scene mode selected %d, was %d\n", ctrl->val,
195 + dev->scene_mode);
196 + control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
197 +
198 + if (ctrl->val == dev->scene_mode)
199 + return 0;
200 +
201 + if (ctrl->val == V4L2_SCENE_MODE_NONE) {
202 + /* Restore all user selections */
203 + dev->scene_mode = V4L2_SCENE_MODE_NONE;
204 +
205 + if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF)
206 + shutter_speed = dev->manual_shutter_speed;
207 + else
208 + shutter_speed = 0;
209 +
210 + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
211 + "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
212 + __func__, shutter_speed, dev->exposure_mode_user,
213 + dev->metering_mode);
214 + ret = vchiq_mmal_port_parameter_set(dev->instance,
215 + control,
216 + MMAL_PARAMETER_SHUTTER_SPEED,
217 + &shutter_speed,
218 + sizeof(shutter_speed));
219 + ret += vchiq_mmal_port_parameter_set(dev->instance,
220 + control,
221 + MMAL_PARAMETER_EXPOSURE_MODE,
222 + &dev->exposure_mode_user,
223 + sizeof(u32));
224 + dev->exposure_mode_active = dev->exposure_mode_user;
225 + ret += vchiq_mmal_port_parameter_set(dev->instance,
226 + control,
227 + MMAL_PARAMETER_EXP_METERING_MODE,
228 + &dev->metering_mode,
229 + sizeof(u32));
230 + ret += set_framerate_params(dev);
231 + } else {
232 + /* Set up scene mode */
233 + int i;
234 + const struct v4l2_mmal_scene_config *scene = NULL;
235 + int shutter_speed;
236 + enum mmal_parameter_exposuremode exposure_mode;
237 + enum mmal_parameter_exposuremeteringmode metering_mode;
238 +
239 + for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
240 + if (scene_configs[i].v4l2_scene ==
241 + ctrl->val) {
242 + scene = &scene_configs[i];
243 + break;
244 + }
245 + }
246 + if (i >= ARRAY_SIZE(scene_configs))
247 + return -EINVAL;
248 +
249 + /* Set all the values */
250 + dev->scene_mode = ctrl->val;
251 +
252 + if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
253 + shutter_speed = dev->manual_shutter_speed;
254 + else
255 + shutter_speed = 0;
256 + exposure_mode = scene->exposure_mode;
257 + metering_mode = scene->metering_mode;
258 +
259 + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
260 + "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
261 + __func__, shutter_speed, exposure_mode, metering_mode);
262 +
263 + ret = vchiq_mmal_port_parameter_set(dev->instance, control,
264 + MMAL_PARAMETER_SHUTTER_SPEED,
265 + &shutter_speed,
266 + sizeof(shutter_speed));
267 + ret += vchiq_mmal_port_parameter_set(dev->instance,
268 + control,
269 + MMAL_PARAMETER_EXPOSURE_MODE,
270 + &exposure_mode,
271 + sizeof(u32));
272 + dev->exposure_mode_active = exposure_mode;
273 + ret += vchiq_mmal_port_parameter_set(dev->instance, control,
274 + MMAL_PARAMETER_EXPOSURE_MODE,
275 + &exposure_mode,
276 + sizeof(u32));
277 + ret += vchiq_mmal_port_parameter_set(dev->instance, control,
278 + MMAL_PARAMETER_EXP_METERING_MODE,
279 + &metering_mode,
280 + sizeof(u32));
281 + ret += set_framerate_params(dev);
282 + }
283 + if (ret) {
284 + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
285 + "%s: Setting scene to %d, ret=%d\n",
286 + __func__, ctrl->val, ret);
287 + ret = -EINVAL;
288 + }
289 + return 0;
290 +}
291 +
292 static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
293 {
294 struct bm2835_mmal_dev *dev =
295 @@ -973,6 +1103,15 @@ static const struct bm2835_mmal_v4l2_ctr
296 &ctrl_set_video_encode_profile_level,
297 false
298 },
299 + {
300 + V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU,
301 + -1, /* Min is computed at runtime */
302 + V4L2_SCENE_MODE_TEXT,
303 + V4L2_SCENE_MODE_NONE, 1, NULL,
304 + MMAL_PARAMETER_PROFILE,
305 + &ctrl_set_scene_mode,
306 + false
307 + },
308 };
309
310 int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
311 @@ -1000,8 +1139,7 @@ int set_framerate_params(struct bm2835_m
312 struct mmal_parameter_fps_range fps_range;
313 int ret;
314
315 - if ((dev->exposure_mode_v4l2 == V4L2_EXPOSURE_AUTO ||
316 - dev->exposure_mode_v4l2 == V4L2_EXPOSURE_APERTURE_PRIORITY) &&
317 + if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) &&
318 (dev->exp_auto_priority)) {
319 /* Variable FPS. Define min FPS as 1fps.
320 * Max as max defined FPS.
321 @@ -1049,6 +1187,7 @@ int set_framerate_params(struct bm2835_m
322 return ret;
323
324 }
325 +
326 int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
327 struct v4l2_ctrl_handler *hdl)
328 {
329 @@ -1068,10 +1207,30 @@ int bm2835_mmal_init_controls(struct bm2
330 break;
331
332 case MMAL_CONTROL_TYPE_STD_MENU:
333 + {
334 + int mask = ctrl->min;
335 +
336 + if (ctrl->id == V4L2_CID_SCENE_MODE) {
337 + /* Special handling to work out the mask
338 + * value based on the scene_configs array
339 + * at runtime. Reduces the chance of
340 + * mismatches.
341 + */
342 + int i;
343 + mask = 1<<V4L2_SCENE_MODE_NONE;
344 + for (i = 0;
345 + i < ARRAY_SIZE(scene_configs);
346 + i++) {
347 + mask |= 1<<scene_configs[i].v4l2_scene;
348 + }
349 + mask = ~mask;
350 + }
351 +
352 dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl,
353 &bm2835_mmal_ctrl_ops, ctrl->id,
354 - ctrl->max, ctrl->min, ctrl->def);
355 + ctrl->max, mask, ctrl->def);
356 break;
357 + }
358
359 case MMAL_CONTROL_TYPE_INT_MENU:
360 dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl,