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