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