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