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