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.
6 Only supports exposure mode and metering modes.
8 Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
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(-)
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
22 -#define V4L2_CTRL_COUNT 24 /* number of v4l controls */
23 +#define V4L2_CTRL_COUNT 25 /* number of v4l controls */
26 MMAL_COMPONENT_CAMERA = 0,
27 @@ -45,11 +45,15 @@ struct bm2835_mmal_dev {
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;
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;
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} }
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;
59 +static const struct v4l2_mmal_scene_config scene_configs[] = {
60 + /* V4L2_SCENE_MODE_NONE automatically added */
62 + V4L2_SCENE_MODE_NIGHT,
63 + MMAL_PARAM_EXPOSUREMODE_NIGHT,
64 + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
67 + V4L2_SCENE_MODE_SPORTS,
68 + MMAL_PARAM_EXPOSUREMODE_SPORTS,
69 + MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
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)
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;
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;
89 - case V4L2_EXPOSURE_SHUTTER_PRIORITY:
90 - exp_mode = MMAL_PARAM_EXPOSUREMODE_SPORTS;
93 - case V4L2_EXPOSURE_APERTURE_PRIORITY:
94 - exp_mode = MMAL_PARAM_EXPOSUREMODE_NIGHT;
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;
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;
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,
120 + MMAL_PARAMETER_SHUTTER_SPEED,
122 + sizeof(shutter_speed));
123 + ret += vchiq_mmal_port_parameter_set(dev->instance,
125 + MMAL_PARAMETER_EXPOSURE_MODE,
128 + dev->exposure_mode_active = exp_mode;
130 + /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should
131 + * always apply irrespective of scene mode.
133 ret += set_framerate_params(dev);
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)
141 - struct vchiq_mmal_port *control;
143 - control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
146 case V4L2_EXPOSURE_METERING_AVERAGE:
147 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
148 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
151 case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
152 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
153 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
156 case V4L2_EXPOSURE_METERING_SPOT:
157 - u32_value = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
158 + dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
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;
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;
175 + control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
177 + return vchiq_mmal_port_parameter_set(dev->instance, control,
179 &u32_value, sizeof(u32_value));
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,
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)
195 + struct vchiq_mmal_port *control;
197 + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
198 + "scene mode selected %d, was %d\n", ctrl->val,
200 + control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
202 + if (ctrl->val == dev->scene_mode)
205 + if (ctrl->val == V4L2_SCENE_MODE_NONE) {
206 + /* Restore all user selections */
207 + dev->scene_mode = V4L2_SCENE_MODE_NONE;
209 + if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF)
210 + shutter_speed = dev->manual_shutter_speed;
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,
220 + MMAL_PARAMETER_SHUTTER_SPEED,
222 + sizeof(shutter_speed));
223 + ret += vchiq_mmal_port_parameter_set(dev->instance,
225 + MMAL_PARAMETER_EXPOSURE_MODE,
226 + &dev->exposure_mode_user,
228 + dev->exposure_mode_active = dev->exposure_mode_user;
229 + ret += vchiq_mmal_port_parameter_set(dev->instance,
231 + MMAL_PARAMETER_EXP_METERING_MODE,
232 + &dev->metering_mode,
234 + ret += set_framerate_params(dev);
236 + /* Set up scene mode */
238 + const struct v4l2_mmal_scene_config *scene = NULL;
240 + enum mmal_parameter_exposuremode exposure_mode;
241 + enum mmal_parameter_exposuremeteringmode metering_mode;
243 + for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
244 + if (scene_configs[i].v4l2_scene ==
246 + scene = &scene_configs[i];
250 + if (i >= ARRAY_SIZE(scene_configs))
253 + /* Set all the values */
254 + dev->scene_mode = ctrl->val;
256 + if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
257 + shutter_speed = dev->manual_shutter_speed;
260 + exposure_mode = scene->exposure_mode;
261 + metering_mode = scene->metering_mode;
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);
267 + ret = vchiq_mmal_port_parameter_set(dev->instance, control,
268 + MMAL_PARAMETER_SHUTTER_SPEED,
270 + sizeof(shutter_speed));
271 + ret += vchiq_mmal_port_parameter_set(dev->instance,
273 + MMAL_PARAMETER_EXPOSURE_MODE,
276 + dev->exposure_mode_active = exposure_mode;
277 + ret += vchiq_mmal_port_parameter_set(dev->instance, control,
278 + MMAL_PARAMETER_EXPOSURE_MODE,
281 + ret += vchiq_mmal_port_parameter_set(dev->instance, control,
282 + MMAL_PARAMETER_EXP_METERING_MODE,
285 + ret += set_framerate_params(dev);
288 + v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
289 + "%s: Setting scene to %d, ret=%d\n",
290 + __func__, ctrl->val, ret);
296 static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
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,
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,
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;
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)
330 int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
331 struct v4l2_ctrl_handler *hdl)
333 @@ -1068,10 +1207,30 @@ int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
336 case MMAL_CONTROL_TYPE_STD_MENU:
338 + int mask = ctrl->min;
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
347 + mask = 1<<V4L2_SCENE_MODE_NONE;
349 + i < ARRAY_SIZE(scene_configs);
351 + mask |= 1<<scene_configs[i].v4l2_scene;
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);
363 case MMAL_CONTROL_TYPE_INT_MENU:
364 dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl,