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