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