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