1 /*
2 * Broadcom BM2835 V4L2 driver
3 *
4 * Copyright © 2013 Raspberry Pi (Trading) Ltd.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 *
10 * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk>
11 * Dave Stevenson <dsteve@broadcom.com>
12 * Simon Mellor <simellor@broadcom.com>
13 * Luke Diamand <luked@broadcom.com>
14 */
15
16 #include <linux/errno.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <media/videobuf2-vmalloc.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-ioctl.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-fh.h>
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-common.h>
27
28 #include "mmal-common.h"
29 #include "mmal-vchiq.h"
30 #include "mmal-parameters.h"
31 #include "bcm2835-camera.h"
32
33 /* The supported V4L2_CID_AUTO_EXPOSURE_BIAS values are from -4.0 to +4.0.
34 * MMAL values are in 1/6th increments so the MMAL range is -24 to +24.
35 * V4L2 docs say value "is expressed in terms of EV, drivers should interpret
36 * the values as 0.001 EV units, where the value 1000 stands for +1 EV."
37 * V4L2 is limited to a max of 32 values in a menu, so count in 1/3rds from
38 * -4 to +4
39 */
40 static const s64 ev_bias_qmenu[] = {
41 -4000, -3667, -3333,
42 -3000, -2667, -2333,
43 -2000, -1667, -1333,
44 -1000, -667, -333,
45 0, 333, 667,
46 1000, 1333, 1667,
47 2000, 2333, 2667,
48 3000, 3333, 3667,
49 4000
50 };
51
52 /* Supported ISO values (*1000)
53 * ISOO = auto ISO
54 */
55 static const s64 iso_qmenu[] = {
56 0, 100000, 200000, 400000, 800000,
57 };
58 static const uint32_t iso_values[] = {
59 0, 100, 200, 400, 800,
60 };
61
62 static const s64 mains_freq_qmenu[] = {
63 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED,
64 V4L2_CID_POWER_LINE_FREQUENCY_50HZ,
65 V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
66 V4L2_CID_POWER_LINE_FREQUENCY_AUTO
67 };
68
69 /* Supported video encode modes */
70 static const s64 bitrate_mode_qmenu[] = {
71 (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
72 (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
73 };
74
75 enum bm2835_mmal_ctrl_type {
76 MMAL_CONTROL_TYPE_STD,
77 MMAL_CONTROL_TYPE_STD_MENU,
78 MMAL_CONTROL_TYPE_INT_MENU,
79 MMAL_CONTROL_TYPE_CLUSTER, /* special cluster entry */
80 };
81
82 struct bm2835_mmal_v4l2_ctrl;
83
84 typedef int(bm2835_mmal_v4l2_ctrl_cb)(
85 struct bm2835_mmal_dev *dev,
86 struct v4l2_ctrl *ctrl,
87 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl);
88
89 struct bm2835_mmal_v4l2_ctrl {
90 u32 id; /* v4l2 control identifier */
91 enum bm2835_mmal_ctrl_type type;
92 /* control minimum value or
93 * mask for MMAL_CONTROL_TYPE_STD_MENU
94 */
95 s32 min;
96 s32 max; /* maximum value of control */
97 s32 def; /* default value of control */
98 s32 step; /* step size of the control */
99 const s64 *imenu; /* integer menu array */
100 u32 mmal_id; /* mmal parameter id */
101 bm2835_mmal_v4l2_ctrl_cb *setter;
102 bool ignore_errors;
103 };
104
105 struct v4l2_to_mmal_effects_setting {
106 u32 v4l2_effect;
107 u32 mmal_effect;
108 s32 col_fx_enable;
109 s32 col_fx_fixed_cbcr;
110 u32 u;
111 u32 v;
112 u32 num_effect_params;
113 u32 effect_params[MMAL_MAX_IMAGEFX_PARAMETERS];
114 };
115
116 static const struct v4l2_to_mmal_effects_setting
117 v4l2_to_mmal_effects_values[] = {
118 { V4L2_COLORFX_NONE, MMAL_PARAM_IMAGEFX_NONE,
119 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
120 { V4L2_COLORFX_BW, MMAL_PARAM_IMAGEFX_NONE,
121 1, 0, 128, 128, 0, {0, 0, 0, 0, 0} },
122 { V4L2_COLORFX_SEPIA, MMAL_PARAM_IMAGEFX_NONE,
123 1, 0, 87, 151, 0, {0, 0, 0, 0, 0} },
124 { V4L2_COLORFX_NEGATIVE, MMAL_PARAM_IMAGEFX_NEGATIVE,
125 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
126 { V4L2_COLORFX_EMBOSS, MMAL_PARAM_IMAGEFX_EMBOSS,
127 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
128 { V4L2_COLORFX_SKETCH, MMAL_PARAM_IMAGEFX_SKETCH,
129 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
130 { V4L2_COLORFX_SKY_BLUE, MMAL_PARAM_IMAGEFX_PASTEL,
131 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
132 { V4L2_COLORFX_GRASS_GREEN, MMAL_PARAM_IMAGEFX_WATERCOLOUR,
133 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
134 { V4L2_COLORFX_SKIN_WHITEN, MMAL_PARAM_IMAGEFX_WASHEDOUT,
135 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
136 { V4L2_COLORFX_VIVID, MMAL_PARAM_IMAGEFX_SATURATION,
137 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
138 { V4L2_COLORFX_AQUA, MMAL_PARAM_IMAGEFX_NONE,
139 1, 0, 171, 121, 0, {0, 0, 0, 0, 0} },
140 { V4L2_COLORFX_ART_FREEZE, MMAL_PARAM_IMAGEFX_HATCH,
141 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
142 { V4L2_COLORFX_SILHOUETTE, MMAL_PARAM_IMAGEFX_FILM,
143 0, 0, 0, 0, 0, {0, 0, 0, 0, 0} },
144 { V4L2_COLORFX_SOLARIZATION, MMAL_PARAM_IMAGEFX_SOLARIZE,
145 0, 0, 0, 0, 5, {1, 128, 160, 160, 48} },
146 { V4L2_COLORFX_ANTIQUE, MMAL_PARAM_IMAGEFX_COLOURBALANCE,
147 0, 0, 0, 0, 3, {108, 274, 238, 0, 0} },
148 { V4L2_COLORFX_SET_CBCR, MMAL_PARAM_IMAGEFX_NONE,
149 1, 1, 0, 0, 0, {0, 0, 0, 0, 0} }
150 };
151
152 struct v4l2_mmal_scene_config {
153 enum v4l2_scene_mode v4l2_scene;
154 enum mmal_parameter_exposuremode exposure_mode;
155 enum mmal_parameter_exposuremeteringmode metering_mode;
156 };
157
158 static const struct v4l2_mmal_scene_config scene_configs[] = {
159 /* V4L2_SCENE_MODE_NONE automatically added */
160 {
161 V4L2_SCENE_MODE_NIGHT,
162 MMAL_PARAM_EXPOSUREMODE_NIGHT,
163 MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
164 },
165 {
166 V4L2_SCENE_MODE_SPORTS,
167 MMAL_PARAM_EXPOSUREMODE_SPORTS,
168 MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
169 },
170 };
171
172 /* control handlers*/
173
ctrl_set_rational(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)174 static int ctrl_set_rational(struct bm2835_mmal_dev *dev,
175 struct v4l2_ctrl *ctrl,
176 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
177 {
178 struct mmal_parameter_rational rational_value;
179 struct vchiq_mmal_port *control;
180
181 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
182
183 rational_value.num = ctrl->val;
184 rational_value.den = 100;
185
186 return vchiq_mmal_port_parameter_set(dev->instance, control,
187 mmal_ctrl->mmal_id,
188 &rational_value,
189 sizeof(rational_value));
190 }
191
ctrl_set_value(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)192 static int ctrl_set_value(struct bm2835_mmal_dev *dev,
193 struct v4l2_ctrl *ctrl,
194 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
195 {
196 u32 u32_value;
197 struct vchiq_mmal_port *control;
198
199 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
200
201 u32_value = ctrl->val;
202
203 return vchiq_mmal_port_parameter_set(dev->instance, control,
204 mmal_ctrl->mmal_id,
205 &u32_value, sizeof(u32_value));
206 }
207
ctrl_set_iso(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)208 static int ctrl_set_iso(struct bm2835_mmal_dev *dev,
209 struct v4l2_ctrl *ctrl,
210 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
211 {
212 u32 u32_value;
213 struct vchiq_mmal_port *control;
214
215 if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min)
216 return 1;
217
218 if (ctrl->id == V4L2_CID_ISO_SENSITIVITY)
219 dev->iso = iso_values[ctrl->val];
220 else if (ctrl->id == V4L2_CID_ISO_SENSITIVITY_AUTO)
221 dev->manual_iso_enabled =
222 (ctrl->val == V4L2_ISO_SENSITIVITY_MANUAL);
223
224 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
225
226 if (dev->manual_iso_enabled)
227 u32_value = dev->iso;
228 else
229 u32_value = 0;
230
231 return vchiq_mmal_port_parameter_set(dev->instance, control,
232 MMAL_PARAMETER_ISO,
233 &u32_value, sizeof(u32_value));
234 }
235
ctrl_set_value_ev(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)236 static int ctrl_set_value_ev(struct bm2835_mmal_dev *dev,
237 struct v4l2_ctrl *ctrl,
238 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
239 {
240 s32 s32_value;
241 struct vchiq_mmal_port *control;
242
243 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
244
245 s32_value = (ctrl->val - 12) * 2; /* Convert from index to 1/6ths */
246
247 return vchiq_mmal_port_parameter_set(dev->instance, control,
248 mmal_ctrl->mmal_id,
249 &s32_value, sizeof(s32_value));
250 }
251
ctrl_set_rotate(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)252 static int ctrl_set_rotate(struct bm2835_mmal_dev *dev,
253 struct v4l2_ctrl *ctrl,
254 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
255 {
256 int ret;
257 u32 u32_value;
258 struct vchiq_mmal_component *camera;
259
260 camera = dev->component[MMAL_COMPONENT_CAMERA];
261
262 u32_value = ((ctrl->val % 360) / 90) * 90;
263
264 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0],
265 mmal_ctrl->mmal_id,
266 &u32_value, sizeof(u32_value));
267 if (ret < 0)
268 return ret;
269
270 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1],
271 mmal_ctrl->mmal_id,
272 &u32_value, sizeof(u32_value));
273 if (ret < 0)
274 return ret;
275
276 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2],
277 mmal_ctrl->mmal_id,
278 &u32_value, sizeof(u32_value));
279
280 return ret;
281 }
282
ctrl_set_flip(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)283 static int ctrl_set_flip(struct bm2835_mmal_dev *dev,
284 struct v4l2_ctrl *ctrl,
285 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
286 {
287 int ret;
288 u32 u32_value;
289 struct vchiq_mmal_component *camera;
290
291 if (ctrl->id == V4L2_CID_HFLIP)
292 dev->hflip = ctrl->val;
293 else
294 dev->vflip = ctrl->val;
295
296 camera = dev->component[MMAL_COMPONENT_CAMERA];
297
298 if (dev->hflip && dev->vflip)
299 u32_value = MMAL_PARAM_MIRROR_BOTH;
300 else if (dev->hflip)
301 u32_value = MMAL_PARAM_MIRROR_HORIZONTAL;
302 else if (dev->vflip)
303 u32_value = MMAL_PARAM_MIRROR_VERTICAL;
304 else
305 u32_value = MMAL_PARAM_MIRROR_NONE;
306
307 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0],
308 mmal_ctrl->mmal_id,
309 &u32_value, sizeof(u32_value));
310 if (ret < 0)
311 return ret;
312
313 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1],
314 mmal_ctrl->mmal_id,
315 &u32_value, sizeof(u32_value));
316 if (ret < 0)
317 return ret;
318
319 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2],
320 mmal_ctrl->mmal_id,
321 &u32_value, sizeof(u32_value));
322
323 return ret;
324 }
325
ctrl_set_exposure(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)326 static int ctrl_set_exposure(struct bm2835_mmal_dev *dev,
327 struct v4l2_ctrl *ctrl,
328 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
329 {
330 enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user;
331 u32 shutter_speed = 0;
332 struct vchiq_mmal_port *control;
333 int ret = 0;
334
335 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
336
337 if (mmal_ctrl->mmal_id == MMAL_PARAMETER_SHUTTER_SPEED) {
338 /* V4L2 is in 100usec increments.
339 * MMAL is 1usec.
340 */
341 dev->manual_shutter_speed = ctrl->val * 100;
342 } else if (mmal_ctrl->mmal_id == MMAL_PARAMETER_EXPOSURE_MODE) {
343 switch (ctrl->val) {
344 case V4L2_EXPOSURE_AUTO:
345 exp_mode = MMAL_PARAM_EXPOSUREMODE_AUTO;
346 break;
347
348 case V4L2_EXPOSURE_MANUAL:
349 exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF;
350 break;
351 }
352 dev->exposure_mode_user = exp_mode;
353 dev->exposure_mode_v4l2_user = ctrl->val;
354 } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) {
355 dev->exp_auto_priority = ctrl->val;
356 }
357
358 if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
359 if (exp_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
360 shutter_speed = dev->manual_shutter_speed;
361
362 ret = vchiq_mmal_port_parameter_set(dev->instance,
363 control,
364 MMAL_PARAMETER_SHUTTER_SPEED,
365 &shutter_speed,
366 sizeof(shutter_speed));
367 ret += vchiq_mmal_port_parameter_set(dev->instance,
368 control,
369 MMAL_PARAMETER_EXPOSURE_MODE,
370 &exp_mode,
371 sizeof(u32));
372 dev->exposure_mode_active = exp_mode;
373 }
374 /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should
375 * always apply irrespective of scene mode.
376 */
377 ret += set_framerate_params(dev);
378
379 return ret;
380 }
381
ctrl_set_metering_mode(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)382 static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev,
383 struct v4l2_ctrl *ctrl,
384 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
385 {
386 switch (ctrl->val) {
387 case V4L2_EXPOSURE_METERING_AVERAGE:
388 dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
389 break;
390
391 case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
392 dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
393 break;
394
395 case V4L2_EXPOSURE_METERING_SPOT:
396 dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
397 break;
398
399 /* todo matrix weighting not added to Linux API till 3.9
400 * case V4L2_EXPOSURE_METERING_MATRIX:
401 * dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_MATRIX;
402 * break;
403 */
404 }
405
406 if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
407 struct vchiq_mmal_port *control;
408 u32 u32_value = dev->metering_mode;
409
410 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
411
412 return vchiq_mmal_port_parameter_set(dev->instance, control,
413 mmal_ctrl->mmal_id,
414 &u32_value, sizeof(u32_value));
415 } else
416 return 0;
417 }
418
ctrl_set_flicker_avoidance(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)419 static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev,
420 struct v4l2_ctrl *ctrl,
421 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
422 {
423 u32 u32_value;
424 struct vchiq_mmal_port *control;
425
426 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
427
428 switch (ctrl->val) {
429 case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
430 u32_value = MMAL_PARAM_FLICKERAVOID_OFF;
431 break;
432 case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
433 u32_value = MMAL_PARAM_FLICKERAVOID_50HZ;
434 break;
435 case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
436 u32_value = MMAL_PARAM_FLICKERAVOID_60HZ;
437 break;
438 case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
439 u32_value = MMAL_PARAM_FLICKERAVOID_AUTO;
440 break;
441 }
442
443 return vchiq_mmal_port_parameter_set(dev->instance, control,
444 mmal_ctrl->mmal_id,
445 &u32_value, sizeof(u32_value));
446 }
447
ctrl_set_awb_mode(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)448 static int ctrl_set_awb_mode(struct bm2835_mmal_dev *dev,
449 struct v4l2_ctrl *ctrl,
450 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
451 {
452 u32 u32_value;
453 struct vchiq_mmal_port *control;
454
455 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
456
457 switch (ctrl->val) {
458 case V4L2_WHITE_BALANCE_MANUAL:
459 u32_value = MMAL_PARAM_AWBMODE_OFF;
460 break;
461
462 case V4L2_WHITE_BALANCE_AUTO:
463 u32_value = MMAL_PARAM_AWBMODE_AUTO;
464 break;
465
466 case V4L2_WHITE_BALANCE_INCANDESCENT:
467 u32_value = MMAL_PARAM_AWBMODE_INCANDESCENT;
468 break;
469
470 case V4L2_WHITE_BALANCE_FLUORESCENT:
471 u32_value = MMAL_PARAM_AWBMODE_FLUORESCENT;
472 break;
473
474 case V4L2_WHITE_BALANCE_FLUORESCENT_H:
475 u32_value = MMAL_PARAM_AWBMODE_TUNGSTEN;
476 break;
477
478 case V4L2_WHITE_BALANCE_HORIZON:
479 u32_value = MMAL_PARAM_AWBMODE_HORIZON;
480 break;
481
482 case V4L2_WHITE_BALANCE_DAYLIGHT:
483 u32_value = MMAL_PARAM_AWBMODE_SUNLIGHT;
484 break;
485
486 case V4L2_WHITE_BALANCE_FLASH:
487 u32_value = MMAL_PARAM_AWBMODE_FLASH;
488 break;
489
490 case V4L2_WHITE_BALANCE_CLOUDY:
491 u32_value = MMAL_PARAM_AWBMODE_CLOUDY;
492 break;
493
494 case V4L2_WHITE_BALANCE_SHADE:
495 u32_value = MMAL_PARAM_AWBMODE_SHADE;
496 break;
497 }
498
499 return vchiq_mmal_port_parameter_set(dev->instance, control,
500 mmal_ctrl->mmal_id,
501 &u32_value, sizeof(u32_value));
502 }
503
ctrl_set_awb_gains(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)504 static int ctrl_set_awb_gains(struct bm2835_mmal_dev *dev,
505 struct v4l2_ctrl *ctrl,
506 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
507 {
508 struct vchiq_mmal_port *control;
509 struct mmal_parameter_awbgains gains;
510
511 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
512
513 if (ctrl->id == V4L2_CID_RED_BALANCE)
514 dev->red_gain = ctrl->val;
515 else if (ctrl->id == V4L2_CID_BLUE_BALANCE)
516 dev->blue_gain = ctrl->val;
517
518 gains.r_gain.num = dev->red_gain;
519 gains.b_gain.num = dev->blue_gain;
520 gains.r_gain.den = gains.b_gain.den = 1000;
521
522 return vchiq_mmal_port_parameter_set(dev->instance, control,
523 mmal_ctrl->mmal_id,
524 &gains, sizeof(gains));
525 }
526
ctrl_set_image_effect(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)527 static int ctrl_set_image_effect(struct bm2835_mmal_dev *dev,
528 struct v4l2_ctrl *ctrl,
529 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
530 {
531 int ret = -EINVAL;
532 int i, j;
533 struct vchiq_mmal_port *control;
534 struct mmal_parameter_imagefx_parameters imagefx;
535
536 for (i = 0; i < ARRAY_SIZE(v4l2_to_mmal_effects_values); i++) {
537 if (ctrl->val == v4l2_to_mmal_effects_values[i].v4l2_effect) {
538 imagefx.effect =
539 v4l2_to_mmal_effects_values[i].mmal_effect;
540 imagefx.num_effect_params =
541 v4l2_to_mmal_effects_values[i].num_effect_params;
542
543 if (imagefx.num_effect_params > MMAL_MAX_IMAGEFX_PARAMETERS)
544 imagefx.num_effect_params = MMAL_MAX_IMAGEFX_PARAMETERS;
545
546 for (j = 0; j < imagefx.num_effect_params; j++)
547 imagefx.effect_parameter[j] =
548 v4l2_to_mmal_effects_values[i].effect_params[j];
549
550 dev->colourfx.enable =
551 v4l2_to_mmal_effects_values[i].col_fx_enable;
552 if (!v4l2_to_mmal_effects_values[i].col_fx_fixed_cbcr) {
553 dev->colourfx.u =
554 v4l2_to_mmal_effects_values[i].u;
555 dev->colourfx.v =
556 v4l2_to_mmal_effects_values[i].v;
557 }
558
559 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
560
561 ret = vchiq_mmal_port_parameter_set(
562 dev->instance, control,
563 MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
564 &imagefx, sizeof(imagefx));
565 if (ret)
566 goto exit;
567
568 ret = vchiq_mmal_port_parameter_set(
569 dev->instance, control,
570 MMAL_PARAMETER_COLOUR_EFFECT,
571 &dev->colourfx, sizeof(dev->colourfx));
572 }
573 }
574
575 exit:
576 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
577 "mmal_ctrl:%p ctrl id:0x%x ctrl val:%d imagefx:0x%x color_effect:%s u:%d v:%d ret %d(%d)\n",
578 mmal_ctrl, ctrl->id, ctrl->val, imagefx.effect,
579 dev->colourfx.enable ? "true" : "false",
580 dev->colourfx.u, dev->colourfx.v,
581 ret, (ret == 0 ? 0 : -EINVAL));
582 return (ret == 0 ? 0 : -EINVAL);
583 }
584
ctrl_set_colfx(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)585 static int ctrl_set_colfx(struct bm2835_mmal_dev *dev,
586 struct v4l2_ctrl *ctrl,
587 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
588 {
589 int ret = -EINVAL;
590 struct vchiq_mmal_port *control;
591
592 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
593
594 dev->colourfx.enable = (ctrl->val & 0xff00) >> 8;
595 dev->colourfx.enable = ctrl->val & 0xff;
596
597 ret = vchiq_mmal_port_parameter_set(dev->instance, control,
598 MMAL_PARAMETER_COLOUR_EFFECT,
599 &dev->colourfx,
600 sizeof(dev->colourfx));
601
602 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
603 "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
604 __func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
605 (ret == 0 ? 0 : -EINVAL));
606 return (ret == 0 ? 0 : -EINVAL);
607 }
608
ctrl_set_bitrate(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)609 static int ctrl_set_bitrate(struct bm2835_mmal_dev *dev,
610 struct v4l2_ctrl *ctrl,
611 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
612 {
613 int ret;
614 struct vchiq_mmal_port *encoder_out;
615
616 dev->capture.encode_bitrate = ctrl->val;
617
618 encoder_out = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0];
619
620 ret = vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
621 mmal_ctrl->mmal_id,
622 &ctrl->val, sizeof(ctrl->val));
623 ret = 0;
624 return ret;
625 }
626
ctrl_set_bitrate_mode(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)627 static int ctrl_set_bitrate_mode(struct bm2835_mmal_dev *dev,
628 struct v4l2_ctrl *ctrl,
629 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
630 {
631 u32 bitrate_mode;
632 struct vchiq_mmal_port *encoder_out;
633
634 encoder_out = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0];
635
636 dev->capture.encode_bitrate_mode = ctrl->val;
637 switch (ctrl->val) {
638 default:
639 case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
640 bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE;
641 break;
642 case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
643 bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT;
644 break;
645 }
646
647 vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
648 mmal_ctrl->mmal_id,
649 &bitrate_mode,
650 sizeof(bitrate_mode));
651 return 0;
652 }
653
ctrl_set_image_encode_output(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)654 static int ctrl_set_image_encode_output(struct bm2835_mmal_dev *dev,
655 struct v4l2_ctrl *ctrl,
656 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
657 {
658 u32 u32_value;
659 struct vchiq_mmal_port *jpeg_out;
660
661 jpeg_out = &dev->component[MMAL_COMPONENT_IMAGE_ENCODE]->output[0];
662
663 u32_value = ctrl->val;
664
665 return vchiq_mmal_port_parameter_set(dev->instance, jpeg_out,
666 mmal_ctrl->mmal_id,
667 &u32_value, sizeof(u32_value));
668 }
669
ctrl_set_video_encode_param_output(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)670 static int ctrl_set_video_encode_param_output(struct bm2835_mmal_dev *dev,
671 struct v4l2_ctrl *ctrl,
672 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
673 {
674 u32 u32_value;
675 struct vchiq_mmal_port *vid_enc_ctl;
676
677 vid_enc_ctl = &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0];
678
679 u32_value = ctrl->val;
680
681 return vchiq_mmal_port_parameter_set(dev->instance, vid_enc_ctl,
682 mmal_ctrl->mmal_id,
683 &u32_value, sizeof(u32_value));
684 }
685
ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)686 static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev,
687 struct v4l2_ctrl *ctrl,
688 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
689 {
690 struct mmal_parameter_video_profile param;
691 int ret = 0;
692
693 if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
694 switch (ctrl->val) {
695 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
696 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
697 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
698 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
699 dev->capture.enc_profile = ctrl->val;
700 break;
701 default:
702 ret = -EINVAL;
703 break;
704 }
705 } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
706 switch (ctrl->val) {
707 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
708 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
709 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
710 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
711 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
712 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
713 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
714 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
715 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
716 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
717 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
718 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
719 dev->capture.enc_level = ctrl->val;
720 break;
721 default:
722 ret = -EINVAL;
723 break;
724 }
725 }
726
727 if (!ret) {
728 switch (dev->capture.enc_profile) {
729 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
730 param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
731 break;
732 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
733 param.profile =
734 MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
735 break;
736 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
737 param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
738 break;
739 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
740 param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
741 break;
742 default:
743 /* Should never get here */
744 break;
745 }
746
747 switch (dev->capture.enc_level) {
748 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
749 param.level = MMAL_VIDEO_LEVEL_H264_1;
750 break;
751 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
752 param.level = MMAL_VIDEO_LEVEL_H264_1b;
753 break;
754 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
755 param.level = MMAL_VIDEO_LEVEL_H264_11;
756 break;
757 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
758 param.level = MMAL_VIDEO_LEVEL_H264_12;
759 break;
760 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
761 param.level = MMAL_VIDEO_LEVEL_H264_13;
762 break;
763 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
764 param.level = MMAL_VIDEO_LEVEL_H264_2;
765 break;
766 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
767 param.level = MMAL_VIDEO_LEVEL_H264_21;
768 break;
769 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
770 param.level = MMAL_VIDEO_LEVEL_H264_22;
771 break;
772 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
773 param.level = MMAL_VIDEO_LEVEL_H264_3;
774 break;
775 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
776 param.level = MMAL_VIDEO_LEVEL_H264_31;
777 break;
778 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
779 param.level = MMAL_VIDEO_LEVEL_H264_32;
780 break;
781 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
782 param.level = MMAL_VIDEO_LEVEL_H264_4;
783 break;
784 default:
785 /* Should never get here */
786 break;
787 }
788
789 ret = vchiq_mmal_port_parameter_set(dev->instance,
790 &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0],
791 mmal_ctrl->mmal_id,
792 ¶m, sizeof(param));
793 }
794 return ret;
795 }
796
ctrl_set_scene_mode(struct bm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bm2835_mmal_v4l2_ctrl * mmal_ctrl)797 static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev,
798 struct v4l2_ctrl *ctrl,
799 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
800 {
801 int ret = 0;
802 int shutter_speed;
803 struct vchiq_mmal_port *control;
804
805 v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
806 "scene mode selected %d, was %d\n", ctrl->val,
807 dev->scene_mode);
808 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
809
810 if (ctrl->val == dev->scene_mode)
811 return 0;
812
813 if (ctrl->val == V4L2_SCENE_MODE_NONE) {
814 /* Restore all user selections */
815 dev->scene_mode = V4L2_SCENE_MODE_NONE;
816
817 if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF)
818 shutter_speed = dev->manual_shutter_speed;
819 else
820 shutter_speed = 0;
821
822 v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
823 "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
824 __func__, shutter_speed, dev->exposure_mode_user,
825 dev->metering_mode);
826 ret = vchiq_mmal_port_parameter_set(dev->instance,
827 control,
828 MMAL_PARAMETER_SHUTTER_SPEED,
829 &shutter_speed,
830 sizeof(shutter_speed));
831 ret += vchiq_mmal_port_parameter_set(dev->instance,
832 control,
833 MMAL_PARAMETER_EXPOSURE_MODE,
834 &dev->exposure_mode_user,
835 sizeof(u32));
836 dev->exposure_mode_active = dev->exposure_mode_user;
837 ret += vchiq_mmal_port_parameter_set(dev->instance,
838 control,
839 MMAL_PARAMETER_EXP_METERING_MODE,
840 &dev->metering_mode,
841 sizeof(u32));
842 ret += set_framerate_params(dev);
843 } else {
844 /* Set up scene mode */
845 int i;
846 const struct v4l2_mmal_scene_config *scene = NULL;
847 int shutter_speed;
848 enum mmal_parameter_exposuremode exposure_mode;
849 enum mmal_parameter_exposuremeteringmode metering_mode;
850
851 for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
852 if (scene_configs[i].v4l2_scene ==
853 ctrl->val) {
854 scene = &scene_configs[i];
855 break;
856 }
857 }
858 if (!scene)
859 return -EINVAL;
860 if (i >= ARRAY_SIZE(scene_configs))
861 return -EINVAL;
862
863 /* Set all the values */
864 dev->scene_mode = ctrl->val;
865
866 if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
867 shutter_speed = dev->manual_shutter_speed;
868 else
869 shutter_speed = 0;
870 exposure_mode = scene->exposure_mode;
871 metering_mode = scene->metering_mode;
872
873 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
874 "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
875 __func__, shutter_speed, exposure_mode, metering_mode);
876
877 ret = vchiq_mmal_port_parameter_set(dev->instance, control,
878 MMAL_PARAMETER_SHUTTER_SPEED,
879 &shutter_speed,
880 sizeof(shutter_speed));
881 ret += vchiq_mmal_port_parameter_set(dev->instance, control,
882 MMAL_PARAMETER_EXPOSURE_MODE,
883 &exposure_mode,
884 sizeof(u32));
885 dev->exposure_mode_active = exposure_mode;
886 ret += vchiq_mmal_port_parameter_set(dev->instance, control,
887 MMAL_PARAMETER_EXPOSURE_MODE,
888 &exposure_mode,
889 sizeof(u32));
890 ret += vchiq_mmal_port_parameter_set(dev->instance, control,
891 MMAL_PARAMETER_EXP_METERING_MODE,
892 &metering_mode,
893 sizeof(u32));
894 ret += set_framerate_params(dev);
895 }
896 if (ret) {
897 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
898 "%s: Setting scene to %d, ret=%d\n",
899 __func__, ctrl->val, ret);
900 ret = -EINVAL;
901 }
902 return 0;
903 }
904
bm2835_mmal_s_ctrl(struct v4l2_ctrl * ctrl)905 static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
906 {
907 struct bm2835_mmal_dev *dev =
908 container_of(ctrl->handler, struct bm2835_mmal_dev,
909 ctrl_handler);
910 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv;
911 int ret;
912
913 if (!mmal_ctrl || mmal_ctrl->id != ctrl->id || !mmal_ctrl->setter) {
914 pr_warn("mmal_ctrl:%p ctrl id:%d\n", mmal_ctrl, ctrl->id);
915 return -EINVAL;
916 }
917
918 ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl);
919 if (ret)
920 pr_warn("ctrl id:%d/MMAL param %08X- returned ret %d\n",
921 ctrl->id, mmal_ctrl->mmal_id, ret);
922 if (mmal_ctrl->ignore_errors)
923 ret = 0;
924 return ret;
925 }
926
927 static const struct v4l2_ctrl_ops bm2835_mmal_ctrl_ops = {
928 .s_ctrl = bm2835_mmal_s_ctrl,
929 };
930
931 static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
932 {
933 V4L2_CID_SATURATION, MMAL_CONTROL_TYPE_STD,
934 -100, 100, 0, 1, NULL,
935 MMAL_PARAMETER_SATURATION,
936 &ctrl_set_rational,
937 false
938 },
939 {
940 V4L2_CID_SHARPNESS, MMAL_CONTROL_TYPE_STD,
941 -100, 100, 0, 1, NULL,
942 MMAL_PARAMETER_SHARPNESS,
943 &ctrl_set_rational,
944 false
945 },
946 {
947 V4L2_CID_CONTRAST, MMAL_CONTROL_TYPE_STD,
948 -100, 100, 0, 1, NULL,
949 MMAL_PARAMETER_CONTRAST,
950 &ctrl_set_rational,
951 false
952 },
953 {
954 V4L2_CID_BRIGHTNESS, MMAL_CONTROL_TYPE_STD,
955 0, 100, 50, 1, NULL,
956 MMAL_PARAMETER_BRIGHTNESS,
957 &ctrl_set_rational,
958 false
959 },
960 {
961 V4L2_CID_ISO_SENSITIVITY, MMAL_CONTROL_TYPE_INT_MENU,
962 0, ARRAY_SIZE(iso_qmenu) - 1, 0, 1, iso_qmenu,
963 MMAL_PARAMETER_ISO,
964 &ctrl_set_iso,
965 false
966 },
967 {
968 V4L2_CID_ISO_SENSITIVITY_AUTO, MMAL_CONTROL_TYPE_STD_MENU,
969 0, 1, V4L2_ISO_SENSITIVITY_AUTO, 1, NULL,
970 MMAL_PARAMETER_ISO,
971 &ctrl_set_iso,
972 false
973 },
974 {
975 V4L2_CID_IMAGE_STABILIZATION, MMAL_CONTROL_TYPE_STD,
976 0, 1, 0, 1, NULL,
977 MMAL_PARAMETER_VIDEO_STABILISATION,
978 &ctrl_set_value,
979 false
980 },
981 /* {
982 * 0, MMAL_CONTROL_TYPE_CLUSTER, 3, 1, 0, NULL, 0, NULL
983 * },
984 */
985 {
986 V4L2_CID_EXPOSURE_AUTO, MMAL_CONTROL_TYPE_STD_MENU,
987 ~0x03, 3, V4L2_EXPOSURE_AUTO, 0, NULL,
988 MMAL_PARAMETER_EXPOSURE_MODE,
989 &ctrl_set_exposure,
990 false
991 },
992 /* todo this needs mixing in with set exposure
993 * {
994 * V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU,
995 * },
996 */
997 {
998 V4L2_CID_EXPOSURE_ABSOLUTE, MMAL_CONTROL_TYPE_STD,
999 /* Units of 100usecs */
1000 1, 1 * 1000 * 10, 100 * 10, 1, NULL,
1001 MMAL_PARAMETER_SHUTTER_SPEED,
1002 &ctrl_set_exposure,
1003 false
1004 },
1005 {
1006 V4L2_CID_AUTO_EXPOSURE_BIAS, MMAL_CONTROL_TYPE_INT_MENU,
1007 0, ARRAY_SIZE(ev_bias_qmenu) - 1,
1008 (ARRAY_SIZE(ev_bias_qmenu) + 1) / 2 - 1, 0, ev_bias_qmenu,
1009 MMAL_PARAMETER_EXPOSURE_COMP,
1010 &ctrl_set_value_ev,
1011 false
1012 },
1013 {
1014 V4L2_CID_EXPOSURE_AUTO_PRIORITY, MMAL_CONTROL_TYPE_STD,
1015 0, 1,
1016 0, 1, NULL,
1017 0, /* Dummy MMAL ID as it gets mapped into FPS range*/
1018 &ctrl_set_exposure,
1019 false
1020 },
1021 {
1022 V4L2_CID_EXPOSURE_METERING,
1023 MMAL_CONTROL_TYPE_STD_MENU,
1024 ~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL,
1025 MMAL_PARAMETER_EXP_METERING_MODE,
1026 &ctrl_set_metering_mode,
1027 false
1028 },
1029 {
1030 V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
1031 MMAL_CONTROL_TYPE_STD_MENU,
1032 ~0x3ff, 9, V4L2_WHITE_BALANCE_AUTO, 0, NULL,
1033 MMAL_PARAMETER_AWB_MODE,
1034 &ctrl_set_awb_mode,
1035 false
1036 },
1037 {
1038 V4L2_CID_RED_BALANCE, MMAL_CONTROL_TYPE_STD,
1039 1, 7999, 1000, 1, NULL,
1040 MMAL_PARAMETER_CUSTOM_AWB_GAINS,
1041 &ctrl_set_awb_gains,
1042 false
1043 },
1044 {
1045 V4L2_CID_BLUE_BALANCE, MMAL_CONTROL_TYPE_STD,
1046 1, 7999, 1000, 1, NULL,
1047 MMAL_PARAMETER_CUSTOM_AWB_GAINS,
1048 &ctrl_set_awb_gains,
1049 false
1050 },
1051 {
1052 V4L2_CID_COLORFX, MMAL_CONTROL_TYPE_STD_MENU,
1053 0, 15, V4L2_COLORFX_NONE, 0, NULL,
1054 MMAL_PARAMETER_IMAGE_EFFECT,
1055 &ctrl_set_image_effect,
1056 false
1057 },
1058 {
1059 V4L2_CID_COLORFX_CBCR, MMAL_CONTROL_TYPE_STD,
1060 0, 0xffff, 0x8080, 1, NULL,
1061 MMAL_PARAMETER_COLOUR_EFFECT,
1062 &ctrl_set_colfx,
1063 false
1064 },
1065 {
1066 V4L2_CID_ROTATE, MMAL_CONTROL_TYPE_STD,
1067 0, 360, 0, 90, NULL,
1068 MMAL_PARAMETER_ROTATION,
1069 &ctrl_set_rotate,
1070 false
1071 },
1072 {
1073 V4L2_CID_HFLIP, MMAL_CONTROL_TYPE_STD,
1074 0, 1, 0, 1, NULL,
1075 MMAL_PARAMETER_MIRROR,
1076 &ctrl_set_flip,
1077 false
1078 },
1079 {
1080 V4L2_CID_VFLIP, MMAL_CONTROL_TYPE_STD,
1081 0, 1, 0, 1, NULL,
1082 MMAL_PARAMETER_MIRROR,
1083 &ctrl_set_flip,
1084 false
1085 },
1086 {
1087 V4L2_CID_MPEG_VIDEO_BITRATE_MODE, MMAL_CONTROL_TYPE_STD_MENU,
1088 0, ARRAY_SIZE(bitrate_mode_qmenu) - 1,
1089 0, 0, bitrate_mode_qmenu,
1090 MMAL_PARAMETER_RATECONTROL,
1091 &ctrl_set_bitrate_mode,
1092 false
1093 },
1094 {
1095 V4L2_CID_MPEG_VIDEO_BITRATE, MMAL_CONTROL_TYPE_STD,
1096 25 * 1000, 25 * 1000 * 1000, 10 * 1000 * 1000, 25 * 1000, NULL,
1097 MMAL_PARAMETER_VIDEO_BIT_RATE,
1098 &ctrl_set_bitrate,
1099 false
1100 },
1101 {
1102 V4L2_CID_JPEG_COMPRESSION_QUALITY, MMAL_CONTROL_TYPE_STD,
1103 1, 100,
1104 30, 1, NULL,
1105 MMAL_PARAMETER_JPEG_Q_FACTOR,
1106 &ctrl_set_image_encode_output,
1107 false
1108 },
1109 {
1110 V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU,
1111 0, ARRAY_SIZE(mains_freq_qmenu) - 1,
1112 1, 1, NULL,
1113 MMAL_PARAMETER_FLICKER_AVOID,
1114 &ctrl_set_flicker_avoidance,
1115 false
1116 },
1117 {
1118 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, MMAL_CONTROL_TYPE_STD,
1119 0, 1,
1120 0, 1, NULL,
1121 MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER,
1122 &ctrl_set_video_encode_param_output,
1123 true /* Errors ignored as requires latest firmware to work */
1124 },
1125 {
1126 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1127 MMAL_CONTROL_TYPE_STD_MENU,
1128 ~((1<<V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
1129 (1<<V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
1130 (1<<V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
1131 (1<<V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
1132 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
1133 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1, NULL,
1134 MMAL_PARAMETER_PROFILE,
1135 &ctrl_set_video_encode_profile_level,
1136 false
1137 },
1138 {
1139 V4L2_CID_MPEG_VIDEO_H264_LEVEL, MMAL_CONTROL_TYPE_STD_MENU,
1140 ~((1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
1141 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
1142 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
1143 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
1144 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
1145 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
1146 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
1147 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
1148 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
1149 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
1150 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
1151 (1<<V4L2_MPEG_VIDEO_H264_LEVEL_4_0)),
1152 V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
1153 V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 1, NULL,
1154 MMAL_PARAMETER_PROFILE,
1155 &ctrl_set_video_encode_profile_level,
1156 false
1157 },
1158 {
1159 V4L2_CID_SCENE_MODE, MMAL_CONTROL_TYPE_STD_MENU,
1160 -1, /* Min is computed at runtime */
1161 V4L2_SCENE_MODE_TEXT,
1162 V4L2_SCENE_MODE_NONE, 1, NULL,
1163 MMAL_PARAMETER_PROFILE,
1164 &ctrl_set_scene_mode,
1165 false
1166 },
1167 {
1168 V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, MMAL_CONTROL_TYPE_STD,
1169 0, 0x7FFFFFFF, 60, 1, NULL,
1170 MMAL_PARAMETER_INTRAPERIOD,
1171 &ctrl_set_video_encode_param_output,
1172 false
1173 },
1174 };
1175
bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev * dev)1176 int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
1177 {
1178 int c;
1179 int ret = 0;
1180
1181 for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1182 if ((dev->ctrls[c]) && (v4l2_ctrls[c].setter)) {
1183 ret = v4l2_ctrls[c].setter(dev, dev->ctrls[c],
1184 &v4l2_ctrls[c]);
1185 if (!v4l2_ctrls[c].ignore_errors && ret) {
1186 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1187 "Failed when setting default values for ctrl %d\n",
1188 c);
1189 break;
1190 }
1191 }
1192 }
1193 return ret;
1194 }
1195
set_framerate_params(struct bm2835_mmal_dev * dev)1196 int set_framerate_params(struct bm2835_mmal_dev *dev)
1197 {
1198 struct mmal_parameter_fps_range fps_range;
1199 int ret;
1200
1201 if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) &&
1202 (dev->exp_auto_priority)) {
1203 /* Variable FPS. Define min FPS as 1fps.
1204 * Max as max defined FPS.
1205 */
1206 fps_range.fps_low.num = 1;
1207 fps_range.fps_low.den = 1;
1208 fps_range.fps_high.num = dev->capture.timeperframe.denominator;
1209 fps_range.fps_high.den = dev->capture.timeperframe.numerator;
1210 } else {
1211 /* Fixed FPS - set min and max to be the same */
1212 fps_range.fps_low.num = fps_range.fps_high.num =
1213 dev->capture.timeperframe.denominator;
1214 fps_range.fps_low.den = fps_range.fps_high.den =
1215 dev->capture.timeperframe.numerator;
1216 }
1217
1218 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1219 "Set fps range to %d/%d to %d/%d\n",
1220 fps_range.fps_low.num,
1221 fps_range.fps_low.den,
1222 fps_range.fps_high.num,
1223 fps_range.fps_high.den);
1224
1225 ret = vchiq_mmal_port_parameter_set(dev->instance,
1226 &dev->component[MMAL_COMPONENT_CAMERA]->
1227 output[MMAL_CAMERA_PORT_PREVIEW],
1228 MMAL_PARAMETER_FPS_RANGE,
1229 &fps_range, sizeof(fps_range));
1230 ret += vchiq_mmal_port_parameter_set(dev->instance,
1231 &dev->component[MMAL_COMPONENT_CAMERA]->
1232 output[MMAL_CAMERA_PORT_VIDEO],
1233 MMAL_PARAMETER_FPS_RANGE,
1234 &fps_range, sizeof(fps_range));
1235 ret += vchiq_mmal_port_parameter_set(dev->instance,
1236 &dev->component[MMAL_COMPONENT_CAMERA]->
1237 output[MMAL_CAMERA_PORT_CAPTURE],
1238 MMAL_PARAMETER_FPS_RANGE,
1239 &fps_range, sizeof(fps_range));
1240 if (ret)
1241 v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
1242 "Failed to set fps ret %d\n", ret);
1243
1244 return ret;
1245 }
1246
bm2835_mmal_init_controls(struct bm2835_mmal_dev * dev,struct v4l2_ctrl_handler * hdl)1247 int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
1248 struct v4l2_ctrl_handler *hdl)
1249 {
1250 int c;
1251 const struct bm2835_mmal_v4l2_ctrl *ctrl;
1252
1253 v4l2_ctrl_handler_init(hdl, V4L2_CTRL_COUNT);
1254
1255 for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1256 ctrl = &v4l2_ctrls[c];
1257
1258 switch (ctrl->type) {
1259 case MMAL_CONTROL_TYPE_STD:
1260 dev->ctrls[c] = v4l2_ctrl_new_std(hdl,
1261 &bm2835_mmal_ctrl_ops, ctrl->id,
1262 ctrl->min, ctrl->max, ctrl->step, ctrl->def);
1263 break;
1264
1265 case MMAL_CONTROL_TYPE_STD_MENU:
1266 {
1267 int mask = ctrl->min;
1268
1269 if (ctrl->id == V4L2_CID_SCENE_MODE) {
1270 /* Special handling to work out the mask
1271 * value based on the scene_configs array
1272 * at runtime. Reduces the chance of
1273 * mismatches.
1274 */
1275 int i;
1276 mask = 1 << V4L2_SCENE_MODE_NONE;
1277 for (i = 0;
1278 i < ARRAY_SIZE(scene_configs);
1279 i++) {
1280 mask |= 1 << scene_configs[i].v4l2_scene;
1281 }
1282 mask = ~mask;
1283 }
1284
1285 dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl,
1286 &bm2835_mmal_ctrl_ops, ctrl->id,
1287 ctrl->max, mask, ctrl->def);
1288 break;
1289 }
1290
1291 case MMAL_CONTROL_TYPE_INT_MENU:
1292 dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl,
1293 &bm2835_mmal_ctrl_ops, ctrl->id,
1294 ctrl->max, ctrl->def, ctrl->imenu);
1295 break;
1296
1297 case MMAL_CONTROL_TYPE_CLUSTER:
1298 /* skip this entry when constructing controls */
1299 continue;
1300 }
1301
1302 if (hdl->error)
1303 break;
1304
1305 dev->ctrls[c]->priv = (void *)ctrl;
1306 }
1307
1308 if (hdl->error) {
1309 pr_err("error adding control %d/%d id 0x%x\n", c,
1310 V4L2_CTRL_COUNT, ctrl->id);
1311 return hdl->error;
1312 }
1313
1314 for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1315 ctrl = &v4l2_ctrls[c];
1316
1317 switch (ctrl->type) {
1318 case MMAL_CONTROL_TYPE_CLUSTER:
1319 v4l2_ctrl_auto_cluster(ctrl->min,
1320 &dev->ctrls[c + 1],
1321 ctrl->max,
1322 ctrl->def);
1323 break;
1324
1325 case MMAL_CONTROL_TYPE_STD:
1326 case MMAL_CONTROL_TYPE_STD_MENU:
1327 case MMAL_CONTROL_TYPE_INT_MENU:
1328 break;
1329 }
1330 }
1331
1332 return 0;
1333 }
1334