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