1 // SPDX-License-Identifier: GPL-2.0
3 * Broadcom BM2835 V4L2 driver
5 * Copyright © 2013 Raspberry Pi (Trading) Ltd.
7 * Authors: Vincent Sanders @ Collabora
8 * Dave Stevenson @ Broadcom
9 * (now dave.stevenson@raspberrypi.org)
10 * Simon Mellor @ Broadcom
11 * Luke Diamand @ Broadcom
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>
26 #include "mmal-common.h"
27 #include "mmal-vchiq.h"
28 #include "mmal-parameters.h"
29 #include "bcm2835-camera.h"
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
38 static const s64 ev_bias_qmenu[] = {
50 /* Supported ISO values (*1000)
53 static const s64 iso_qmenu[] = {
54 0, 100000, 200000, 400000, 800000,
57 static const u32 iso_values[] = {
58 0, 100, 200, 400, 800,
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 */
68 struct bm2835_mmal_v4l2_ctrl;
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);
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
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;
91 struct v4l2_to_mmal_effects_setting {
95 s32 col_fx_fixed_cbcr;
98 u32 num_effect_params;
99 u32 effect_params[MMAL_MAX_IMAGEFX_PARAMETERS];
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} }
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;
144 static const struct v4l2_mmal_scene_config scene_configs[] = {
145 /* V4L2_SCENE_MODE_NONE automatically added */
147 V4L2_SCENE_MODE_NIGHT,
148 MMAL_PARAM_EXPOSUREMODE_NIGHT,
149 MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
152 V4L2_SCENE_MODE_SPORTS,
153 MMAL_PARAM_EXPOSUREMODE_SPORTS,
154 MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE
158 /* control handlers*/
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)
164 struct mmal_parameter_rational rational_value;
165 struct vchiq_mmal_port *control;
167 control = &dev->component[COMP_CAMERA]->control;
169 rational_value.num = ctrl->val;
170 rational_value.den = 100;
172 return vchiq_mmal_port_parameter_set(dev->instance, control,
175 sizeof(rational_value));
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)
183 struct vchiq_mmal_port *control;
185 control = &dev->component[COMP_CAMERA]->control;
187 u32_value = ctrl->val;
189 return vchiq_mmal_port_parameter_set(dev->instance, control,
191 &u32_value, sizeof(u32_value));
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)
199 struct vchiq_mmal_port *control;
201 if (ctrl->val > mmal_ctrl->max || ctrl->val < mmal_ctrl->min)
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);
210 control = &dev->component[COMP_CAMERA]->control;
212 if (dev->manual_iso_enabled)
213 u32_value = dev->iso;
217 return vchiq_mmal_port_parameter_set(dev->instance, control,
219 &u32_value, sizeof(u32_value));
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)
227 struct vchiq_mmal_port *control;
229 control = &dev->component[COMP_CAMERA]->control;
231 s32_value = (ctrl->val - 12) * 2; /* Convert from index to 1/6ths */
233 return vchiq_mmal_port_parameter_set(dev->instance, control,
235 &s32_value, sizeof(s32_value));
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)
244 struct vchiq_mmal_component *camera;
246 camera = dev->component[COMP_CAMERA];
248 u32_value = ((ctrl->val % 360) / 90) * 90;
250 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0],
252 &u32_value, sizeof(u32_value));
256 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1],
258 &u32_value, sizeof(u32_value));
262 return vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2],
264 &u32_value, sizeof(u32_value));
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)
273 struct vchiq_mmal_component *camera;
275 if (ctrl->id == V4L2_CID_HFLIP)
276 dev->hflip = ctrl->val;
278 dev->vflip = ctrl->val;
280 camera = dev->component[COMP_CAMERA];
282 if (dev->hflip && dev->vflip)
283 u32_value = MMAL_PARAM_MIRROR_BOTH;
285 u32_value = MMAL_PARAM_MIRROR_HORIZONTAL;
287 u32_value = MMAL_PARAM_MIRROR_VERTICAL;
289 u32_value = MMAL_PARAM_MIRROR_NONE;
291 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[0],
293 &u32_value, sizeof(u32_value));
297 ret = vchiq_mmal_port_parameter_set(dev->instance, &camera->output[1],
299 &u32_value, sizeof(u32_value));
303 return vchiq_mmal_port_parameter_set(dev->instance, &camera->output[2],
305 &u32_value, sizeof(u32_value));
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)
312 enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user;
313 u32 shutter_speed = 0;
314 struct vchiq_mmal_port *control;
317 control = &dev->component[COMP_CAMERA]->control;
319 if (mmal_ctrl->mmal_id == MMAL_PARAMETER_SHUTTER_SPEED) {
320 /* V4L2 is in 100usec increments.
323 dev->manual_shutter_speed = ctrl->val * 100;
324 } else if (mmal_ctrl->mmal_id == MMAL_PARAMETER_EXPOSURE_MODE) {
326 case V4L2_EXPOSURE_AUTO:
327 exp_mode = MMAL_PARAM_EXPOSUREMODE_AUTO;
330 case V4L2_EXPOSURE_MANUAL:
331 exp_mode = MMAL_PARAM_EXPOSUREMODE_OFF;
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;
340 if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
341 if (exp_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
342 shutter_speed = dev->manual_shutter_speed;
344 ret = vchiq_mmal_port_parameter_set(dev->instance,
346 MMAL_PARAMETER_SHUTTER_SPEED,
348 sizeof(shutter_speed));
349 ret += vchiq_mmal_port_parameter_set(dev->instance,
351 MMAL_PARAMETER_EXPOSURE_MODE,
354 dev->exposure_mode_active = exp_mode;
356 /* exposure_dynamic_framerate (V4L2_CID_EXPOSURE_AUTO_PRIORITY) should
357 * always apply irrespective of scene mode.
359 ret += set_framerate_params(dev);
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)
369 case V4L2_EXPOSURE_METERING_AVERAGE:
370 dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_AVERAGE;
373 case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
374 dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_BACKLIT;
377 case V4L2_EXPOSURE_METERING_SPOT:
378 dev->metering_mode = MMAL_PARAM_EXPOSUREMETERINGMODE_SPOT;
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;
388 if (dev->scene_mode == V4L2_SCENE_MODE_NONE) {
389 struct vchiq_mmal_port *control;
390 u32 u32_value = dev->metering_mode;
392 control = &dev->component[COMP_CAMERA]->control;
394 return vchiq_mmal_port_parameter_set(dev->instance, control,
396 &u32_value, sizeof(u32_value));
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)
407 struct vchiq_mmal_port *control;
409 control = &dev->component[COMP_CAMERA]->control;
412 case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
413 u32_value = MMAL_PARAM_FLICKERAVOID_OFF;
415 case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
416 u32_value = MMAL_PARAM_FLICKERAVOID_50HZ;
418 case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
419 u32_value = MMAL_PARAM_FLICKERAVOID_60HZ;
421 case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
422 u32_value = MMAL_PARAM_FLICKERAVOID_AUTO;
426 return vchiq_mmal_port_parameter_set(dev->instance, control,
428 &u32_value, sizeof(u32_value));
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)
436 struct vchiq_mmal_port *control;
438 control = &dev->component[COMP_CAMERA]->control;
441 case V4L2_WHITE_BALANCE_MANUAL:
442 u32_value = MMAL_PARAM_AWBMODE_OFF;
445 case V4L2_WHITE_BALANCE_AUTO:
446 u32_value = MMAL_PARAM_AWBMODE_AUTO;
449 case V4L2_WHITE_BALANCE_INCANDESCENT:
450 u32_value = MMAL_PARAM_AWBMODE_INCANDESCENT;
453 case V4L2_WHITE_BALANCE_FLUORESCENT:
454 u32_value = MMAL_PARAM_AWBMODE_FLUORESCENT;
457 case V4L2_WHITE_BALANCE_FLUORESCENT_H:
458 u32_value = MMAL_PARAM_AWBMODE_TUNGSTEN;
461 case V4L2_WHITE_BALANCE_HORIZON:
462 u32_value = MMAL_PARAM_AWBMODE_HORIZON;
465 case V4L2_WHITE_BALANCE_DAYLIGHT:
466 u32_value = MMAL_PARAM_AWBMODE_SUNLIGHT;
469 case V4L2_WHITE_BALANCE_FLASH:
470 u32_value = MMAL_PARAM_AWBMODE_FLASH;
473 case V4L2_WHITE_BALANCE_CLOUDY:
474 u32_value = MMAL_PARAM_AWBMODE_CLOUDY;
477 case V4L2_WHITE_BALANCE_SHADE:
478 u32_value = MMAL_PARAM_AWBMODE_SHADE;
482 return vchiq_mmal_port_parameter_set(dev->instance, control,
484 &u32_value, sizeof(u32_value));
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)
491 struct vchiq_mmal_port *control;
492 struct mmal_parameter_awbgains gains;
494 control = &dev->component[COMP_CAMERA]->control;
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;
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;
505 return vchiq_mmal_port_parameter_set(dev->instance, control,
507 &gains, sizeof(gains));
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)
516 struct vchiq_mmal_port *control;
517 struct mmal_parameter_imagefx_parameters imagefx;
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) {
522 v4l2_to_mmal_effects_values[i].mmal_effect;
523 imagefx.num_effect_params =
524 v4l2_to_mmal_effects_values[i].num_effect_params;
526 if (imagefx.num_effect_params > MMAL_MAX_IMAGEFX_PARAMETERS)
527 imagefx.num_effect_params = MMAL_MAX_IMAGEFX_PARAMETERS;
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];
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) {
537 v4l2_to_mmal_effects_values[i].u;
539 v4l2_to_mmal_effects_values[i].v;
542 control = &dev->component[COMP_CAMERA]->control;
544 ret = vchiq_mmal_port_parameter_set(
545 dev->instance, control,
546 MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS,
547 &imagefx, sizeof(imagefx));
551 ret = vchiq_mmal_port_parameter_set(
552 dev->instance, control,
553 MMAL_PARAMETER_COLOUR_EFFECT,
554 &dev->colourfx, sizeof(dev->colourfx));
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);
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)
573 struct vchiq_mmal_port *control;
575 control = &dev->component[COMP_CAMERA]->control;
577 dev->colourfx.u = (ctrl->val & 0xff00) >> 8;
578 dev->colourfx.v = ctrl->val & 0xff;
580 ret = vchiq_mmal_port_parameter_set(dev->instance, control,
581 MMAL_PARAMETER_COLOUR_EFFECT,
583 sizeof(dev->colourfx));
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);
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)
597 struct vchiq_mmal_port *encoder_out;
599 dev->capture.encode_bitrate = ctrl->val;
601 encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0];
603 ret = vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
604 mmal_ctrl->mmal_id, &ctrl->val,
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));
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.
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)
625 struct vchiq_mmal_port *encoder_out;
627 encoder_out = &dev->component[COMP_VIDEO_ENCODE]->output[0];
629 dev->capture.encode_bitrate_mode = ctrl->val;
632 case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
633 bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE;
635 case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
636 bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT;
640 vchiq_mmal_port_parameter_set(dev->instance, encoder_out,
643 sizeof(bitrate_mode));
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)
652 struct vchiq_mmal_port *jpeg_out;
654 jpeg_out = &dev->component[COMP_IMAGE_ENCODE]->output[0];
656 u32_value = ctrl->val;
658 return vchiq_mmal_port_parameter_set(dev->instance, jpeg_out,
660 &u32_value, sizeof(u32_value));
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)
668 struct vchiq_mmal_port *vid_enc_ctl;
670 vid_enc_ctl = &dev->component[COMP_VIDEO_ENCODE]->output[0];
672 u32_value = ctrl->val;
674 return vchiq_mmal_port_parameter_set(dev->instance, vid_enc_ctl,
676 &u32_value, sizeof(u32_value));
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)
683 struct mmal_parameter_video_profile param;
686 if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
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;
698 } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
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;
721 switch (dev->capture.enc_profile) {
722 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
723 param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
725 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
727 MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
729 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
730 param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
732 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
733 param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
736 /* Should never get here */
740 switch (dev->capture.enc_level) {
741 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
742 param.level = MMAL_VIDEO_LEVEL_H264_1;
744 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
745 param.level = MMAL_VIDEO_LEVEL_H264_1b;
747 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
748 param.level = MMAL_VIDEO_LEVEL_H264_11;
750 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
751 param.level = MMAL_VIDEO_LEVEL_H264_12;
753 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
754 param.level = MMAL_VIDEO_LEVEL_H264_13;
756 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
757 param.level = MMAL_VIDEO_LEVEL_H264_2;
759 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
760 param.level = MMAL_VIDEO_LEVEL_H264_21;
762 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
763 param.level = MMAL_VIDEO_LEVEL_H264_22;
765 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
766 param.level = MMAL_VIDEO_LEVEL_H264_3;
768 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
769 param.level = MMAL_VIDEO_LEVEL_H264_31;
771 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
772 param.level = MMAL_VIDEO_LEVEL_H264_32;
774 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
775 param.level = MMAL_VIDEO_LEVEL_H264_4;
778 /* Should never get here */
782 ret = vchiq_mmal_port_parameter_set(dev->instance,
783 &dev->component[COMP_VIDEO_ENCODE]->output[0],
785 ¶m, sizeof(param));
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)
796 struct vchiq_mmal_port *control;
798 v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
799 "scene mode selected %d, was %d\n", ctrl->val,
801 control = &dev->component[COMP_CAMERA]->control;
803 if (ctrl->val == dev->scene_mode)
806 if (ctrl->val == V4L2_SCENE_MODE_NONE) {
807 /* Restore all user selections */
808 dev->scene_mode = V4L2_SCENE_MODE_NONE;
810 if (dev->exposure_mode_user == MMAL_PARAM_EXPOSUREMODE_OFF)
811 shutter_speed = dev->manual_shutter_speed;
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,
819 ret = vchiq_mmal_port_parameter_set(dev->instance,
821 MMAL_PARAMETER_SHUTTER_SPEED,
823 sizeof(shutter_speed));
824 ret += vchiq_mmal_port_parameter_set(dev->instance,
826 MMAL_PARAMETER_EXPOSURE_MODE,
827 &dev->exposure_mode_user,
829 dev->exposure_mode_active = dev->exposure_mode_user;
830 ret += vchiq_mmal_port_parameter_set(dev->instance,
832 MMAL_PARAMETER_EXP_METERING_MODE,
835 ret += set_framerate_params(dev);
837 /* Set up scene mode */
839 const struct v4l2_mmal_scene_config *scene = NULL;
841 enum mmal_parameter_exposuremode exposure_mode;
842 enum mmal_parameter_exposuremeteringmode metering_mode;
844 for (i = 0; i < ARRAY_SIZE(scene_configs); i++) {
845 if (scene_configs[i].v4l2_scene ==
847 scene = &scene_configs[i];
853 if (i >= ARRAY_SIZE(scene_configs))
856 /* Set all the values */
857 dev->scene_mode = ctrl->val;
859 if (scene->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
860 shutter_speed = dev->manual_shutter_speed;
863 exposure_mode = scene->exposure_mode;
864 metering_mode = scene->metering_mode;
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);
870 ret = vchiq_mmal_port_parameter_set(dev->instance, control,
871 MMAL_PARAMETER_SHUTTER_SPEED,
873 sizeof(shutter_speed));
874 ret += vchiq_mmal_port_parameter_set(dev->instance, control,
875 MMAL_PARAMETER_EXPOSURE_MODE,
878 dev->exposure_mode_active = exposure_mode;
879 ret += vchiq_mmal_port_parameter_set(dev->instance, control,
880 MMAL_PARAMETER_EXPOSURE_MODE,
883 ret += vchiq_mmal_port_parameter_set(dev->instance, control,
884 MMAL_PARAMETER_EXP_METERING_MODE,
887 ret += set_framerate_params(dev);
890 v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
891 "%s: Setting scene to %d, ret=%d\n",
892 __func__, ctrl->val, ret);
898 static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
900 struct bm2835_mmal_dev *dev =
901 container_of(ctrl->handler, struct bm2835_mmal_dev,
903 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv;
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);
911 ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl);
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)
920 static const struct v4l2_ctrl_ops bm2835_mmal_ctrl_ops = {
921 .s_ctrl = bm2835_mmal_s_ctrl,
924 static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
926 V4L2_CID_SATURATION, MMAL_CONTROL_TYPE_STD,
927 -100, 100, 0, 1, NULL,
928 MMAL_PARAMETER_SATURATION,
933 V4L2_CID_SHARPNESS, MMAL_CONTROL_TYPE_STD,
934 -100, 100, 0, 1, NULL,
935 MMAL_PARAMETER_SHARPNESS,
940 V4L2_CID_CONTRAST, MMAL_CONTROL_TYPE_STD,
941 -100, 100, 0, 1, NULL,
942 MMAL_PARAMETER_CONTRAST,
947 V4L2_CID_BRIGHTNESS, MMAL_CONTROL_TYPE_STD,
949 MMAL_PARAMETER_BRIGHTNESS,
954 V4L2_CID_ISO_SENSITIVITY, MMAL_CONTROL_TYPE_INT_MENU,
955 0, ARRAY_SIZE(iso_qmenu) - 1, 0, 1, iso_qmenu,
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,
968 V4L2_CID_IMAGE_STABILIZATION, MMAL_CONTROL_TYPE_STD,
970 MMAL_PARAMETER_VIDEO_STABILISATION,
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,
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,
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,
998 V4L2_CID_EXPOSURE_AUTO_PRIORITY, MMAL_CONTROL_TYPE_STD,
1001 0, /* Dummy MMAL ID as it gets mapped into FPS range*/
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,
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,
1019 MMAL_PARAMETER_AWB_MODE,
1024 V4L2_CID_RED_BALANCE, MMAL_CONTROL_TYPE_STD,
1025 1, 7999, 1000, 1, NULL,
1026 MMAL_PARAMETER_CUSTOM_AWB_GAINS,
1031 V4L2_CID_BLUE_BALANCE, MMAL_CONTROL_TYPE_STD,
1032 1, 7999, 1000, 1, NULL,
1033 MMAL_PARAMETER_CUSTOM_AWB_GAINS,
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,
1045 V4L2_CID_COLORFX_CBCR, MMAL_CONTROL_TYPE_STD,
1046 0, 0xffff, 0x8080, 1, NULL,
1047 MMAL_PARAMETER_COLOUR_EFFECT,
1052 V4L2_CID_ROTATE, MMAL_CONTROL_TYPE_STD,
1053 0, 360, 0, 90, NULL,
1054 MMAL_PARAMETER_ROTATION,
1059 V4L2_CID_HFLIP, MMAL_CONTROL_TYPE_STD,
1061 MMAL_PARAMETER_MIRROR,
1066 V4L2_CID_VFLIP, MMAL_CONTROL_TYPE_STD,
1068 MMAL_PARAMETER_MIRROR,
1073 V4L2_CID_MPEG_VIDEO_BITRATE_MODE, MMAL_CONTROL_TYPE_STD_MENU,
1074 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
1076 MMAL_PARAMETER_RATECONTROL,
1077 ctrl_set_bitrate_mode,
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,
1088 V4L2_CID_JPEG_COMPRESSION_QUALITY, MMAL_CONTROL_TYPE_STD,
1091 MMAL_PARAMETER_JPEG_Q_FACTOR,
1092 ctrl_set_image_encode_output,
1096 V4L2_CID_POWER_LINE_FREQUENCY, MMAL_CONTROL_TYPE_STD_MENU,
1097 0, V4L2_CID_POWER_LINE_FREQUENCY_AUTO,
1099 MMAL_PARAMETER_FLICKER_AVOID,
1100 ctrl_set_flicker_avoidance,
1104 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, MMAL_CONTROL_TYPE_STD,
1107 MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER,
1108 ctrl_set_video_encode_param_output,
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,
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,
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,
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,
1162 int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
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],
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",
1182 int set_framerate_params(struct bm2835_mmal_dev *dev)
1184 struct mmal_parameter_fps_range fps_range;
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.
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;
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;
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);
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));
1224 v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
1225 "Failed to set fps ret %d\n", ret);
1230 int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
1231 struct v4l2_ctrl_handler *hdl)
1234 const struct bm2835_mmal_v4l2_ctrl *ctrl;
1236 v4l2_ctrl_handler_init(hdl, V4L2_CTRL_COUNT);
1238 for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1239 ctrl = &v4l2_ctrls[c];
1241 switch (ctrl->type) {
1242 case MMAL_CONTROL_TYPE_STD:
1244 v4l2_ctrl_new_std(hdl,
1245 &bm2835_mmal_ctrl_ops,
1246 ctrl->id, ctrl->min,
1247 ctrl->max, ctrl->step,
1251 case MMAL_CONTROL_TYPE_STD_MENU:
1253 u64 mask = ctrl->min;
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
1263 mask = BIT(V4L2_SCENE_MODE_NONE);
1265 i < ARRAY_SIZE(scene_configs);
1267 mask |= BIT(scene_configs[i].v4l2_scene);
1273 v4l2_ctrl_new_std_menu(hdl,
1274 &bm2835_mmal_ctrl_ops,
1275 ctrl->id, ctrl->max,
1280 case MMAL_CONTROL_TYPE_INT_MENU:
1282 v4l2_ctrl_new_int_menu(hdl,
1283 &bm2835_mmal_ctrl_ops,
1284 ctrl->id, ctrl->max,
1285 ctrl->def, ctrl->imenu);
1288 case MMAL_CONTROL_TYPE_CLUSTER:
1289 /* skip this entry when constructing controls */
1296 dev->ctrls[c]->priv = (void *)ctrl;
1300 pr_err("error adding control %d/%d id 0x%x\n", c,
1301 V4L2_CTRL_COUNT, ctrl->id);
1305 for (c = 0; c < V4L2_CTRL_COUNT; c++) {
1306 ctrl = &v4l2_ctrls[c];
1308 switch (ctrl->type) {
1309 case MMAL_CONTROL_TYPE_CLUSTER:
1310 v4l2_ctrl_auto_cluster(ctrl->min,
1316 case MMAL_CONTROL_TYPE_STD:
1317 case MMAL_CONTROL_TYPE_STD_MENU:
1318 case MMAL_CONTROL_TYPE_INT_MENU: