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