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