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