.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Omnivision OV9650/OV9652 CMOS Image Sensor driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * Register definitions and initial settings based on a driver written |
---|
7 | 8 | * by Vladimir Fonov. |
---|
8 | 9 | * Copyright (c) 2010, Vladimir Fonov |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License version 2 as |
---|
12 | | - * published by the Free Software Foundation. |
---|
13 | 10 | */ |
---|
14 | 11 | #include <linux/clk.h> |
---|
15 | 12 | #include <linux/delay.h> |
---|
.. | .. |
---|
20 | 17 | #include <linux/media.h> |
---|
21 | 18 | #include <linux/module.h> |
---|
22 | 19 | #include <linux/ratelimit.h> |
---|
| 20 | +#include <linux/regmap.h> |
---|
23 | 21 | #include <linux/slab.h> |
---|
24 | 22 | #include <linux/string.h> |
---|
25 | 23 | #include <linux/videodev2.h> |
---|
.. | .. |
---|
44 | 42 | * OV9650/OV9652 register definitions |
---|
45 | 43 | */ |
---|
46 | 44 | #define REG_GAIN 0x00 /* Gain control, AGC[7:0] */ |
---|
47 | | -#define REG_BLUE 0x01 /* AWB - Blue chanel gain */ |
---|
48 | | -#define REG_RED 0x02 /* AWB - Red chanel gain */ |
---|
| 45 | +#define REG_BLUE 0x01 /* AWB - Blue channel gain */ |
---|
| 46 | +#define REG_RED 0x02 /* AWB - Red channel gain */ |
---|
49 | 47 | #define REG_VREF 0x03 /* [7:6] - AGC[9:8], [5:3]/[2:0] */ |
---|
50 | 48 | #define VREF_GAIN_MASK 0xc0 /* - VREF end/start low 3 bits */ |
---|
51 | 49 | #define REG_COM1 0x04 |
---|
.. | .. |
---|
259 | 257 | /* Protects the struct fields below */ |
---|
260 | 258 | struct mutex lock; |
---|
261 | 259 | |
---|
262 | | - struct i2c_client *client; |
---|
| 260 | + struct regmap *regmap; |
---|
263 | 261 | |
---|
264 | 262 | /* Exposure row interval in us */ |
---|
265 | 263 | unsigned int exp_row_interval; |
---|
.. | .. |
---|
424 | 422 | return container_of(sd, struct ov965x, sd); |
---|
425 | 423 | } |
---|
426 | 424 | |
---|
427 | | -static int ov965x_read(struct i2c_client *client, u8 addr, u8 *val) |
---|
| 425 | +static int ov965x_read(struct ov965x *ov965x, u8 addr, u8 *val) |
---|
428 | 426 | { |
---|
429 | | - u8 buf = addr; |
---|
430 | | - struct i2c_msg msg = { |
---|
431 | | - .addr = client->addr, |
---|
432 | | - .flags = 0, |
---|
433 | | - .len = 1, |
---|
434 | | - .buf = &buf |
---|
435 | | - }; |
---|
436 | 427 | int ret; |
---|
| 428 | + unsigned int buf; |
---|
437 | 429 | |
---|
438 | | - ret = i2c_transfer(client->adapter, &msg, 1); |
---|
439 | | - if (ret == 1) { |
---|
440 | | - msg.flags = I2C_M_RD; |
---|
441 | | - ret = i2c_transfer(client->adapter, &msg, 1); |
---|
| 430 | + ret = regmap_read(ov965x->regmap, addr, &buf); |
---|
| 431 | + if (!ret) |
---|
| 432 | + *val = buf; |
---|
| 433 | + else |
---|
| 434 | + *val = -1; |
---|
442 | 435 | |
---|
443 | | - if (ret == 1) |
---|
444 | | - *val = buf; |
---|
445 | | - } |
---|
446 | | - |
---|
447 | | - v4l2_dbg(2, debug, client, "%s: 0x%02x @ 0x%02x. (%d)\n", |
---|
| 436 | + v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02x. (%d)\n", |
---|
448 | 437 | __func__, *val, addr, ret); |
---|
449 | 438 | |
---|
450 | | - return ret == 1 ? 0 : ret; |
---|
| 439 | + return ret; |
---|
451 | 440 | } |
---|
452 | 441 | |
---|
453 | | -static int ov965x_write(struct i2c_client *client, u8 addr, u8 val) |
---|
| 442 | +static int ov965x_write(struct ov965x *ov965x, u8 addr, u8 val) |
---|
454 | 443 | { |
---|
455 | | - u8 buf[2] = { addr, val }; |
---|
| 444 | + int ret; |
---|
456 | 445 | |
---|
457 | | - int ret = i2c_master_send(client, buf, 2); |
---|
| 446 | + ret = regmap_write(ov965x->regmap, addr, val); |
---|
458 | 447 | |
---|
459 | | - v4l2_dbg(2, debug, client, "%s: 0x%02x @ 0x%02X (%d)\n", |
---|
| 448 | + v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02X (%d)\n", |
---|
460 | 449 | __func__, val, addr, ret); |
---|
461 | 450 | |
---|
462 | | - return ret == 2 ? 0 : ret; |
---|
| 451 | + return ret; |
---|
463 | 452 | } |
---|
464 | 453 | |
---|
465 | | -static int ov965x_write_array(struct i2c_client *client, |
---|
| 454 | +static int ov965x_write_array(struct ov965x *ov965x, |
---|
466 | 455 | const struct i2c_rv *regs) |
---|
467 | 456 | { |
---|
468 | 457 | int i, ret = 0; |
---|
469 | 458 | |
---|
470 | 459 | for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) |
---|
471 | | - ret = ov965x_write(client, regs[i].addr, regs[i].value); |
---|
| 460 | + ret = ov965x_write(ov965x, regs[i].addr, regs[i].value); |
---|
472 | 461 | |
---|
473 | 462 | return ret; |
---|
474 | 463 | } |
---|
.. | .. |
---|
486 | 475 | unsigned int i; |
---|
487 | 476 | |
---|
488 | 477 | for (i = 0; i < ARRAY_SIZE(gamma_curve); i++) { |
---|
489 | | - int ret = ov965x_write(ov965x->client, addr, gamma_curve[i]); |
---|
| 478 | + int ret = ov965x_write(ov965x, addr, gamma_curve[i]); |
---|
490 | 479 | |
---|
491 | 480 | if (ret < 0) |
---|
492 | 481 | return ret; |
---|
.. | .. |
---|
506 | 495 | unsigned int i; |
---|
507 | 496 | |
---|
508 | 497 | for (i = 0; i < ARRAY_SIZE(mtx); i++) { |
---|
509 | | - int ret = ov965x_write(ov965x->client, addr, mtx[i]); |
---|
| 498 | + int ret = ov965x_write(ov965x, addr, mtx[i]); |
---|
510 | 499 | |
---|
511 | 500 | if (ret < 0) |
---|
512 | 501 | return ret; |
---|
.. | .. |
---|
542 | 531 | static int ov965x_s_power(struct v4l2_subdev *sd, int on) |
---|
543 | 532 | { |
---|
544 | 533 | struct ov965x *ov965x = to_ov965x(sd); |
---|
545 | | - struct i2c_client *client = ov965x->client; |
---|
546 | 534 | int ret = 0; |
---|
547 | 535 | |
---|
548 | | - v4l2_dbg(1, debug, client, "%s: on: %d\n", __func__, on); |
---|
| 536 | + v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on); |
---|
549 | 537 | |
---|
550 | 538 | mutex_lock(&ov965x->lock); |
---|
551 | 539 | if (ov965x->power == !on) { |
---|
552 | 540 | ret = __ov965x_set_power(ov965x, on); |
---|
553 | 541 | if (!ret && on) { |
---|
554 | | - ret = ov965x_write_array(client, |
---|
| 542 | + ret = ov965x_write_array(ov965x, |
---|
555 | 543 | ov965x_init_regs); |
---|
556 | 544 | ov965x->apply_frame_fmt = 1; |
---|
557 | 545 | ov965x->ctrls.update = 1; |
---|
.. | .. |
---|
609 | 597 | int ret; |
---|
610 | 598 | u8 reg; |
---|
611 | 599 | |
---|
612 | | - ret = ov965x_read(ov965x->client, REG_COM8, ®); |
---|
| 600 | + ret = ov965x_read(ov965x, REG_COM8, ®); |
---|
613 | 601 | if (!ret) { |
---|
614 | 602 | if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED) |
---|
615 | 603 | reg &= ~COM8_BFILT; |
---|
616 | 604 | else |
---|
617 | 605 | reg |= COM8_BFILT; |
---|
618 | | - ret = ov965x_write(ov965x->client, REG_COM8, reg); |
---|
| 606 | + ret = ov965x_write(ov965x, REG_COM8, reg); |
---|
619 | 607 | } |
---|
620 | 608 | if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED) |
---|
621 | 609 | return 0; |
---|
.. | .. |
---|
631 | 619 | ov965x->fiv->interval.numerator; |
---|
632 | 620 | mbd = ((mbd / (light_freq * 2)) + 500) / 1000UL; |
---|
633 | 621 | |
---|
634 | | - return ov965x_write(ov965x->client, REG_MBD, mbd); |
---|
| 622 | + return ov965x_write(ov965x, REG_MBD, mbd); |
---|
635 | 623 | } |
---|
636 | 624 | |
---|
637 | 625 | static int ov965x_set_white_balance(struct ov965x *ov965x, int awb) |
---|
.. | .. |
---|
639 | 627 | int ret; |
---|
640 | 628 | u8 reg; |
---|
641 | 629 | |
---|
642 | | - ret = ov965x_read(ov965x->client, REG_COM8, ®); |
---|
| 630 | + ret = ov965x_read(ov965x, REG_COM8, ®); |
---|
643 | 631 | if (!ret) { |
---|
644 | 632 | reg = awb ? reg | REG_COM8 : reg & ~REG_COM8; |
---|
645 | | - ret = ov965x_write(ov965x->client, REG_COM8, reg); |
---|
| 633 | + ret = ov965x_write(ov965x, REG_COM8, reg); |
---|
646 | 634 | } |
---|
647 | 635 | if (!ret && !awb) { |
---|
648 | | - ret = ov965x_write(ov965x->client, REG_BLUE, |
---|
| 636 | + ret = ov965x_write(ov965x, REG_BLUE, |
---|
649 | 637 | ov965x->ctrls.blue_balance->val); |
---|
650 | 638 | if (ret < 0) |
---|
651 | 639 | return ret; |
---|
652 | | - ret = ov965x_write(ov965x->client, REG_RED, |
---|
| 640 | + ret = ov965x_write(ov965x, REG_RED, |
---|
653 | 641 | ov965x->ctrls.red_balance->val); |
---|
654 | 642 | } |
---|
655 | 643 | return ret; |
---|
.. | .. |
---|
677 | 665 | return -EINVAL; |
---|
678 | 666 | |
---|
679 | 667 | for (i = 0; i < NUM_BR_REGS && !ret; i++) |
---|
680 | | - ret = ov965x_write(ov965x->client, regs[0][i], |
---|
| 668 | + ret = ov965x_write(ov965x, regs[0][i], |
---|
681 | 669 | regs[val][i]); |
---|
682 | 670 | return ret; |
---|
683 | 671 | } |
---|
684 | 672 | |
---|
685 | 673 | static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain) |
---|
686 | 674 | { |
---|
687 | | - struct i2c_client *client = ov965x->client; |
---|
688 | 675 | struct ov965x_ctrls *ctrls = &ov965x->ctrls; |
---|
689 | 676 | int ret = 0; |
---|
690 | 677 | u8 reg; |
---|
.. | .. |
---|
693 | 680 | * gain value in REG_VREF, REG_GAIN is not overwritten. |
---|
694 | 681 | */ |
---|
695 | 682 | if (ctrls->auto_gain->is_new) { |
---|
696 | | - ret = ov965x_read(client, REG_COM8, ®); |
---|
| 683 | + ret = ov965x_read(ov965x, REG_COM8, ®); |
---|
697 | 684 | if (ret < 0) |
---|
698 | 685 | return ret; |
---|
699 | 686 | if (ctrls->auto_gain->val) |
---|
700 | 687 | reg |= COM8_AGC; |
---|
701 | 688 | else |
---|
702 | 689 | reg &= ~COM8_AGC; |
---|
703 | | - ret = ov965x_write(client, REG_COM8, reg); |
---|
| 690 | + ret = ov965x_write(ov965x, REG_COM8, reg); |
---|
704 | 691 | if (ret < 0) |
---|
705 | 692 | return ret; |
---|
706 | 693 | } |
---|
.. | .. |
---|
724 | 711 | rgain = (gain - ((1 << m) * 16)) / (1 << m); |
---|
725 | 712 | rgain |= (((1 << m) - 1) << 4); |
---|
726 | 713 | |
---|
727 | | - ret = ov965x_write(client, REG_GAIN, rgain & 0xff); |
---|
| 714 | + ret = ov965x_write(ov965x, REG_GAIN, rgain & 0xff); |
---|
728 | 715 | if (ret < 0) |
---|
729 | 716 | return ret; |
---|
730 | | - ret = ov965x_read(client, REG_VREF, ®); |
---|
| 717 | + ret = ov965x_read(ov965x, REG_VREF, ®); |
---|
731 | 718 | if (ret < 0) |
---|
732 | 719 | return ret; |
---|
733 | 720 | reg &= ~VREF_GAIN_MASK; |
---|
734 | 721 | reg |= (((rgain >> 8) & 0x3) << 6); |
---|
735 | | - ret = ov965x_write(client, REG_VREF, reg); |
---|
| 722 | + ret = ov965x_write(ov965x, REG_VREF, reg); |
---|
736 | 723 | if (ret < 0) |
---|
737 | 724 | return ret; |
---|
738 | 725 | /* Return updated control's value to userspace */ |
---|
.. | .. |
---|
747 | 734 | u8 com14, edge; |
---|
748 | 735 | int ret; |
---|
749 | 736 | |
---|
750 | | - ret = ov965x_read(ov965x->client, REG_COM14, &com14); |
---|
| 737 | + ret = ov965x_read(ov965x, REG_COM14, &com14); |
---|
751 | 738 | if (ret < 0) |
---|
752 | 739 | return ret; |
---|
753 | | - ret = ov965x_read(ov965x->client, REG_EDGE, &edge); |
---|
| 740 | + ret = ov965x_read(ov965x, REG_EDGE, &edge); |
---|
754 | 741 | if (ret < 0) |
---|
755 | 742 | return ret; |
---|
756 | 743 | com14 = value ? com14 | COM14_EDGE_EN : com14 & ~COM14_EDGE_EN; |
---|
.. | .. |
---|
761 | 748 | } else { |
---|
762 | 749 | com14 &= ~COM14_EEF_X2; |
---|
763 | 750 | } |
---|
764 | | - ret = ov965x_write(ov965x->client, REG_COM14, com14); |
---|
| 751 | + ret = ov965x_write(ov965x, REG_COM14, com14); |
---|
765 | 752 | if (ret < 0) |
---|
766 | 753 | return ret; |
---|
767 | 754 | |
---|
768 | 755 | edge &= ~EDGE_FACTOR_MASK; |
---|
769 | 756 | edge |= ((u8)value & 0x0f); |
---|
770 | 757 | |
---|
771 | | - return ov965x_write(ov965x->client, REG_EDGE, edge); |
---|
| 758 | + return ov965x_write(ov965x, REG_EDGE, edge); |
---|
772 | 759 | } |
---|
773 | 760 | |
---|
774 | 761 | static int ov965x_set_exposure(struct ov965x *ov965x, int exp) |
---|
775 | 762 | { |
---|
776 | | - struct i2c_client *client = ov965x->client; |
---|
777 | 763 | struct ov965x_ctrls *ctrls = &ov965x->ctrls; |
---|
778 | 764 | bool auto_exposure = (exp == V4L2_EXPOSURE_AUTO); |
---|
779 | 765 | int ret; |
---|
780 | 766 | u8 reg; |
---|
781 | 767 | |
---|
782 | 768 | if (ctrls->auto_exp->is_new) { |
---|
783 | | - ret = ov965x_read(client, REG_COM8, ®); |
---|
| 769 | + ret = ov965x_read(ov965x, REG_COM8, ®); |
---|
784 | 770 | if (ret < 0) |
---|
785 | 771 | return ret; |
---|
786 | 772 | if (auto_exposure) |
---|
787 | 773 | reg |= (COM8_AEC | COM8_AGC); |
---|
788 | 774 | else |
---|
789 | 775 | reg &= ~(COM8_AEC | COM8_AGC); |
---|
790 | | - ret = ov965x_write(client, REG_COM8, reg); |
---|
| 776 | + ret = ov965x_write(ov965x, REG_COM8, reg); |
---|
791 | 777 | if (ret < 0) |
---|
792 | 778 | return ret; |
---|
793 | 779 | } |
---|
.. | .. |
---|
799 | 785 | * Manual exposure value |
---|
800 | 786 | * [b15:b0] - AECHM (b15:b10), AECH (b9:b2), COM1 (b1:b0) |
---|
801 | 787 | */ |
---|
802 | | - ret = ov965x_write(client, REG_COM1, exposure & 0x3); |
---|
| 788 | + ret = ov965x_write(ov965x, REG_COM1, exposure & 0x3); |
---|
803 | 789 | if (!ret) |
---|
804 | | - ret = ov965x_write(client, REG_AECH, |
---|
| 790 | + ret = ov965x_write(ov965x, REG_AECH, |
---|
805 | 791 | (exposure >> 2) & 0xff); |
---|
806 | 792 | if (!ret) |
---|
807 | | - ret = ov965x_write(client, REG_AECHM, |
---|
| 793 | + ret = ov965x_write(ov965x, REG_AECHM, |
---|
808 | 794 | (exposure >> 10) & 0x3f); |
---|
809 | 795 | /* Update the value to minimize rounding errors */ |
---|
810 | 796 | ctrls->exposure->val = ((exposure * ov965x->exp_row_interval) |
---|
.. | .. |
---|
827 | 813 | if (ov965x->ctrls.vflip->val) |
---|
828 | 814 | mvfp |= MVFP_FLIP; |
---|
829 | 815 | |
---|
830 | | - return ov965x_write(ov965x->client, REG_MVFP, mvfp); |
---|
| 816 | + return ov965x_write(ov965x, REG_MVFP, mvfp); |
---|
831 | 817 | } |
---|
832 | 818 | |
---|
833 | 819 | #define NUM_SAT_LEVELS 5 |
---|
.. | .. |
---|
851 | 837 | return -EINVAL; |
---|
852 | 838 | |
---|
853 | 839 | for (i = 0; i < NUM_SAT_REGS && !ret; i++) |
---|
854 | | - ret = ov965x_write(ov965x->client, addr + i, regs[val][i]); |
---|
| 840 | + ret = ov965x_write(ov965x, addr + i, regs[val][i]); |
---|
855 | 841 | |
---|
856 | 842 | return ret; |
---|
857 | 843 | } |
---|
.. | .. |
---|
861 | 847 | int ret; |
---|
862 | 848 | u8 reg; |
---|
863 | 849 | |
---|
864 | | - ret = ov965x_read(ov965x->client, REG_COM23, ®); |
---|
| 850 | + ret = ov965x_read(ov965x, REG_COM23, ®); |
---|
865 | 851 | if (ret < 0) |
---|
866 | 852 | return ret; |
---|
867 | 853 | reg = value ? reg | COM23_TEST_MODE : reg & ~COM23_TEST_MODE; |
---|
868 | | - return ov965x_write(ov965x->client, REG_COM23, reg); |
---|
| 854 | + return ov965x_write(ov965x, REG_COM23, reg); |
---|
869 | 855 | } |
---|
870 | 856 | |
---|
871 | 857 | static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl) |
---|
872 | 858 | { |
---|
873 | | - struct i2c_client *client = ov965x->client; |
---|
874 | 859 | unsigned int exposure, gain, m; |
---|
875 | 860 | u8 reg0, reg1, reg2; |
---|
876 | 861 | int ret; |
---|
.. | .. |
---|
882 | 867 | case V4L2_CID_AUTOGAIN: |
---|
883 | 868 | if (!ctrl->val) |
---|
884 | 869 | return 0; |
---|
885 | | - ret = ov965x_read(client, REG_GAIN, ®0); |
---|
| 870 | + ret = ov965x_read(ov965x, REG_GAIN, ®0); |
---|
886 | 871 | if (ret < 0) |
---|
887 | 872 | return ret; |
---|
888 | | - ret = ov965x_read(client, REG_VREF, ®1); |
---|
| 873 | + ret = ov965x_read(ov965x, REG_VREF, ®1); |
---|
889 | 874 | if (ret < 0) |
---|
890 | 875 | return ret; |
---|
891 | 876 | gain = ((reg1 >> 6) << 8) | reg0; |
---|
.. | .. |
---|
896 | 881 | case V4L2_CID_EXPOSURE_AUTO: |
---|
897 | 882 | if (ctrl->val == V4L2_EXPOSURE_MANUAL) |
---|
898 | 883 | return 0; |
---|
899 | | - ret = ov965x_read(client, REG_COM1, ®0); |
---|
| 884 | + ret = ov965x_read(ov965x, REG_COM1, ®0); |
---|
900 | 885 | if (ret < 0) |
---|
901 | 886 | return ret; |
---|
902 | | - ret = ov965x_read(client, REG_AECH, ®1); |
---|
| 887 | + ret = ov965x_read(ov965x, REG_AECH, ®1); |
---|
903 | 888 | if (ret < 0) |
---|
904 | 889 | return ret; |
---|
905 | | - ret = ov965x_read(client, REG_AECHM, ®2); |
---|
| 890 | + ret = ov965x_read(ov965x, REG_AECHM, ®2); |
---|
906 | 891 | if (ret < 0) |
---|
907 | 892 | return ret; |
---|
908 | 893 | exposure = ((reg2 & 0x3f) << 10) | (reg1 << 2) | |
---|
.. | .. |
---|
1123 | 1108 | { |
---|
1124 | 1109 | struct ov965x *ov965x = to_ov965x(sd); |
---|
1125 | 1110 | |
---|
1126 | | - mutex_lock(&ov965x->lock); |
---|
1127 | 1111 | fi->interval = ov965x->fiv->interval; |
---|
1128 | | - mutex_unlock(&ov965x->lock); |
---|
1129 | 1112 | |
---|
1130 | 1113 | return 0; |
---|
1131 | 1114 | } |
---|
.. | .. |
---|
1284 | 1267 | int i, ret = 0; |
---|
1285 | 1268 | |
---|
1286 | 1269 | for (i = 0; ret == 0 && i < NUM_FMT_REGS; i++) |
---|
1287 | | - ret = ov965x_write(ov965x->client, frame_size_reg_addr[i], |
---|
| 1270 | + ret = ov965x_write(ov965x, frame_size_reg_addr[i], |
---|
1288 | 1271 | ov965x->frame_size->regs[i]); |
---|
1289 | 1272 | return ret; |
---|
1290 | 1273 | } |
---|
1291 | 1274 | |
---|
1292 | 1275 | static int __ov965x_set_params(struct ov965x *ov965x) |
---|
1293 | 1276 | { |
---|
1294 | | - struct i2c_client *client = ov965x->client; |
---|
1295 | 1277 | struct ov965x_ctrls *ctrls = &ov965x->ctrls; |
---|
1296 | 1278 | int ret = 0; |
---|
1297 | 1279 | u8 reg; |
---|
1298 | 1280 | |
---|
1299 | 1281 | if (ov965x->apply_frame_fmt) { |
---|
1300 | 1282 | reg = DEF_CLKRC + ov965x->fiv->clkrc_div; |
---|
1301 | | - ret = ov965x_write(client, REG_CLKRC, reg); |
---|
| 1283 | + ret = ov965x_write(ov965x, REG_CLKRC, reg); |
---|
1302 | 1284 | if (ret < 0) |
---|
1303 | 1285 | return ret; |
---|
1304 | 1286 | ret = ov965x_set_frame_size(ov965x); |
---|
1305 | 1287 | if (ret < 0) |
---|
1306 | 1288 | return ret; |
---|
1307 | | - ret = ov965x_read(client, REG_TSLB, ®); |
---|
| 1289 | + ret = ov965x_read(ov965x, REG_TSLB, ®); |
---|
1308 | 1290 | if (ret < 0) |
---|
1309 | 1291 | return ret; |
---|
1310 | 1292 | reg &= ~TSLB_YUYV_MASK; |
---|
1311 | 1293 | reg |= ov965x->tslb_reg; |
---|
1312 | | - ret = ov965x_write(client, REG_TSLB, reg); |
---|
| 1294 | + ret = ov965x_write(ov965x, REG_TSLB, reg); |
---|
1313 | 1295 | if (ret < 0) |
---|
1314 | 1296 | return ret; |
---|
1315 | 1297 | } |
---|
.. | .. |
---|
1323 | 1305 | * Select manual banding filter, the filter will |
---|
1324 | 1306 | * be enabled further if required. |
---|
1325 | 1307 | */ |
---|
1326 | | - ret = ov965x_read(client, REG_COM11, ®); |
---|
| 1308 | + ret = ov965x_read(ov965x, REG_COM11, ®); |
---|
1327 | 1309 | if (!ret) |
---|
1328 | 1310 | reg |= COM11_BANDING; |
---|
1329 | | - ret = ov965x_write(client, REG_COM11, reg); |
---|
| 1311 | + ret = ov965x_write(ov965x, REG_COM11, reg); |
---|
1330 | 1312 | if (ret < 0) |
---|
1331 | 1313 | return ret; |
---|
1332 | 1314 | /* |
---|
.. | .. |
---|
1338 | 1320 | |
---|
1339 | 1321 | static int ov965x_s_stream(struct v4l2_subdev *sd, int on) |
---|
1340 | 1322 | { |
---|
1341 | | - struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1342 | 1323 | struct ov965x *ov965x = to_ov965x(sd); |
---|
1343 | 1324 | struct ov965x_ctrls *ctrls = &ov965x->ctrls; |
---|
1344 | 1325 | int ret = 0; |
---|
1345 | 1326 | |
---|
1346 | | - v4l2_dbg(1, debug, client, "%s: on: %d\n", __func__, on); |
---|
| 1327 | + v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on); |
---|
1347 | 1328 | |
---|
1348 | 1329 | mutex_lock(&ov965x->lock); |
---|
1349 | 1330 | if (ov965x->streaming == !on) { |
---|
.. | .. |
---|
1363 | 1344 | ctrls->update = 0; |
---|
1364 | 1345 | } |
---|
1365 | 1346 | if (!ret) |
---|
1366 | | - ret = ov965x_write(client, REG_COM2, |
---|
| 1347 | + ret = ov965x_write(ov965x, REG_COM2, |
---|
1367 | 1348 | on ? 0x01 : 0x11); |
---|
1368 | 1349 | } |
---|
1369 | 1350 | if (!ret) |
---|
.. | .. |
---|
1426 | 1407 | { |
---|
1427 | 1408 | int ret, i; |
---|
1428 | 1409 | int gpios[NUM_GPIOS]; |
---|
| 1410 | + struct device *dev = regmap_get_device(ov965x->regmap); |
---|
1429 | 1411 | |
---|
1430 | 1412 | gpios[GPIO_PWDN] = pdata->gpio_pwdn; |
---|
1431 | 1413 | gpios[GPIO_RST] = pdata->gpio_reset; |
---|
.. | .. |
---|
1435 | 1417 | |
---|
1436 | 1418 | if (!gpio_is_valid(gpio)) |
---|
1437 | 1419 | continue; |
---|
1438 | | - ret = devm_gpio_request_one(&ov965x->client->dev, gpio, |
---|
| 1420 | + ret = devm_gpio_request_one(dev, gpio, |
---|
1439 | 1421 | GPIOF_OUT_INIT_HIGH, "OV965X"); |
---|
1440 | 1422 | if (ret < 0) |
---|
1441 | 1423 | return ret; |
---|
.. | .. |
---|
1451 | 1433 | |
---|
1452 | 1434 | static int ov965x_configure_gpios(struct ov965x *ov965x) |
---|
1453 | 1435 | { |
---|
1454 | | - struct device *dev = &ov965x->client->dev; |
---|
| 1436 | + struct device *dev = regmap_get_device(ov965x->regmap); |
---|
1455 | 1437 | |
---|
1456 | 1438 | ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown", |
---|
1457 | 1439 | GPIOD_OUT_HIGH); |
---|
.. | .. |
---|
1472 | 1454 | |
---|
1473 | 1455 | static int ov965x_detect_sensor(struct v4l2_subdev *sd) |
---|
1474 | 1456 | { |
---|
1475 | | - struct i2c_client *client = v4l2_get_subdevdata(sd); |
---|
1476 | 1457 | struct ov965x *ov965x = to_ov965x(sd); |
---|
1477 | 1458 | u8 pid, ver; |
---|
1478 | 1459 | int ret; |
---|
.. | .. |
---|
1485 | 1466 | msleep(25); |
---|
1486 | 1467 | |
---|
1487 | 1468 | /* Check sensor revision */ |
---|
1488 | | - ret = ov965x_read(client, REG_PID, &pid); |
---|
| 1469 | + ret = ov965x_read(ov965x, REG_PID, &pid); |
---|
1489 | 1470 | if (!ret) |
---|
1490 | | - ret = ov965x_read(client, REG_VER, &ver); |
---|
| 1471 | + ret = ov965x_read(ov965x, REG_VER, &ver); |
---|
1491 | 1472 | |
---|
1492 | 1473 | __ov965x_set_power(ov965x, 0); |
---|
1493 | 1474 | |
---|
.. | .. |
---|
1507 | 1488 | return ret; |
---|
1508 | 1489 | } |
---|
1509 | 1490 | |
---|
1510 | | -static int ov965x_probe(struct i2c_client *client, |
---|
1511 | | - const struct i2c_device_id *id) |
---|
| 1491 | +static int ov965x_probe(struct i2c_client *client) |
---|
1512 | 1492 | { |
---|
1513 | 1493 | const struct ov9650_platform_data *pdata = client->dev.platform_data; |
---|
1514 | 1494 | struct v4l2_subdev *sd; |
---|
1515 | 1495 | struct ov965x *ov965x; |
---|
1516 | 1496 | int ret; |
---|
| 1497 | + static const struct regmap_config ov965x_regmap_config = { |
---|
| 1498 | + .reg_bits = 8, |
---|
| 1499 | + .val_bits = 8, |
---|
| 1500 | + .max_register = 0xab, |
---|
| 1501 | + }; |
---|
1517 | 1502 | |
---|
1518 | 1503 | ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL); |
---|
1519 | 1504 | if (!ov965x) |
---|
1520 | 1505 | return -ENOMEM; |
---|
1521 | 1506 | |
---|
1522 | | - ov965x->client = client; |
---|
| 1507 | + ov965x->regmap = devm_regmap_init_sccb(client, &ov965x_regmap_config); |
---|
| 1508 | + if (IS_ERR(ov965x->regmap)) { |
---|
| 1509 | + dev_err(&client->dev, "Failed to allocate register map\n"); |
---|
| 1510 | + return PTR_ERR(ov965x->regmap); |
---|
| 1511 | + } |
---|
1523 | 1512 | |
---|
1524 | 1513 | if (pdata) { |
---|
1525 | 1514 | if (pdata->mclk_frequency == 0) { |
---|
.. | .. |
---|
1532 | 1521 | if (ret < 0) |
---|
1533 | 1522 | return ret; |
---|
1534 | 1523 | } else if (dev_fwnode(&client->dev)) { |
---|
1535 | | - ov965x->clk = devm_clk_get(&ov965x->client->dev, NULL); |
---|
| 1524 | + ov965x->clk = devm_clk_get(&client->dev, NULL); |
---|
1536 | 1525 | if (IS_ERR(ov965x->clk)) |
---|
1537 | 1526 | return PTR_ERR(ov965x->clk); |
---|
1538 | 1527 | ov965x->mclk_frequency = clk_get_rate(ov965x->clk); |
---|
.. | .. |
---|
1551 | 1540 | |
---|
1552 | 1541 | sd = &ov965x->sd; |
---|
1553 | 1542 | v4l2_i2c_subdev_init(sd, client, &ov965x_subdev_ops); |
---|
1554 | | - strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name)); |
---|
| 1543 | + strscpy(sd->name, DRIVER_NAME, sizeof(sd->name)); |
---|
1555 | 1544 | |
---|
1556 | 1545 | sd->internal_ops = &ov965x_sd_internal_ops; |
---|
1557 | 1546 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | |
---|
.. | .. |
---|
1626 | 1615 | .name = DRIVER_NAME, |
---|
1627 | 1616 | .of_match_table = of_match_ptr(ov965x_of_match), |
---|
1628 | 1617 | }, |
---|
1629 | | - .probe = ov965x_probe, |
---|
| 1618 | + .probe_new = ov965x_probe, |
---|
1630 | 1619 | .remove = ov965x_remove, |
---|
1631 | 1620 | .id_table = ov965x_id, |
---|
1632 | 1621 | }; |
---|