diff options
author | Bhanu Murthy V <bmurthyv@nvidia.com> | 2017-11-02 20:03:28 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-11-25 15:47:06 -0500 |
commit | da93dd6a272a45736da36ab37725a752de20ee85 (patch) | |
tree | cce3773c489c8d163d5e1285a01f097313889013 /drivers | |
parent | e46e5a7a71a4ca39c1501fcc42b55bafab9047c2 (diff) |
drivers: i2c: Cleanup sensor drivers
Replace volatile with READ ONLY control for
EEPROM and clean up multiple power sequences
during probe of the sensor drivers.
Bug 1881474
Change-Id: I0af9b6e13a38651ecb9991e063563eb2579c99ab
Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1591620
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/i2c/imx318.c | 118 | ||||
-rw-r--r-- | drivers/media/i2c/ov23850.c | 80 | ||||
-rw-r--r-- | drivers/media/i2c/ov5693.c | 126 |
3 files changed, 89 insertions, 235 deletions
diff --git a/drivers/media/i2c/imx318.c b/drivers/media/i2c/imx318.c index da604a8c9..d0ce9ba5e 100644 --- a/drivers/media/i2c/imx318.c +++ b/drivers/media/i2c/imx318.c | |||
@@ -93,11 +93,9 @@ static const struct regmap_config sensor_regmap_config = { | |||
93 | .use_single_rw = true, | 93 | .use_single_rw = true, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static int imx318_g_volatile_ctrl(struct v4l2_ctrl *ctrl); | ||
97 | static int imx318_s_ctrl(struct v4l2_ctrl *ctrl); | 96 | static int imx318_s_ctrl(struct v4l2_ctrl *ctrl); |
98 | 97 | ||
99 | static const struct v4l2_ctrl_ops imx318_ctrl_ops = { | 98 | static const struct v4l2_ctrl_ops imx318_ctrl_ops = { |
100 | .g_volatile_ctrl = imx318_g_volatile_ctrl, | ||
101 | .s_ctrl = imx318_s_ctrl, | 99 | .s_ctrl = imx318_s_ctrl, |
102 | }; | 100 | }; |
103 | 101 | ||
@@ -152,7 +150,7 @@ static struct v4l2_ctrl_config ctrl_config_list[] = { | |||
152 | .id = TEGRA_CAMERA_CID_EEPROM_DATA, | 150 | .id = TEGRA_CAMERA_CID_EEPROM_DATA, |
153 | .name = "EEPROM Data", | 151 | .name = "EEPROM Data", |
154 | .type = V4L2_CTRL_TYPE_STRING, | 152 | .type = V4L2_CTRL_TYPE_STRING, |
155 | .flags = V4L2_CTRL_FLAG_VOLATILE, | 153 | .flags = V4L2_CTRL_FLAG_READ_ONLY, |
156 | .min = 0, | 154 | .min = 0, |
157 | .max = IMX318_EEPROM_STR_SIZE, | 155 | .max = IMX318_EEPROM_STR_SIZE, |
158 | .step = 2, | 156 | .step = 2, |
@@ -726,10 +724,18 @@ static int imx318_eeprom_device_init(struct imx318 *priv) | |||
726 | return 0; | 724 | return 0; |
727 | } | 725 | } |
728 | 726 | ||
729 | static int imx318_read_eeprom(struct imx318 *priv, | 727 | static int imx318_read_eeprom(struct imx318 *priv) |
730 | struct v4l2_ctrl *ctrl) | ||
731 | { | 728 | { |
732 | int err, i; | 729 | int err, i; |
730 | struct v4l2_ctrl *ctrl; | ||
731 | |||
732 | ctrl = v4l2_ctrl_find(&priv->ctrl_handler, | ||
733 | TEGRA_CAMERA_CID_EEPROM_DATA); | ||
734 | if (!ctrl) { | ||
735 | dev_err(&priv->i2c_client->dev, | ||
736 | "could not find device ctrl.\n"); | ||
737 | return -EINVAL; | ||
738 | } | ||
733 | 739 | ||
734 | for (i = 0; i < IMX318_EEPROM_NUM_BLOCKS; i++) { | 740 | for (i = 0; i < IMX318_EEPROM_NUM_BLOCKS; i++) { |
735 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, | 741 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, |
@@ -745,36 +751,6 @@ static int imx318_read_eeprom(struct imx318 *priv, | |||
745 | return 0; | 751 | return 0; |
746 | } | 752 | } |
747 | 753 | ||
748 | static int imx318_write_eeprom(struct imx318 *priv, | ||
749 | char *string) | ||
750 | { | ||
751 | struct device *dev = &priv->i2c_client->dev; | ||
752 | int err; | ||
753 | int i; | ||
754 | u8 curr[3]; | ||
755 | unsigned long data; | ||
756 | |||
757 | for (i = 0; i < IMX318_EEPROM_SIZE; i++) { | ||
758 | curr[0] = string[i*2]; | ||
759 | curr[1] = string[i*2+1]; | ||
760 | curr[2] = '\0'; | ||
761 | |||
762 | err = kstrtol(curr, 16, &data); | ||
763 | if (err) { | ||
764 | dev_err(dev, "invalid eeprom string\n"); | ||
765 | return -EINVAL; | ||
766 | } | ||
767 | |||
768 | priv->eeprom_buf[i] = (u8)data; | ||
769 | err = regmap_write(priv->eeprom[i >> 8].regmap, | ||
770 | i & 0xFF, (u8)data); | ||
771 | if (err) | ||
772 | return err; | ||
773 | msleep(20); | ||
774 | } | ||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | /* TODO Validate id from sensor */ | 754 | /* TODO Validate id from sensor */ |
779 | static int imx318_fuse_id_setup(struct imx318 *priv) | 755 | static int imx318_fuse_id_setup(struct imx318 *priv) |
780 | { | 756 | { |
@@ -787,10 +763,6 @@ static int imx318_fuse_id_setup(struct imx318 *priv) | |||
787 | u8 fuse_id[IMX318_FUSE_ID_SIZE]; | 763 | u8 fuse_id[IMX318_FUSE_ID_SIZE]; |
788 | u8 bak = 0; | 764 | u8 bak = 0; |
789 | 765 | ||
790 | err = camera_common_s_power(priv->subdev, true); | ||
791 | if (err) | ||
792 | return -ENODEV; | ||
793 | |||
794 | for (i = 0; i < IMX318_FUSE_ID_SIZE; i++) { | 766 | for (i = 0; i < IMX318_FUSE_ID_SIZE; i++) { |
795 | err |= imx318_read_reg(s_data, | 767 | err |= imx318_read_reg(s_data, |
796 | IMX318_FUSE_ID_START_ADDR + i, &bak); | 768 | IMX318_FUSE_ID_START_ADDR + i, &bak); |
@@ -815,37 +787,9 @@ static int imx318_fuse_id_setup(struct imx318 *priv) | |||
815 | dev_info(&client->dev, "%s, fuse id: %s\n", __func__, | 787 | dev_info(&client->dev, "%s, fuse id: %s\n", __func__, |
816 | ctrl->p_cur.p_char); | 788 | ctrl->p_cur.p_char); |
817 | 789 | ||
818 | err = camera_common_s_power(priv->subdev, false); | ||
819 | if (err) | ||
820 | return -ENODEV; | ||
821 | |||
822 | return 0; | 790 | return 0; |
823 | } | 791 | } |
824 | 792 | ||
825 | static int imx318_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
826 | { | ||
827 | struct imx318 *priv = | ||
828 | container_of(ctrl->handler, struct imx318, ctrl_handler); | ||
829 | struct device *dev = &priv->i2c_client->dev; | ||
830 | int err = 0; | ||
831 | |||
832 | if (priv->power.state == SWITCH_OFF) | ||
833 | return 0; | ||
834 | |||
835 | switch (ctrl->id) { | ||
836 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
837 | err = imx318_read_eeprom(priv, ctrl); | ||
838 | if (err) | ||
839 | return err; | ||
840 | break; | ||
841 | default: | ||
842 | dev_err(dev, "%s: unknown ctrl id.\n", __func__); | ||
843 | return -EINVAL; | ||
844 | } | ||
845 | |||
846 | return err; | ||
847 | } | ||
848 | |||
849 | static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) | 793 | static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) |
850 | { | 794 | { |
851 | struct imx318 *priv = | 795 | struct imx318 *priv = |
@@ -866,13 +810,6 @@ static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) | |||
866 | case TEGRA_CAMERA_CID_COARSE_TIME: | 810 | case TEGRA_CAMERA_CID_COARSE_TIME: |
867 | err = imx318_set_coarse_time(priv, ctrl->val); | 811 | err = imx318_set_coarse_time(priv, ctrl->val); |
868 | break; | 812 | break; |
869 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
870 | if (!ctrl->p_new.p_char[0]) | ||
871 | break; | ||
872 | err = imx318_write_eeprom(priv, ctrl->p_new.p_char); | ||
873 | if (err) | ||
874 | return err; | ||
875 | break; | ||
876 | case TEGRA_CAMERA_CID_GROUP_HOLD: | 813 | case TEGRA_CAMERA_CID_GROUP_HOLD: |
877 | err = imx318_set_group_hold(priv, ctrl->val); | 814 | err = imx318_set_group_hold(priv, ctrl->val); |
878 | break; | 815 | break; |
@@ -889,7 +826,6 @@ static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) | |||
889 | static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) | 826 | static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) |
890 | { | 827 | { |
891 | struct i2c_client *client = priv->i2c_client; | 828 | struct i2c_client *client = priv->i2c_client; |
892 | struct camera_common_data *common_data = priv->s_data; | ||
893 | struct v4l2_ctrl *ctrl; | 829 | struct v4l2_ctrl *ctrl; |
894 | int num_ctrls; | 830 | int num_ctrls; |
895 | int err; | 831 | int err; |
@@ -901,16 +837,6 @@ static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) | |||
901 | v4l2_ctrl_handler_init(&priv->ctrl_handler, num_ctrls); | 837 | v4l2_ctrl_handler_init(&priv->ctrl_handler, num_ctrls); |
902 | 838 | ||
903 | for (i = 0; i < num_ctrls; i++) { | 839 | for (i = 0; i < num_ctrls; i++) { |
904 | /* | ||
905 | * Skip control 'TEGRA_CAMERA_CID_EEPROM_DATA' | ||
906 | * if eeprom inint err | ||
907 | */ | ||
908 | if (ctrl_config_list[i].id == TEGRA_CAMERA_CID_EEPROM_DATA) { | ||
909 | if (!eeprom_ctrl) { | ||
910 | common_data->numctrls -= 1; | ||
911 | continue; | ||
912 | } | ||
913 | } | ||
914 | ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, | 840 | ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, |
915 | &ctrl_config_list[i], NULL); | 841 | &ctrl_config_list[i], NULL); |
916 | if (ctrl == NULL) { | 842 | if (ctrl == NULL) { |
@@ -943,15 +869,35 @@ static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) | |||
943 | goto error; | 869 | goto error; |
944 | } | 870 | } |
945 | 871 | ||
872 | err = camera_common_s_power(priv->subdev, true); | ||
873 | if (err) { | ||
874 | dev_err(&client->dev, | ||
875 | "Error %d during power on sensor\n", err); | ||
876 | err = -ENODEV; | ||
877 | goto error; | ||
878 | } | ||
879 | |||
880 | if (eeprom_ctrl) { | ||
881 | err = imx318_read_eeprom(priv); | ||
882 | if (err) { | ||
883 | dev_err(&client->dev, | ||
884 | "Error %d reading eeprom data\n", err); | ||
885 | goto error_hw; | ||
886 | } | ||
887 | } | ||
888 | |||
946 | err = imx318_fuse_id_setup(priv); | 889 | err = imx318_fuse_id_setup(priv); |
947 | if (err) { | 890 | if (err) { |
948 | dev_err(&client->dev, | 891 | dev_err(&client->dev, |
949 | "Error %d reading fuse id data\n", err); | 892 | "Error %d reading fuse id data\n", err); |
950 | goto error; | 893 | goto error_hw; |
951 | } | 894 | } |
952 | 895 | ||
896 | camera_common_s_power(priv->subdev, false); | ||
953 | return 0; | 897 | return 0; |
954 | 898 | ||
899 | error_hw: | ||
900 | camera_common_s_power(priv->subdev, false); | ||
955 | error: | 901 | error: |
956 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | 902 | v4l2_ctrl_handler_free(&priv->ctrl_handler); |
957 | return err; | 903 | return err; |
diff --git a/drivers/media/i2c/ov23850.c b/drivers/media/i2c/ov23850.c index 6f0dd4504..210152c2e 100644 --- a/drivers/media/i2c/ov23850.c +++ b/drivers/media/i2c/ov23850.c | |||
@@ -114,11 +114,9 @@ static u16 ov23850_to_gain(u32 rep, int shift) | |||
114 | return gain; | 114 | return gain; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int ov23850_g_volatile_ctrl(struct v4l2_ctrl *ctrl); | ||
118 | static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl); | 117 | static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl); |
119 | 118 | ||
120 | static const struct v4l2_ctrl_ops ov23850_ctrl_ops = { | 119 | static const struct v4l2_ctrl_ops ov23850_ctrl_ops = { |
121 | .g_volatile_ctrl = ov23850_g_volatile_ctrl, | ||
122 | .s_ctrl = ov23850_s_ctrl, | 120 | .s_ctrl = ov23850_s_ctrl, |
123 | }; | 121 | }; |
124 | 122 | ||
@@ -830,10 +828,18 @@ static int ov23850_eeprom_device_init(struct ov23850 *priv) | |||
830 | return 0; | 828 | return 0; |
831 | } | 829 | } |
832 | 830 | ||
833 | static int ov23850_read_eeprom(struct ov23850 *priv, | 831 | static int ov23850_read_eeprom(struct ov23850 *priv) |
834 | struct v4l2_ctrl *ctrl) | ||
835 | { | 832 | { |
836 | int err, i; | 833 | int err, i; |
834 | struct v4l2_ctrl *ctrl; | ||
835 | |||
836 | ctrl = v4l2_ctrl_find(&priv->ctrl_handler, | ||
837 | TEGRA_CAMERA_CID_EEPROM_DATA); | ||
838 | if (!ctrl) { | ||
839 | dev_err(&priv->i2c_client->dev, | ||
840 | "could not find device ctrl.\n"); | ||
841 | return -EINVAL; | ||
842 | } | ||
837 | 843 | ||
838 | for (i = 0; i < OV23850_EEPROM_NUM_BLOCKS; i++) { | 844 | for (i = 0; i < OV23850_EEPROM_NUM_BLOCKS; i++) { |
839 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, | 845 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, |
@@ -978,10 +984,6 @@ static int ov23850_otp_setup(struct ov23850 *priv) | |||
978 | struct v4l2_ctrl *ctrl; | 984 | struct v4l2_ctrl *ctrl; |
979 | u8 otp_buf[OV23850_OTP_SIZE]; | 985 | u8 otp_buf[OV23850_OTP_SIZE]; |
980 | 986 | ||
981 | err = camera_common_s_power(priv->subdev, true); | ||
982 | if (err) | ||
983 | return -ENODEV; | ||
984 | |||
985 | err = ov23850_read_otp_manual(priv, | 987 | err = ov23850_read_otp_manual(priv, |
986 | otp_buf, | 988 | otp_buf, |
987 | OV23850_OTP_START_ADDR, | 989 | OV23850_OTP_START_ADDR, |
@@ -1000,10 +1002,6 @@ static int ov23850_otp_setup(struct ov23850 *priv) | |||
1000 | otp_buf[i]); | 1002 | otp_buf[i]); |
1001 | ctrl->p_cur.p_char = ctrl->p_new.p_char; | 1003 | ctrl->p_cur.p_char = ctrl->p_new.p_char; |
1002 | 1004 | ||
1003 | err = camera_common_s_power(priv->subdev, false); | ||
1004 | if (err) | ||
1005 | return -ENODEV; | ||
1006 | |||
1007 | return 0; | 1005 | return 0; |
1008 | } | 1006 | } |
1009 | 1007 | ||
@@ -1015,10 +1013,6 @@ static int ov23850_fuse_id_setup(struct ov23850 *priv) | |||
1015 | struct v4l2_ctrl *ctrl; | 1013 | struct v4l2_ctrl *ctrl; |
1016 | u8 fuse_id[OV23850_FUSE_ID_SIZE]; | 1014 | u8 fuse_id[OV23850_FUSE_ID_SIZE]; |
1017 | 1015 | ||
1018 | err = camera_common_s_power(priv->subdev, true); | ||
1019 | if (err) | ||
1020 | return -ENODEV; | ||
1021 | |||
1022 | err = ov23850_read_otp_manual(priv, | 1016 | err = ov23850_read_otp_manual(priv, |
1023 | fuse_id, | 1017 | fuse_id, |
1024 | OV23850_FUSE_ID_OTP_START_ADDR, | 1018 | OV23850_FUSE_ID_OTP_START_ADDR, |
@@ -1037,39 +1031,9 @@ static int ov23850_fuse_id_setup(struct ov23850 *priv) | |||
1037 | fuse_id[i]); | 1031 | fuse_id[i]); |
1038 | ctrl->p_cur.p_char = ctrl->p_new.p_char; | 1032 | ctrl->p_cur.p_char = ctrl->p_new.p_char; |
1039 | 1033 | ||
1040 | err = camera_common_s_power(priv->subdev, false); | ||
1041 | if (err) | ||
1042 | return -ENODEV; | ||
1043 | |||
1044 | return 0; | 1034 | return 0; |
1045 | } | 1035 | } |
1046 | 1036 | ||
1047 | static int ov23850_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
1048 | { | ||
1049 | struct ov23850 *priv = | ||
1050 | container_of(ctrl->handler, struct ov23850, ctrl_handler); | ||
1051 | struct device *dev = &priv->i2c_client->dev; | ||
1052 | int err = 0; | ||
1053 | |||
1054 | if (priv->power.state == SWITCH_OFF) | ||
1055 | return 0; | ||
1056 | |||
1057 | switch (ctrl->id) { | ||
1058 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
1059 | #if 0 | ||
1060 | err = ov23850_read_eeprom(priv, ctrl); | ||
1061 | if (err) | ||
1062 | return err; | ||
1063 | #endif | ||
1064 | break; | ||
1065 | default: | ||
1066 | dev_err(dev, "%s: unknown ctrl id.\n", __func__); | ||
1067 | return -EINVAL; | ||
1068 | } | ||
1069 | |||
1070 | return err; | ||
1071 | } | ||
1072 | |||
1073 | static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl) | 1037 | static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl) |
1074 | { | 1038 | { |
1075 | struct ov23850 *priv = | 1039 | struct ov23850 *priv = |
@@ -1101,15 +1065,6 @@ static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1101 | err = ov23850_set_group_hold(priv); | 1065 | err = ov23850_set_group_hold(priv); |
1102 | } | 1066 | } |
1103 | break; | 1067 | break; |
1104 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
1105 | #if 0 | ||
1106 | if (!ctrl->p_new.p_char[0]) | ||
1107 | break; | ||
1108 | err = ov23850_write_eeprom(priv, ctrl->p_new.p_char); | ||
1109 | if (err) | ||
1110 | return err; | ||
1111 | #endif | ||
1112 | break; | ||
1113 | case TEGRA_CAMERA_CID_HDR_EN: | 1068 | case TEGRA_CAMERA_CID_HDR_EN: |
1114 | break; | 1069 | break; |
1115 | default: | 1070 | default: |
@@ -1166,22 +1121,33 @@ static int ov23850_ctrls_init(struct ov23850 *priv) | |||
1166 | goto error; | 1121 | goto error; |
1167 | } | 1122 | } |
1168 | 1123 | ||
1124 | err = camera_common_s_power(priv->subdev, true); | ||
1125 | if (err) { | ||
1126 | dev_err(&client->dev, | ||
1127 | "Error %d during power on\n", err); | ||
1128 | err = -ENODEV; | ||
1129 | goto error; | ||
1130 | } | ||
1131 | |||
1169 | err = ov23850_otp_setup(priv); | 1132 | err = ov23850_otp_setup(priv); |
1170 | if (err) { | 1133 | if (err) { |
1171 | dev_err(&client->dev, | 1134 | dev_err(&client->dev, |
1172 | "Error %d reading otp data\n", err); | 1135 | "Error %d reading otp data\n", err); |
1173 | goto error; | 1136 | goto error_hw; |
1174 | } | 1137 | } |
1175 | 1138 | ||
1176 | err = ov23850_fuse_id_setup(priv); | 1139 | err = ov23850_fuse_id_setup(priv); |
1177 | if (err) { | 1140 | if (err) { |
1178 | dev_err(&client->dev, | 1141 | dev_err(&client->dev, |
1179 | "Error %d reading fuse id data\n", err); | 1142 | "Error %d reading fuse id data\n", err); |
1180 | goto error; | 1143 | goto error_hw; |
1181 | } | 1144 | } |
1182 | 1145 | ||
1146 | camera_common_s_power(priv->subdev, false); | ||
1183 | return 0; | 1147 | return 0; |
1184 | 1148 | ||
1149 | error_hw: | ||
1150 | camera_common_s_power(priv->subdev, false); | ||
1185 | error: | 1151 | error: |
1186 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | 1152 | v4l2_ctrl_handler_free(&priv->ctrl_handler); |
1187 | return err; | 1153 | return err; |
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c index b88040e1b..00d87b5bf 100644 --- a/drivers/media/i2c/ov5693.c +++ b/drivers/media/i2c/ov5693.c | |||
@@ -108,12 +108,10 @@ static struct tegra_i2c_rtcpu_config ov5693_i2c_rtcpu_config = { | |||
108 | .reg_bytes = 2, | 108 | .reg_bytes = 2, |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl); | ||
112 | static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl); | 111 | static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl); |
113 | static void ov5693_update_ctrl_range(struct ov5693 *priv, s32 frame_length); | 112 | static void ov5693_update_ctrl_range(struct ov5693 *priv, s32 frame_length); |
114 | 113 | ||
115 | static const struct v4l2_ctrl_ops ov5693_ctrl_ops = { | 114 | static const struct v4l2_ctrl_ops ov5693_ctrl_ops = { |
116 | .g_volatile_ctrl = ov5693_g_volatile_ctrl, | ||
117 | .s_ctrl = ov5693_s_ctrl, | 115 | .s_ctrl = ov5693_s_ctrl, |
118 | }; | 116 | }; |
119 | 117 | ||
@@ -190,7 +188,7 @@ static struct v4l2_ctrl_config ctrl_config_list[] = { | |||
190 | .id = TEGRA_CAMERA_CID_EEPROM_DATA, | 188 | .id = TEGRA_CAMERA_CID_EEPROM_DATA, |
191 | .name = "EEPROM Data", | 189 | .name = "EEPROM Data", |
192 | .type = V4L2_CTRL_TYPE_STRING, | 190 | .type = V4L2_CTRL_TYPE_STRING, |
193 | .flags = V4L2_CTRL_FLAG_VOLATILE, | 191 | .flags = V4L2_CTRL_FLAG_READ_ONLY, |
194 | .min = 0, | 192 | .min = 0, |
195 | .max = OV5693_EEPROM_STR_SIZE, | 193 | .max = OV5693_EEPROM_STR_SIZE, |
196 | .step = 2, | 194 | .step = 2, |
@@ -1005,10 +1003,18 @@ static int ov5693_eeprom_device_init(struct ov5693 *priv) | |||
1005 | return 0; | 1003 | return 0; |
1006 | } | 1004 | } |
1007 | 1005 | ||
1008 | static int ov5693_read_eeprom(struct ov5693 *priv, | 1006 | static int ov5693_read_eeprom(struct ov5693 *priv) |
1009 | struct v4l2_ctrl *ctrl) | ||
1010 | { | 1007 | { |
1011 | int err, i; | 1008 | int err, i; |
1009 | struct v4l2_ctrl *ctrl; | ||
1010 | |||
1011 | ctrl = v4l2_ctrl_find(&priv->ctrl_handler, | ||
1012 | TEGRA_CAMERA_CID_EEPROM_DATA); | ||
1013 | if (!ctrl) { | ||
1014 | dev_err(&priv->i2c_client->dev, | ||
1015 | "could not find device ctrl.\n"); | ||
1016 | return -EINVAL; | ||
1017 | } | ||
1012 | 1018 | ||
1013 | for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { | 1019 | for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { |
1014 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, | 1020 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, |
@@ -1024,36 +1030,6 @@ static int ov5693_read_eeprom(struct ov5693 *priv, | |||
1024 | return 0; | 1030 | return 0; |
1025 | } | 1031 | } |
1026 | 1032 | ||
1027 | static int ov5693_write_eeprom(struct ov5693 *priv, | ||
1028 | char *string) | ||
1029 | { | ||
1030 | struct device *dev = &priv->i2c_client->dev; | ||
1031 | int err; | ||
1032 | int i; | ||
1033 | u8 curr[3]; | ||
1034 | unsigned long data; | ||
1035 | |||
1036 | for (i = 0; i < OV5693_EEPROM_SIZE; i++) { | ||
1037 | curr[0] = string[i*2]; | ||
1038 | curr[1] = string[i*2+1]; | ||
1039 | curr[2] = '\0'; | ||
1040 | |||
1041 | err = kstrtol(curr, 16, &data); | ||
1042 | if (err) { | ||
1043 | dev_err(dev, "invalid eeprom string\n"); | ||
1044 | return -EINVAL; | ||
1045 | } | ||
1046 | |||
1047 | priv->eeprom_buf[i] = (u8)data; | ||
1048 | err = regmap_write(priv->eeprom[i >> 8].regmap, | ||
1049 | i & 0xFF, (u8)data); | ||
1050 | if (err) | ||
1051 | return err; | ||
1052 | msleep(20); | ||
1053 | } | ||
1054 | return 0; | ||
1055 | } | ||
1056 | |||
1057 | static int ov5693_read_otp_bank(struct ov5693 *priv, | 1033 | static int ov5693_read_otp_bank(struct ov5693 *priv, |
1058 | u8 *buf, int bank, u16 addr, int size) | 1034 | u8 *buf, int bank, u16 addr, int size) |
1059 | { | 1035 | { |
@@ -1099,10 +1075,6 @@ static int ov5693_otp_setup(struct ov5693 *priv) | |||
1099 | struct v4l2_ctrl *ctrl; | 1075 | struct v4l2_ctrl *ctrl; |
1100 | u8 otp_buf[OV5693_OTP_SIZE]; | 1076 | u8 otp_buf[OV5693_OTP_SIZE]; |
1101 | 1077 | ||
1102 | err = camera_common_s_power(priv->subdev, true); | ||
1103 | if (err) | ||
1104 | return -ENODEV; | ||
1105 | |||
1106 | for (i = 0; i < OV5693_OTP_NUM_BANKS; i++) { | 1078 | for (i = 0; i < OV5693_OTP_NUM_BANKS; i++) { |
1107 | err = ov5693_read_otp_bank(priv, | 1079 | err = ov5693_read_otp_bank(priv, |
1108 | &otp_buf[i * OV5693_OTP_BANK_SIZE], | 1080 | &otp_buf[i * OV5693_OTP_BANK_SIZE], |
@@ -1128,8 +1100,6 @@ static int ov5693_otp_setup(struct ov5693 *priv) | |||
1128 | ctrl->p_cur.p_char = ctrl->p_new.p_char; | 1100 | ctrl->p_cur.p_char = ctrl->p_new.p_char; |
1129 | 1101 | ||
1130 | ret: | 1102 | ret: |
1131 | camera_common_s_power(priv->subdev, false); | ||
1132 | |||
1133 | return err; | 1103 | return err; |
1134 | } | 1104 | } |
1135 | 1105 | ||
@@ -1141,10 +1111,6 @@ static int ov5693_fuse_id_setup(struct ov5693 *priv) | |||
1141 | struct v4l2_ctrl *ctrl; | 1111 | struct v4l2_ctrl *ctrl; |
1142 | u8 fuse_id[OV5693_FUSE_ID_SIZE]; | 1112 | u8 fuse_id[OV5693_FUSE_ID_SIZE]; |
1143 | 1113 | ||
1144 | err = camera_common_s_power(priv->subdev, true); | ||
1145 | if (err) | ||
1146 | return -ENODEV; | ||
1147 | |||
1148 | err = ov5693_read_otp_bank(priv, | 1114 | err = ov5693_read_otp_bank(priv, |
1149 | &fuse_id[0], | 1115 | &fuse_id[0], |
1150 | OV5693_FUSE_ID_OTP_BANK, | 1116 | OV5693_FUSE_ID_OTP_BANK, |
@@ -1168,32 +1134,6 @@ static int ov5693_fuse_id_setup(struct ov5693 *priv) | |||
1168 | ctrl->p_cur.p_char = ctrl->p_new.p_char; | 1134 | ctrl->p_cur.p_char = ctrl->p_new.p_char; |
1169 | 1135 | ||
1170 | ret: | 1136 | ret: |
1171 | camera_common_s_power(priv->subdev, false); | ||
1172 | |||
1173 | return err; | ||
1174 | } | ||
1175 | |||
1176 | static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
1177 | { | ||
1178 | struct ov5693 *priv = | ||
1179 | container_of(ctrl->handler, struct ov5693, ctrl_handler); | ||
1180 | struct device *dev = &priv->i2c_client->dev; | ||
1181 | int err = 0; | ||
1182 | |||
1183 | if (priv->power.state == SWITCH_OFF) | ||
1184 | return 0; | ||
1185 | |||
1186 | switch (ctrl->id) { | ||
1187 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
1188 | err = ov5693_read_eeprom(priv, ctrl); | ||
1189 | if (err) | ||
1190 | return err; | ||
1191 | break; | ||
1192 | default: | ||
1193 | dev_err(dev, "%s: unknown ctrl id.\n", __func__); | ||
1194 | return -EINVAL; | ||
1195 | } | ||
1196 | |||
1197 | return err; | 1137 | return err; |
1198 | } | 1138 | } |
1199 | 1139 | ||
@@ -1228,13 +1168,6 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1228 | err = ov5693_set_group_hold(priv); | 1168 | err = ov5693_set_group_hold(priv); |
1229 | } | 1169 | } |
1230 | break; | 1170 | break; |
1231 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
1232 | if (!ctrl->p_new.p_char[0]) | ||
1233 | break; | ||
1234 | err = ov5693_write_eeprom(priv, ctrl->p_new.p_char); | ||
1235 | if (err) | ||
1236 | return err; | ||
1237 | break; | ||
1238 | case TEGRA_CAMERA_CID_HDR_EN: | 1171 | case TEGRA_CAMERA_CID_HDR_EN: |
1239 | break; | 1172 | break; |
1240 | default: | 1173 | default: |
@@ -1248,7 +1181,6 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1248 | static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) | 1181 | static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) |
1249 | { | 1182 | { |
1250 | struct i2c_client *client = priv->i2c_client; | 1183 | struct i2c_client *client = priv->i2c_client; |
1251 | struct camera_common_data *common_data = priv->s_data; | ||
1252 | struct v4l2_ctrl *ctrl; | 1184 | struct v4l2_ctrl *ctrl; |
1253 | int numctrls; | 1185 | int numctrls; |
1254 | int err; | 1186 | int err; |
@@ -1260,17 +1192,6 @@ static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) | |||
1260 | v4l2_ctrl_handler_init(&priv->ctrl_handler, numctrls); | 1192 | v4l2_ctrl_handler_init(&priv->ctrl_handler, numctrls); |
1261 | 1193 | ||
1262 | for (i = 0; i < numctrls; i++) { | 1194 | for (i = 0; i < numctrls; i++) { |
1263 | /* | ||
1264 | * Skip control 'TEGRA_CAMERA_CID_EEPROM_DATA' | ||
1265 | * if eeprom inint err | ||
1266 | */ | ||
1267 | if (ctrl_config_list[i].id == TEGRA_CAMERA_CID_EEPROM_DATA) { | ||
1268 | if (!eeprom_ctrl) { | ||
1269 | common_data->numctrls -= 1; | ||
1270 | continue; | ||
1271 | } | ||
1272 | } | ||
1273 | |||
1274 | ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, | 1195 | ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, |
1275 | &ctrl_config_list[i], NULL); | 1196 | &ctrl_config_list[i], NULL); |
1276 | if (ctrl == NULL) { | 1197 | if (ctrl == NULL) { |
@@ -1305,21 +1226,42 @@ static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) | |||
1305 | goto error; | 1226 | goto error; |
1306 | } | 1227 | } |
1307 | 1228 | ||
1229 | err = camera_common_s_power(priv->subdev, true); | ||
1230 | if (err) { | ||
1231 | dev_err(&client->dev, | ||
1232 | "Error %d during power on\n", err); | ||
1233 | err = -ENODEV; | ||
1234 | goto error; | ||
1235 | } | ||
1236 | |||
1237 | if (eeprom_ctrl) { | ||
1238 | err = ov5693_read_eeprom(priv); | ||
1239 | if (err) { | ||
1240 | dev_err(&client->dev, | ||
1241 | "Error %d reading eeprom\n", err); | ||
1242 | goto error_hw; | ||
1243 | } | ||
1244 | } | ||
1245 | |||
1308 | err = ov5693_otp_setup(priv); | 1246 | err = ov5693_otp_setup(priv); |
1309 | if (err) { | 1247 | if (err) { |
1310 | dev_err(&client->dev, | 1248 | dev_err(&client->dev, |
1311 | "Error %d reading otp data\n", err); | 1249 | "Error %d reading otp data\n", err); |
1312 | goto error; | 1250 | goto error_hw; |
1313 | } | 1251 | } |
1314 | 1252 | ||
1315 | err = ov5693_fuse_id_setup(priv); | 1253 | err = ov5693_fuse_id_setup(priv); |
1316 | if (err) { | 1254 | if (err) { |
1317 | dev_err(&client->dev, | 1255 | dev_err(&client->dev, |
1318 | "Error %d reading fuse id data\n", err); | 1256 | "Error %d reading fuse id data\n", err); |
1319 | goto error; | 1257 | goto error_hw; |
1320 | } | 1258 | } |
1259 | |||
1260 | camera_common_s_power(priv->subdev, false); | ||
1321 | return 0; | 1261 | return 0; |
1322 | 1262 | ||
1263 | error_hw: | ||
1264 | camera_common_s_power(priv->subdev, false); | ||
1323 | error: | 1265 | error: |
1324 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | 1266 | v4l2_ctrl_handler_free(&priv->ctrl_handler); |
1325 | return err; | 1267 | return err; |