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