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