.. | .. |
---|
85 | 85 | |
---|
86 | 86 | struct ov2680_ctrls { |
---|
87 | 87 | struct v4l2_ctrl_handler handler; |
---|
88 | | - struct { |
---|
89 | | - struct v4l2_ctrl *auto_exp; |
---|
90 | | - struct v4l2_ctrl *exposure; |
---|
91 | | - }; |
---|
92 | | - struct { |
---|
93 | | - struct v4l2_ctrl *auto_gain; |
---|
94 | | - struct v4l2_ctrl *gain; |
---|
95 | | - }; |
---|
96 | | - |
---|
| 88 | + struct v4l2_ctrl *exposure; |
---|
| 89 | + struct v4l2_ctrl *gain; |
---|
97 | 90 | struct v4l2_ctrl *hflip; |
---|
98 | 91 | struct v4l2_ctrl *vflip; |
---|
99 | 92 | struct v4l2_ctrl *test_pattern; |
---|
.. | .. |
---|
143 | 136 | {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, |
---|
144 | 137 | {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00}, |
---|
145 | 138 | {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0}, |
---|
| 139 | + {0x3503, 0x03}, |
---|
146 | 140 | }; |
---|
147 | 141 | |
---|
148 | 142 | static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = { |
---|
.. | .. |
---|
321 | 315 | usleep_range(5000, 10000); |
---|
322 | 316 | } |
---|
323 | 317 | |
---|
324 | | -static int ov2680_bayer_order(struct ov2680_dev *sensor) |
---|
| 318 | +static void ov2680_set_bayer_order(struct ov2680_dev *sensor) |
---|
325 | 319 | { |
---|
326 | | - u32 format1; |
---|
327 | | - u32 format2; |
---|
328 | | - u32 hv_flip; |
---|
329 | | - int ret; |
---|
| 320 | + int hv_flip = 0; |
---|
330 | 321 | |
---|
331 | | - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1); |
---|
332 | | - if (ret < 0) |
---|
333 | | - return ret; |
---|
| 322 | + if (sensor->ctrls.vflip && sensor->ctrls.vflip->val) |
---|
| 323 | + hv_flip += 1; |
---|
334 | 324 | |
---|
335 | | - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2); |
---|
336 | | - if (ret < 0) |
---|
337 | | - return ret; |
---|
338 | | - |
---|
339 | | - hv_flip = (format2 & BIT(2) << 1) | (format1 & BIT(2)); |
---|
| 325 | + if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) |
---|
| 326 | + hv_flip += 2; |
---|
340 | 327 | |
---|
341 | 328 | sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; |
---|
| 329 | +} |
---|
342 | 330 | |
---|
| 331 | +static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) |
---|
| 332 | +{ |
---|
| 333 | + int ret; |
---|
| 334 | + |
---|
| 335 | + if (sensor->is_streaming) |
---|
| 336 | + return -EBUSY; |
---|
| 337 | + |
---|
| 338 | + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, |
---|
| 339 | + BIT(2), val ? BIT(2) : 0); |
---|
| 340 | + if (ret < 0) |
---|
| 341 | + return ret; |
---|
| 342 | + |
---|
| 343 | + ov2680_set_bayer_order(sensor); |
---|
343 | 344 | return 0; |
---|
344 | 345 | } |
---|
345 | 346 | |
---|
346 | | -static int ov2680_vflip_enable(struct ov2680_dev *sensor) |
---|
| 347 | +static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) |
---|
347 | 348 | { |
---|
348 | 349 | int ret; |
---|
349 | 350 | |
---|
350 | | - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2)); |
---|
| 351 | + if (sensor->is_streaming) |
---|
| 352 | + return -EBUSY; |
---|
| 353 | + |
---|
| 354 | + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, |
---|
| 355 | + BIT(2), val ? BIT(2) : 0); |
---|
351 | 356 | if (ret < 0) |
---|
352 | 357 | return ret; |
---|
353 | 358 | |
---|
354 | | - return ov2680_bayer_order(sensor); |
---|
355 | | -} |
---|
356 | | - |
---|
357 | | -static int ov2680_vflip_disable(struct ov2680_dev *sensor) |
---|
358 | | -{ |
---|
359 | | - int ret; |
---|
360 | | - |
---|
361 | | - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0)); |
---|
362 | | - if (ret < 0) |
---|
363 | | - return ret; |
---|
364 | | - |
---|
365 | | - return ov2680_bayer_order(sensor); |
---|
366 | | -} |
---|
367 | | - |
---|
368 | | -static int ov2680_hflip_enable(struct ov2680_dev *sensor) |
---|
369 | | -{ |
---|
370 | | - int ret; |
---|
371 | | - |
---|
372 | | - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2)); |
---|
373 | | - if (ret < 0) |
---|
374 | | - return ret; |
---|
375 | | - |
---|
376 | | - return ov2680_bayer_order(sensor); |
---|
377 | | -} |
---|
378 | | - |
---|
379 | | -static int ov2680_hflip_disable(struct ov2680_dev *sensor) |
---|
380 | | -{ |
---|
381 | | - int ret; |
---|
382 | | - |
---|
383 | | - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0)); |
---|
384 | | - if (ret < 0) |
---|
385 | | - return ret; |
---|
386 | | - |
---|
387 | | - return ov2680_bayer_order(sensor); |
---|
| 359 | + ov2680_set_bayer_order(sensor); |
---|
| 360 | + return 0; |
---|
388 | 361 | } |
---|
389 | 362 | |
---|
390 | 363 | static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) |
---|
.. | .. |
---|
405 | 378 | return 0; |
---|
406 | 379 | } |
---|
407 | 380 | |
---|
408 | | -static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain) |
---|
| 381 | +static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) |
---|
409 | 382 | { |
---|
410 | | - struct ov2680_ctrls *ctrls = &sensor->ctrls; |
---|
411 | | - u32 gain; |
---|
412 | | - int ret; |
---|
413 | | - |
---|
414 | | - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1), |
---|
415 | | - auto_gain ? 0 : BIT(1)); |
---|
416 | | - if (ret < 0) |
---|
417 | | - return ret; |
---|
418 | | - |
---|
419 | | - if (auto_gain || !ctrls->gain->is_new) |
---|
420 | | - return 0; |
---|
421 | | - |
---|
422 | | - gain = ctrls->gain->val; |
---|
423 | | - |
---|
424 | | - ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); |
---|
425 | | - |
---|
426 | | - return 0; |
---|
| 383 | + return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); |
---|
427 | 384 | } |
---|
428 | 385 | |
---|
429 | | -static int ov2680_gain_get(struct ov2680_dev *sensor) |
---|
| 386 | +static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) |
---|
430 | 387 | { |
---|
431 | | - u32 gain; |
---|
432 | | - int ret; |
---|
433 | | - |
---|
434 | | - ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain); |
---|
435 | | - if (ret) |
---|
436 | | - return ret; |
---|
437 | | - |
---|
438 | | - return gain; |
---|
439 | | -} |
---|
440 | | - |
---|
441 | | -static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp) |
---|
442 | | -{ |
---|
443 | | - struct ov2680_ctrls *ctrls = &sensor->ctrls; |
---|
444 | | - u32 exp; |
---|
445 | | - int ret; |
---|
446 | | - |
---|
447 | | - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0), |
---|
448 | | - auto_exp ? 0 : BIT(0)); |
---|
449 | | - if (ret < 0) |
---|
450 | | - return ret; |
---|
451 | | - |
---|
452 | | - if (auto_exp || !ctrls->exposure->is_new) |
---|
453 | | - return 0; |
---|
454 | | - |
---|
455 | | - exp = (u32)ctrls->exposure->val; |
---|
456 | | - exp <<= 4; |
---|
457 | | - |
---|
458 | | - return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp); |
---|
459 | | -} |
---|
460 | | - |
---|
461 | | -static int ov2680_exposure_get(struct ov2680_dev *sensor) |
---|
462 | | -{ |
---|
463 | | - int ret; |
---|
464 | | - u32 exp; |
---|
465 | | - |
---|
466 | | - ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp); |
---|
467 | | - if (ret) |
---|
468 | | - return ret; |
---|
469 | | - |
---|
470 | | - return exp >> 4; |
---|
| 388 | + return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, |
---|
| 389 | + exp << 4); |
---|
471 | 390 | } |
---|
472 | 391 | |
---|
473 | 392 | static int ov2680_stream_enable(struct ov2680_dev *sensor) |
---|
.. | .. |
---|
482 | 401 | |
---|
483 | 402 | static int ov2680_mode_set(struct ov2680_dev *sensor) |
---|
484 | 403 | { |
---|
485 | | - struct ov2680_ctrls *ctrls = &sensor->ctrls; |
---|
486 | 404 | int ret; |
---|
487 | | - |
---|
488 | | - ret = ov2680_gain_set(sensor, false); |
---|
489 | | - if (ret < 0) |
---|
490 | | - return ret; |
---|
491 | | - |
---|
492 | | - ret = ov2680_exposure_set(sensor, false); |
---|
493 | | - if (ret < 0) |
---|
494 | | - return ret; |
---|
495 | 405 | |
---|
496 | 406 | ret = ov2680_load_regs(sensor, sensor->current_mode); |
---|
497 | 407 | if (ret < 0) |
---|
498 | 408 | return ret; |
---|
499 | 409 | |
---|
500 | | - if (ctrls->auto_gain->val) { |
---|
501 | | - ret = ov2680_gain_set(sensor, true); |
---|
502 | | - if (ret < 0) |
---|
503 | | - return ret; |
---|
504 | | - } |
---|
505 | | - |
---|
506 | | - if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) { |
---|
507 | | - ret = ov2680_exposure_set(sensor, true); |
---|
508 | | - if (ret < 0) |
---|
509 | | - return ret; |
---|
510 | | - } |
---|
| 410 | + /* Restore value of all ctrls */ |
---|
| 411 | + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); |
---|
| 412 | + if (ret < 0) |
---|
| 413 | + return ret; |
---|
511 | 414 | |
---|
512 | 415 | sensor->mode_pending_changes = false; |
---|
513 | 416 | |
---|
.. | .. |
---|
556 | 459 | ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01); |
---|
557 | 460 | if (ret != 0) { |
---|
558 | 461 | dev_err(dev, "sensor soft reset failed\n"); |
---|
559 | | - return ret; |
---|
| 462 | + goto err_disable_regulators; |
---|
560 | 463 | } |
---|
561 | 464 | usleep_range(1000, 2000); |
---|
562 | 465 | } else { |
---|
.. | .. |
---|
566 | 469 | |
---|
567 | 470 | ret = clk_prepare_enable(sensor->xvclk); |
---|
568 | 471 | if (ret < 0) |
---|
569 | | - return ret; |
---|
| 472 | + goto err_disable_regulators; |
---|
570 | 473 | |
---|
571 | 474 | sensor->is_enabled = true; |
---|
572 | 475 | |
---|
.. | .. |
---|
576 | 479 | ov2680_stream_disable(sensor); |
---|
577 | 480 | |
---|
578 | 481 | return 0; |
---|
| 482 | + |
---|
| 483 | +err_disable_regulators: |
---|
| 484 | + regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); |
---|
| 485 | + return ret; |
---|
579 | 486 | } |
---|
580 | 487 | |
---|
581 | 488 | static int ov2680_s_power(struct v4l2_subdev *sd, int on) |
---|
.. | .. |
---|
590 | 497 | else |
---|
591 | 498 | ret = ov2680_power_off(sensor); |
---|
592 | 499 | |
---|
593 | | - mutex_unlock(&sensor->lock); |
---|
594 | | - |
---|
595 | | - if (on && ret == 0) { |
---|
596 | | - ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); |
---|
597 | | - if (ret < 0) |
---|
598 | | - return ret; |
---|
599 | | - |
---|
| 500 | + if (on && ret == 0) |
---|
600 | 501 | ret = ov2680_mode_restore(sensor); |
---|
601 | | - } |
---|
| 502 | + |
---|
| 503 | + mutex_unlock(&sensor->lock); |
---|
602 | 504 | |
---|
603 | 505 | return ret; |
---|
604 | 506 | } |
---|
.. | .. |
---|
793 | 695 | return 0; |
---|
794 | 696 | } |
---|
795 | 697 | |
---|
796 | | -static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
---|
797 | | -{ |
---|
798 | | - struct v4l2_subdev *sd = ctrl_to_sd(ctrl); |
---|
799 | | - struct ov2680_dev *sensor = to_ov2680_dev(sd); |
---|
800 | | - struct ov2680_ctrls *ctrls = &sensor->ctrls; |
---|
801 | | - int val; |
---|
802 | | - |
---|
803 | | - if (!sensor->is_enabled) |
---|
804 | | - return 0; |
---|
805 | | - |
---|
806 | | - switch (ctrl->id) { |
---|
807 | | - case V4L2_CID_GAIN: |
---|
808 | | - val = ov2680_gain_get(sensor); |
---|
809 | | - if (val < 0) |
---|
810 | | - return val; |
---|
811 | | - ctrls->gain->val = val; |
---|
812 | | - break; |
---|
813 | | - case V4L2_CID_EXPOSURE: |
---|
814 | | - val = ov2680_exposure_get(sensor); |
---|
815 | | - if (val < 0) |
---|
816 | | - return val; |
---|
817 | | - ctrls->exposure->val = val; |
---|
818 | | - break; |
---|
819 | | - } |
---|
820 | | - |
---|
821 | | - return 0; |
---|
822 | | -} |
---|
823 | | - |
---|
824 | 698 | static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) |
---|
825 | 699 | { |
---|
826 | 700 | struct v4l2_subdev *sd = ctrl_to_sd(ctrl); |
---|
827 | 701 | struct ov2680_dev *sensor = to_ov2680_dev(sd); |
---|
828 | | - struct ov2680_ctrls *ctrls = &sensor->ctrls; |
---|
829 | 702 | |
---|
830 | 703 | if (!sensor->is_enabled) |
---|
831 | 704 | return 0; |
---|
832 | 705 | |
---|
833 | 706 | switch (ctrl->id) { |
---|
834 | | - case V4L2_CID_AUTOGAIN: |
---|
835 | | - return ov2680_gain_set(sensor, !!ctrl->val); |
---|
836 | 707 | case V4L2_CID_GAIN: |
---|
837 | | - return ov2680_gain_set(sensor, !!ctrls->auto_gain->val); |
---|
838 | | - case V4L2_CID_EXPOSURE_AUTO: |
---|
839 | | - return ov2680_exposure_set(sensor, !!ctrl->val); |
---|
| 708 | + return ov2680_gain_set(sensor, ctrl->val); |
---|
840 | 709 | case V4L2_CID_EXPOSURE: |
---|
841 | | - return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val); |
---|
| 710 | + return ov2680_exposure_set(sensor, ctrl->val); |
---|
842 | 711 | case V4L2_CID_VFLIP: |
---|
843 | | - if (sensor->is_streaming) |
---|
844 | | - return -EBUSY; |
---|
845 | | - if (ctrl->val) |
---|
846 | | - return ov2680_vflip_enable(sensor); |
---|
847 | | - else |
---|
848 | | - return ov2680_vflip_disable(sensor); |
---|
| 712 | + return ov2680_set_vflip(sensor, ctrl->val); |
---|
849 | 713 | case V4L2_CID_HFLIP: |
---|
850 | | - if (sensor->is_streaming) |
---|
851 | | - return -EBUSY; |
---|
852 | | - if (ctrl->val) |
---|
853 | | - return ov2680_hflip_enable(sensor); |
---|
854 | | - else |
---|
855 | | - return ov2680_hflip_disable(sensor); |
---|
| 714 | + return ov2680_set_hflip(sensor, ctrl->val); |
---|
856 | 715 | case V4L2_CID_TEST_PATTERN: |
---|
857 | 716 | return ov2680_test_pattern_set(sensor, ctrl->val); |
---|
858 | 717 | default: |
---|
.. | .. |
---|
863 | 722 | } |
---|
864 | 723 | |
---|
865 | 724 | static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { |
---|
866 | | - .g_volatile_ctrl = ov2680_g_volatile_ctrl, |
---|
867 | 725 | .s_ctrl = ov2680_s_ctrl, |
---|
868 | 726 | }; |
---|
869 | 727 | |
---|
.. | .. |
---|
935 | 793 | if (ret < 0) |
---|
936 | 794 | return ret; |
---|
937 | 795 | |
---|
938 | | - v4l2_ctrl_handler_init(hdl, 7); |
---|
| 796 | + v4l2_ctrl_handler_init(hdl, 5); |
---|
939 | 797 | |
---|
940 | 798 | hdl->lock = &sensor->lock; |
---|
941 | 799 | |
---|
.. | .. |
---|
947 | 805 | ARRAY_SIZE(test_pattern_menu) - 1, |
---|
948 | 806 | 0, 0, test_pattern_menu); |
---|
949 | 807 | |
---|
950 | | - ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, |
---|
951 | | - V4L2_CID_EXPOSURE_AUTO, |
---|
952 | | - V4L2_EXPOSURE_MANUAL, 0, |
---|
953 | | - V4L2_EXPOSURE_AUTO); |
---|
954 | | - |
---|
955 | 808 | ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, |
---|
956 | 809 | 0, 32767, 1, 0); |
---|
957 | 810 | |
---|
958 | | - ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, |
---|
959 | | - 0, 1, 1, 1); |
---|
960 | 811 | ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0); |
---|
961 | 812 | |
---|
962 | 813 | if (hdl->error) { |
---|
.. | .. |
---|
964 | 815 | goto cleanup_entity; |
---|
965 | 816 | } |
---|
966 | 817 | |
---|
967 | | - ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; |
---|
968 | | - ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; |
---|
969 | | - |
---|
970 | | - v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true); |
---|
971 | | - v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true); |
---|
| 818 | + ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; |
---|
| 819 | + ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; |
---|
972 | 820 | |
---|
973 | 821 | sensor->sd.ctrl_handler = hdl; |
---|
974 | 822 | |
---|