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