diff options
Diffstat (limited to 'drivers/media/i2c/ov5693.c')
-rw-r--r-- | drivers/media/i2c/ov5693.c | 126 |
1 files changed, 34 insertions, 92 deletions
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; |