• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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 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(
537 				dev->instance, control,
538 				MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
539 				&imagefx, sizeof(imagefx));
540 		if (ret)
541 			goto exit;
542 
543 		ret = vchiq_mmal_port_parameter_set(
544 				dev->instance, control,
545 				MMAL_PARAMETER_COLOUR_EFFECT,
546 				&dev->colourfx, sizeof(dev->colourfx));
547 	}
548 
549 exit:
550 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
551 		 "mmal_ctrl:%p ctrl id:0x%x ctrl val:%d imagefx:0x%x color_effect:%s u:%d v:%d ret %d(%d)\n",
552 				mmal_ctrl, ctrl->id, ctrl->val, imagefx.effect,
553 				dev->colourfx.enable ? "true" : "false",
554 				dev->colourfx.u, dev->colourfx.v,
555 				ret, (ret == 0 ? 0 : -EINVAL));
556 	return (ret == 0 ? 0 : -EINVAL);
557 }
558 
ctrl_set_colfx(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)559 static int ctrl_set_colfx(struct bcm2835_mmal_dev *dev,
560 			  struct v4l2_ctrl *ctrl,
561 			  const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
562 {
563 	int ret;
564 	struct vchiq_mmal_port *control;
565 
566 	control = &dev->component[COMP_CAMERA]->control;
567 
568 	dev->colourfx.u = (ctrl->val & 0xff00) >> 8;
569 	dev->colourfx.v = ctrl->val & 0xff;
570 
571 	ret = vchiq_mmal_port_parameter_set(dev->instance, control,
572 					    MMAL_PARAMETER_COLOUR_EFFECT,
573 					    &dev->colourfx,
574 					    sizeof(dev->colourfx));
575 
576 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
577 		 "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
578 			__func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
579 			(ret == 0 ? 0 : -EINVAL));
580 	return (ret == 0 ? 0 : -EINVAL);
581 }
582 
ctrl_set_bitrate(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)583 static int ctrl_set_bitrate(struct bcm2835_mmal_dev *dev,
584 			    struct v4l2_ctrl *ctrl,
585 			    const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
586 {
587 	int ret;
588 	struct vchiq_mmal_port *encoder_out;
589 
590 	dev->capture.encode_bitrate = ctrl->val;
591 
592 	encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0];
593 
594 	ret = vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
595 					    mmal_ctrl->mmal_id, &ctrl->val,
596 					    sizeof(ctrl->val));
597 
598 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
599 		 "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
600 		 __func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
601 		 (ret == 0 ? 0 : -EINVAL));
602 
603 	/*
604 	 * Older firmware versions (pre July 2019) have a bug in handling
605 	 * MMAL_PARAMETER_VIDEO_BIT_RATE that result in the call
606 	 * returning -MMAL_MSG_STATUS_EINVAL. So ignore errors from this call.
607 	 */
608 	return 0;
609 }
610 
ctrl_set_bitrate_mode(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)611 static int ctrl_set_bitrate_mode(struct bcm2835_mmal_dev *dev,
612 				 struct v4l2_ctrl *ctrl,
613 				 const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
614 {
615 	u32 bitrate_mode;
616 	struct vchiq_mmal_port *encoder_out;
617 
618 	encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0];
619 
620 	dev->capture.encode_bitrate_mode = ctrl->val;
621 	switch (ctrl->val) {
622 	default:
623 	case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
624 		bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE;
625 		break;
626 	case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
627 		bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT;
628 		break;
629 	}
630 
631 	vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
632 				      mmal_ctrl->mmal_id,
633 					     &bitrate_mode,
634 					     sizeof(bitrate_mode));
635 	return 0;
636 }
637 
ctrl_set_image_encode_output(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)638 static int ctrl_set_image_encode_output(struct bcm2835_mmal_dev *dev,
639 					struct v4l2_ctrl *ctrl,
640 					const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
641 {
642 	u32 u32_value;
643 	struct vchiq_mmal_port *jpeg_out;
644 
645 	jpeg_out = &dev->component[COMP_IMAGE_ENCODE]->output[0];
646 
647 	u32_value = ctrl->val;
648 
649 	return vchiq_mmal_port_parameter_set(dev->instance, jpeg_out,
650 					     mmal_ctrl->mmal_id,
651 					     &u32_value, sizeof(u32_value));
652 }
653 
ctrl_set_video_encode_param_output(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)654 static int ctrl_set_video_encode_param_output(struct bcm2835_mmal_dev *dev,
655 					      struct v4l2_ctrl *ctrl,
656 					      const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
657 {
658 	u32 u32_value;
659 	struct vchiq_mmal_port *vid_enc_ctl;
660 
661 	vid_enc_ctl = &dev->component[COMP_VIDEO_ENCODE]->output[0];
662 
663 	u32_value = ctrl->val;
664 
665 	return vchiq_mmal_port_parameter_set(dev->instance, vid_enc_ctl,
666 					     mmal_ctrl->mmal_id,
667 					     &u32_value, sizeof(u32_value));
668 }
669 
ctrl_set_video_encode_profile_level(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)670 static int ctrl_set_video_encode_profile_level(struct bcm2835_mmal_dev *dev,
671 					       struct v4l2_ctrl *ctrl,
672 					       const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
673 {
674 	struct mmal_parameter_video_profile param;
675 	int ret = 0;
676 
677 	if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
678 		switch (ctrl->val) {
679 		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
680 		case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
681 		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
682 		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
683 			dev->capture.enc_profile = ctrl->val;
684 			break;
685 		default:
686 			ret = -EINVAL;
687 			break;
688 		}
689 	} else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
690 		switch (ctrl->val) {
691 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
692 		case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
693 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
694 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
695 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
696 		case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
697 		case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
698 		case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
699 		case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
700 		case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
701 		case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
702 		case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
703 			dev->capture.enc_level = ctrl->val;
704 			break;
705 		default:
706 			ret = -EINVAL;
707 			break;
708 		}
709 	}
710 
711 	if (!ret) {
712 		switch (dev->capture.enc_profile) {
713 		case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
714 			param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
715 			break;
716 		case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
717 			param.profile =
718 				MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
719 			break;
720 		case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
721 			param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
722 			break;
723 		case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
724 			param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
725 			break;
726 		default:
727 			/* Should never get here */
728 			break;
729 		}
730 
731 		switch (dev->capture.enc_level) {
732 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
733 			param.level = MMAL_VIDEO_LEVEL_H264_1;
734 			break;
735 		case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
736 			param.level = MMAL_VIDEO_LEVEL_H264_1b;
737 			break;
738 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
739 			param.level = MMAL_VIDEO_LEVEL_H264_11;
740 			break;
741 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
742 			param.level = MMAL_VIDEO_LEVEL_H264_12;
743 			break;
744 		case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
745 			param.level = MMAL_VIDEO_LEVEL_H264_13;
746 			break;
747 		case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
748 			param.level = MMAL_VIDEO_LEVEL_H264_2;
749 			break;
750 		case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
751 			param.level = MMAL_VIDEO_LEVEL_H264_21;
752 			break;
753 		case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
754 			param.level = MMAL_VIDEO_LEVEL_H264_22;
755 			break;
756 		case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
757 			param.level = MMAL_VIDEO_LEVEL_H264_3;
758 			break;
759 		case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
760 			param.level = MMAL_VIDEO_LEVEL_H264_31;
761 			break;
762 		case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
763 			param.level = MMAL_VIDEO_LEVEL_H264_32;
764 			break;
765 		case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
766 			param.level = MMAL_VIDEO_LEVEL_H264_4;
767 			break;
768 		default:
769 			/* Should never get here */
770 			break;
771 		}
772 
773 		ret = vchiq_mmal_port_parameter_set(dev->instance,
774 						    &dev->component[COMP_VIDEO_ENCODE]->output[0],
775 			mmal_ctrl->mmal_id,
776 			&param, sizeof(param));
777 	}
778 	return ret;
779 }
780 
ctrl_set_scene_mode(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl * ctrl,const struct bcm2835_mmal_v4l2_ctrl * mmal_ctrl)781 static int ctrl_set_scene_mode(struct bcm2835_mmal_dev *dev,
782 			       struct v4l2_ctrl *ctrl,
783 			       const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
784 {
785 	int ret = 0;
786 	int shutter_speed;
787 	struct vchiq_mmal_port *control;
788 
789 	v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
790 		 "scene mode selected %d, was %d\n", ctrl->val,
791 		 dev->scene_mode);
792 	control = &dev->component[COMP_CAMERA]->control;
793 
794 	if (ctrl->val == dev->scene_mode)
795 		return 0;
796 
797 	if (ctrl->val == V4L2_SCENE_MODE_NONE) {
798 		/* Restore all user selections */
799 		dev->scene_mode = V4L2_SCENE_MODE_NONE;
800 
801 		if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF)
802 			shutter_speed = dev->manual_shutter_speed;
803 		else
804 			shutter_speed = 0;
805 
806 		v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
807 			 "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
808 			 __func__, shutter_speed, dev->exposure_mode_user,
809 			 dev->metering_mode);
810 		ret = vchiq_mmal_port_parameter_set(dev->instance,
811 						    control,
812 						    MMAL_PARAMETER_SHUTTER_SPEED,
813 						    &shutter_speed,
814 						    sizeof(shutter_speed));
815 		ret += vchiq_mmal_port_parameter_set(dev->instance,
816 						     control,
817 						     MMAL_PARAMETER_EXPOSURE_MODE,
818 						     &dev->exposure_mode_user,
819 						     sizeof(u32));
820 		dev->exposure_mode_active = dev->exposure_mode_user;
821 		ret += vchiq_mmal_port_parameter_set(dev->instance,
822 						     control,
823 						     MMAL_PARAMETER_EXP_METERING_MODE,
824 						     &dev->metering_mode,
825 						     sizeof(u32));
826 		ret += set_framerate_params(dev);
827 	} else {
828 		/* Set up scene mode */
829 		int i;
830 		const struct v4l2_mmal_scene_config *scene = NULL;
831 		int shutter_speed;
832 		enum mmal_parameter_exposuremode exposure_mode;
833 		enum mmal_parameter_exposuremeteringmode metering_mode;
834 
835 		for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
836 			if (scene_configs[i].v4l2_scene == ctrl->val) {
837 				scene = &scene_configs[i];
838 				break;
839 			}
840 		}
841 		if (!scene)
842 			return -EINVAL;
843 		if (i >= ARRAY_SIZE(scene_configs))
844 			return -EINVAL;
845 
846 		/* Set all the values */
847 		dev->scene_mode = ctrl->val;
848 
849 		if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
850 			shutter_speed = dev->manual_shutter_speed;
851 		else
852 			shutter_speed = 0;
853 		exposure_mode = scene->exposure_mode;
854 		metering_mode = scene->metering_mode;
855 
856 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
857 			 "%s: scene mode none: shut_speed %d, exp_mode %d, metering %d\n",
858 			 __func__, shutter_speed, exposure_mode, metering_mode);
859 
860 		ret = vchiq_mmal_port_parameter_set(dev->instance, control,
861 						    MMAL_PARAMETER_SHUTTER_SPEED,
862 						    &shutter_speed,
863 						    sizeof(shutter_speed));
864 		ret += vchiq_mmal_port_parameter_set(dev->instance, control,
865 						     MMAL_PARAMETER_EXPOSURE_MODE,
866 						     &exposure_mode,
867 						     sizeof(u32));
868 		dev->exposure_mode_active = exposure_mode;
869 		ret += vchiq_mmal_port_parameter_set(dev->instance, control,
870 						     MMAL_PARAMETER_EXPOSURE_MODE,
871 						     &exposure_mode,
872 						     sizeof(u32));
873 		ret += vchiq_mmal_port_parameter_set(dev->instance, control,
874 						     MMAL_PARAMETER_EXP_METERING_MODE,
875 						     &metering_mode,
876 						     sizeof(u32));
877 		ret += set_framerate_params(dev);
878 	}
879 	if (ret) {
880 		v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
881 			 "%s: Setting scene to %d, ret=%d\n",
882 			 __func__, ctrl->val, ret);
883 		ret = -EINVAL;
884 	}
885 	return 0;
886 }
887 
bcm2835_mmal_s_ctrl(struct v4l2_ctrl * ctrl)888 static int bcm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
889 {
890 	struct bcm2835_mmal_dev *dev = container_of(ctrl->handler, struct bcm2835_mmal_dev,
891 						    ctrl_handler);
892 	const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv;
893 	int ret;
894 
895 	if (!mmal_ctrl || mmal_ctrl->id != ctrl->id || !mmal_ctrl->setter) {
896 		pr_warn("mmal_ctrl:%p ctrl id:%d\n", mmal_ctrl, ctrl->id);
897 		return -EINVAL;
898 	}
899 
900 	ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl);
901 	if (ret)
902 		pr_warn("ctrl id:%d/MMAL param %08X- returned ret %d\n",
903 			ctrl->id, mmal_ctrl->mmal_id, ret);
904 	return ret;
905 }
906 
907 static const struct v4l2_ctrl_ops bcm2835_mmal_ctrl_ops = {
908 	.s_ctrl = bcm2835_mmal_s_ctrl,
909 };
910 
911 static const struct bcm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
912 	{
913 		.id = V4L2_CID_SATURATION,
914 		.type = MMAL_CONTROL_TYPE_STD,
915 		.min = -100,
916 		.max = 100,
917 		.def = 0,
918 		.step = 1,
919 		.imenu = NULL,
920 		.mmal_id = MMAL_PARAMETER_SATURATION,
921 		.setter = ctrl_set_rational,
922 	},
923 	{
924 		.id = V4L2_CID_SHARPNESS,
925 		.type = MMAL_CONTROL_TYPE_STD,
926 		.min = -100,
927 		.max = 100,
928 		.def = 0,
929 		.step = 1,
930 		.imenu = NULL,
931 		.mmal_id = MMAL_PARAMETER_SHARPNESS,
932 		.setter = ctrl_set_rational,
933 	},
934 	{
935 		.id = V4L2_CID_CONTRAST,
936 		.type = MMAL_CONTROL_TYPE_STD,
937 		.min = -100,
938 		.max = 100,
939 		.def = 0,
940 		.step = 1,
941 		.imenu = NULL,
942 		.mmal_id = MMAL_PARAMETER_CONTRAST,
943 		.setter = ctrl_set_rational,
944 	},
945 	{
946 		.id = V4L2_CID_BRIGHTNESS,
947 		.type = MMAL_CONTROL_TYPE_STD,
948 		.min = 0,
949 		.max = 100,
950 		.def = 50,
951 		.step = 1,
952 		.imenu = NULL,
953 		.mmal_id = MMAL_PARAMETER_BRIGHTNESS,
954 		.setter = ctrl_set_rational,
955 	},
956 	{
957 		.id = V4L2_CID_ISO_SENSITIVITY,
958 		.type = MMAL_CONTROL_TYPE_INT_MENU,
959 		.min = 0,
960 		.max = ARRAY_SIZE(iso_qmenu) - 1,
961 		.def = 0,
962 		.step = 1,
963 		.imenu = iso_qmenu,
964 		.mmal_id = MMAL_PARAMETER_ISO,
965 		.setter = ctrl_set_iso,
966 	},
967 	{
968 		.id = V4L2_CID_ISO_SENSITIVITY_AUTO,
969 		.type = MMAL_CONTROL_TYPE_STD_MENU,
970 		.min = 0,
971 		.max = V4L2_ISO_SENSITIVITY_AUTO,
972 		.def = V4L2_ISO_SENSITIVITY_AUTO,
973 		.step = 1,
974 		.imenu = NULL,
975 		.mmal_id = MMAL_PARAMETER_ISO,
976 		.setter = ctrl_set_iso,
977 	},
978 	{
979 		.id = V4L2_CID_IMAGE_STABILIZATION,
980 		.type = MMAL_CONTROL_TYPE_STD,
981 		.min = 0,
982 		.max = 1,
983 		.def = 0,
984 		.step = 1,
985 		.imenu = NULL,
986 		.mmal_id = MMAL_PARAMETER_VIDEO_STABILISATION,
987 		.setter = ctrl_set_value,
988 	},
989 	{
990 		.id = V4L2_CID_EXPOSURE_AUTO,
991 		.type = MMAL_CONTROL_TYPE_STD_MENU,
992 		.min = ~0x03,
993 		.max = V4L2_EXPOSURE_APERTURE_PRIORITY,
994 		.def = V4L2_EXPOSURE_AUTO,
995 		.step = 0,
996 		.imenu = NULL,
997 		.mmal_id = MMAL_PARAMETER_EXPOSURE_MODE,
998 		.setter = ctrl_set_exposure,
999 	},
1000 	{
1001 		.id = V4L2_CID_EXPOSURE_ABSOLUTE,
1002 		.type = MMAL_CONTROL_TYPE_STD,
1003 		/* Units of 100usecs */
1004 		.min = 1,
1005 		.max = 1 * 1000 * 10,
1006 		.def = 100 * 10,
1007 		.step = 1,
1008 		.imenu = NULL,
1009 		.mmal_id = MMAL_PARAMETER_SHUTTER_SPEED,
1010 		.setter = ctrl_set_exposure,
1011 	},
1012 	{
1013 		.id = V4L2_CID_AUTO_EXPOSURE_BIAS,
1014 		.type = MMAL_CONTROL_TYPE_INT_MENU,
1015 		.min = 0,
1016 		.max = ARRAY_SIZE(ev_bias_qmenu) - 1,
1017 		.def = (ARRAY_SIZE(ev_bias_qmenu) + 1) / 2 - 1,
1018 		.step = 0,
1019 		.imenu = ev_bias_qmenu,
1020 		.mmal_id = MMAL_PARAMETER_EXPOSURE_COMP,
1021 		.setter = ctrl_set_value_ev,
1022 	},
1023 	{
1024 		.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
1025 		.type = MMAL_CONTROL_TYPE_STD,
1026 		.min = 0,
1027 		.max = 1,
1028 		.def = 0,
1029 		.step = 1,
1030 		.imenu = NULL,
1031 		/* Dummy MMAL ID as it gets mapped into FPS range */
1032 		.mmal_id = 0,
1033 		.setter = ctrl_set_exposure,
1034 	},
1035 	{
1036 		.id = V4L2_CID_EXPOSURE_METERING,
1037 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1038 		.min = ~0xf,
1039 		.max = V4L2_EXPOSURE_METERING_MATRIX,
1040 		.def = V4L2_EXPOSURE_METERING_AVERAGE,
1041 		.step = 0,
1042 		.imenu = NULL,
1043 		.mmal_id = MMAL_PARAMETER_EXP_METERING_MODE,
1044 		.setter = ctrl_set_metering_mode,
1045 	},
1046 	{
1047 		.id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
1048 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1049 		.min = ~0x3ff,
1050 		.max = V4L2_WHITE_BALANCE_SHADE,
1051 		.def = V4L2_WHITE_BALANCE_AUTO,
1052 		.step = 0,
1053 		.imenu = NULL,
1054 		.mmal_id = MMAL_PARAMETER_AWB_MODE,
1055 		.setter = ctrl_set_awb_mode,
1056 	},
1057 	{
1058 		.id = V4L2_CID_RED_BALANCE,
1059 		.type = MMAL_CONTROL_TYPE_STD,
1060 		.min = 1,
1061 		.max = 7999,
1062 		.def = 1000,
1063 		.step = 1,
1064 		.imenu = NULL,
1065 		.mmal_id = MMAL_PARAMETER_CUSTOM_AWB_GAINS,
1066 		.setter = ctrl_set_awb_gains,
1067 	},
1068 	{
1069 		.id = V4L2_CID_BLUE_BALANCE,
1070 		.type = MMAL_CONTROL_TYPE_STD,
1071 		.min = 1,
1072 		.max = 7999,
1073 		.def = 1000,
1074 		.step = 1,
1075 		.imenu = NULL,
1076 		.mmal_id = MMAL_PARAMETER_CUSTOM_AWB_GAINS,
1077 		.setter = ctrl_set_awb_gains,
1078 	},
1079 	{
1080 		.id = V4L2_CID_COLORFX,
1081 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1082 		.min = 0,
1083 		.max = V4L2_COLORFX_SET_CBCR,
1084 		.def = V4L2_COLORFX_NONE,
1085 		.step = 0,
1086 		.imenu = NULL,
1087 		.mmal_id = MMAL_PARAMETER_IMAGE_EFFECT,
1088 		.setter = ctrl_set_image_effect,
1089 	},
1090 	{
1091 		.id = V4L2_CID_COLORFX_CBCR,
1092 		.type = MMAL_CONTROL_TYPE_STD,
1093 		.min = 0,
1094 		.max = 0xffff,
1095 		.def = 0x8080,
1096 		.step = 1,
1097 		.imenu = NULL,
1098 		.mmal_id = MMAL_PARAMETER_COLOUR_EFFECT,
1099 		.setter = ctrl_set_colfx,
1100 	},
1101 	{
1102 		.id = V4L2_CID_ROTATE,
1103 		.type = MMAL_CONTROL_TYPE_STD,
1104 		.min = 0,
1105 		.max = 360,
1106 		.def = 0,
1107 		.step = 90,
1108 		.imenu = NULL,
1109 		.mmal_id = MMAL_PARAMETER_ROTATION,
1110 		.setter = ctrl_set_rotate,
1111 	},
1112 	{
1113 		.id = V4L2_CID_HFLIP,
1114 		.type = MMAL_CONTROL_TYPE_STD,
1115 		.min = 0,
1116 		.max = 1,
1117 		.def = 0,
1118 		.step = 1,
1119 		.imenu = NULL,
1120 		.mmal_id = MMAL_PARAMETER_MIRROR,
1121 		.setter = ctrl_set_flip,
1122 	},
1123 	{
1124 		.id = V4L2_CID_VFLIP,
1125 		.type = MMAL_CONTROL_TYPE_STD,
1126 		.min = 0,
1127 		.max = 1,
1128 		.def = 0,
1129 		.step = 1,
1130 		.imenu = NULL,
1131 		.mmal_id = MMAL_PARAMETER_MIRROR,
1132 		.setter = ctrl_set_flip,
1133 	},
1134 	{
1135 		.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1136 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1137 		.min = 0,
1138 		.max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
1139 		.def = 0,
1140 		.step = 0,
1141 		.imenu = NULL,
1142 		.mmal_id = MMAL_PARAMETER_RATECONTROL,
1143 		.setter = ctrl_set_bitrate_mode,
1144 	},
1145 	{
1146 		.id = V4L2_CID_MPEG_VIDEO_BITRATE,
1147 		.type = MMAL_CONTROL_TYPE_STD,
1148 		.min = 25 * 1000,
1149 		.max = 25 * 1000 * 1000,
1150 		.def = 10 * 1000 * 1000,
1151 		.step = 25 * 1000,
1152 		.imenu = NULL,
1153 		.mmal_id = MMAL_PARAMETER_VIDEO_BIT_RATE,
1154 		.setter = ctrl_set_bitrate,
1155 	},
1156 	{
1157 		.id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
1158 		.type = MMAL_CONTROL_TYPE_STD,
1159 		.min = 1,
1160 		.max = 100,
1161 		.def = 30,
1162 		.step = 1,
1163 		.imenu = NULL,
1164 		.mmal_id = MMAL_PARAMETER_JPEG_Q_FACTOR,
1165 		.setter = ctrl_set_image_encode_output,
1166 	},
1167 	{
1168 		.id = V4L2_CID_POWER_LINE_FREQUENCY,
1169 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1170 		.min = 0,
1171 		.max = V4L2_CID_POWER_LINE_FREQUENCY_AUTO,
1172 		.def = 1,
1173 		.step = 1,
1174 		.imenu = NULL,
1175 		.mmal_id = MMAL_PARAMETER_FLICKER_AVOID,
1176 		.setter = ctrl_set_flicker_avoidance,
1177 	},
1178 	{
1179 		.id = V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER,
1180 		.type = MMAL_CONTROL_TYPE_STD,
1181 		.min = 0,
1182 		.max = 1,
1183 		.def = 0,
1184 		.step = 1,
1185 		.imenu = NULL,
1186 		.mmal_id = MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER,
1187 		.setter = ctrl_set_video_encode_param_output,
1188 	},
1189 	{
1190 		.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1191 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1192 		.min = ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
1193 			 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
1194 			 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
1195 			 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
1196 		.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
1197 		.def = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
1198 		.step = 1,
1199 		.imenu = NULL,
1200 		.mmal_id = MMAL_PARAMETER_PROFILE,
1201 		.setter = ctrl_set_video_encode_profile_level,
1202 	},
1203 	{
1204 		.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1205 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1206 		.min = ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
1207 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
1208 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
1209 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
1210 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
1211 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
1212 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
1213 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
1214 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
1215 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
1216 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
1217 			 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0)),
1218 		.max = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
1219 		.def = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
1220 		.step = 1,
1221 		.imenu = NULL,
1222 		.mmal_id = MMAL_PARAMETER_PROFILE,
1223 		.setter = ctrl_set_video_encode_profile_level,
1224 	},
1225 	{
1226 		.id = V4L2_CID_SCENE_MODE,
1227 		.type = MMAL_CONTROL_TYPE_STD_MENU,
1228 		/* mask is computed at runtime */
1229 		.min = -1,
1230 		.max = V4L2_SCENE_MODE_TEXT,
1231 		.def = V4L2_SCENE_MODE_NONE,
1232 		.step = 1,
1233 		.imenu = NULL,
1234 		.mmal_id = MMAL_PARAMETER_PROFILE,
1235 		.setter = ctrl_set_scene_mode,
1236 	},
1237 	{
1238 		.id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
1239 		.type = MMAL_CONTROL_TYPE_STD,
1240 		.min = 0,
1241 		.max = 0x7FFFFFFF,
1242 		.def = 60,
1243 		.step = 1,
1244 		.imenu = NULL,
1245 		.mmal_id = MMAL_PARAMETER_INTRAPERIOD,
1246 		.setter = ctrl_set_video_encode_param_output,
1247 	},
1248 };
1249 
bcm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev * dev)1250 int bcm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev)
1251 {
1252 	int c;
1253 	int ret = 0;
1254 
1255 	for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1256 		if ((dev->ctrls[c]) && (v4l2_ctrls[c].setter)) {
1257 			ret = v4l2_ctrls[c].setter(dev, dev->ctrls[c],
1258 						   &v4l2_ctrls[c]);
1259 			if (ret) {
1260 				v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1261 					 "Failed when setting default values for ctrl %d\n",
1262 					 c);
1263 				break;
1264 			}
1265 		}
1266 	}
1267 	return ret;
1268 }
1269 
set_framerate_params(struct bcm2835_mmal_dev * dev)1270 int set_framerate_params(struct bcm2835_mmal_dev *dev)
1271 {
1272 	struct mmal_parameter_fps_range fps_range;
1273 	int ret;
1274 
1275 	fps_range.fps_high.numerator = dev->capture.timeperframe.denominator;
1276 	fps_range.fps_high.denominator = dev->capture.timeperframe.numerator;
1277 
1278 	if ((dev->exposure_mode_active != MMAL_PARAM_EXPOSUREMODE_OFF) &&
1279 	    (dev->exp_auto_priority)) {
1280 		/* Variable FPS. Define min FPS as 1fps. */
1281 		fps_range.fps_low.numerator = 1;
1282 		fps_range.fps_low.denominator = 1;
1283 	} else {
1284 		/* Fixed FPS - set min and max to be the same */
1285 		fps_range.fps_low.numerator = fps_range.fps_high.numerator;
1286 		fps_range.fps_low.denominator = fps_range.fps_high.denominator;
1287 	}
1288 
1289 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1290 		 "Set fps range to %d/%d to %d/%d\n",
1291 		 fps_range.fps_low.numerator,
1292 		 fps_range.fps_low.denominator,
1293 		 fps_range.fps_high.numerator,
1294 		 fps_range.fps_high.denominator);
1295 
1296 	ret = vchiq_mmal_port_parameter_set(dev->instance,
1297 					    &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW],
1298 					    MMAL_PARAMETER_FPS_RANGE,
1299 					    &fps_range, sizeof(fps_range));
1300 	ret += vchiq_mmal_port_parameter_set(dev->instance,
1301 					     &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO],
1302 					     MMAL_PARAMETER_FPS_RANGE,
1303 					     &fps_range, sizeof(fps_range));
1304 	ret += vchiq_mmal_port_parameter_set(dev->instance,
1305 					     &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE],
1306 					     MMAL_PARAMETER_FPS_RANGE,
1307 					     &fps_range, sizeof(fps_range));
1308 	if (ret)
1309 		v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
1310 			 "Failed to set fps ret %d\n", ret);
1311 
1312 	return ret;
1313 }
1314 
bcm2835_mmal_init_controls(struct bcm2835_mmal_dev * dev,struct v4l2_ctrl_handler * hdl)1315 int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_handler *hdl)
1316 {
1317 	int c;
1318 	const struct bcm2835_mmal_v4l2_ctrl *ctrl;
1319 
1320 	v4l2_ctrl_handler_init(hdl, V4L2_CTRL_COUNT);
1321 
1322 	for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1323 		ctrl = &v4l2_ctrls[c];
1324 
1325 		switch (ctrl->type) {
1326 		case MMAL_CONTROL_TYPE_STD:
1327 			dev->ctrls[c] = v4l2_ctrl_new_std(hdl, &bcm2835_mmal_ctrl_ops,
1328 							  ctrl->id, ctrl->min, ctrl->max,
1329 							  ctrl->step, ctrl->def);
1330 			break;
1331 
1332 		case MMAL_CONTROL_TYPE_STD_MENU:
1333 		{
1334 			u64 mask = ctrl->min;
1335 
1336 			if (ctrl->id == V4L2_CID_SCENE_MODE) {
1337 				/* Special handling to work out the mask
1338 				 * value based on the scene_configs array
1339 				 * at runtime. Reduces the chance of
1340 				 * mismatches.
1341 				 */
1342 				int i;
1343 
1344 				mask = BIT(V4L2_SCENE_MODE_NONE);
1345 				for (i = 0;
1346 				     i < ARRAY_SIZE(scene_configs);
1347 				     i++) {
1348 					mask |= BIT(scene_configs[i].v4l2_scene);
1349 				}
1350 				mask = ~mask;
1351 			}
1352 
1353 			dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl, &bcm2835_mmal_ctrl_ops,
1354 							       ctrl->id, ctrl->max, mask,
1355 							       ctrl->def);
1356 			break;
1357 		}
1358 
1359 		case MMAL_CONTROL_TYPE_INT_MENU:
1360 			dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl, &bcm2835_mmal_ctrl_ops,
1361 							       ctrl->id, ctrl->max,
1362 							       ctrl->def, ctrl->imenu);
1363 			break;
1364 
1365 		case MMAL_CONTROL_TYPE_CLUSTER:
1366 			/* skip this entry when constructing controls */
1367 			continue;
1368 		}
1369 
1370 		if (hdl->error)
1371 			break;
1372 
1373 		dev->ctrls[c]->priv = (void *)ctrl;
1374 	}
1375 
1376 	if (hdl->error) {
1377 		pr_err("error adding control %d/%d id 0x%x\n", c,
1378 		       V4L2_CTRL_COUNT, ctrl->id);
1379 		return hdl->error;
1380 	}
1381 
1382 	for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1383 		ctrl = &v4l2_ctrls[c];
1384 
1385 		switch (ctrl->type) {
1386 		case MMAL_CONTROL_TYPE_CLUSTER:
1387 			v4l2_ctrl_auto_cluster(ctrl->min,
1388 					       &dev->ctrls[c + 1],
1389 					       ctrl->max,
1390 					       ctrl->def);
1391 			break;
1392 
1393 		case MMAL_CONTROL_TYPE_STD:
1394 		case MMAL_CONTROL_TYPE_STD_MENU:
1395 		case MMAL_CONTROL_TYPE_INT_MENU:
1396 			break;
1397 		}
1398 	}
1399 
1400 	return 0;
1401 }
1402