xref: /linux/drivers/staging/vc04_services/bcm2835-camera/controls.c (revision a100922a3855eb35ecd465f1d558546b1e144445)
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 			&param, 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