From da93dd6a272a45736da36ab37725a752de20ee85 Mon Sep 17 00:00:00 2001 From: Bhanu Murthy V Date: Thu, 2 Nov 2017 17:03:28 -0700 Subject: 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 Reviewed-on: https://git-master.nvidia.com/r/1591620 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Jihoon Bang Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/media/i2c/imx318.c | 118 +++++++++++------------------------------ drivers/media/i2c/ov23850.c | 80 ++++++++-------------------- drivers/media/i2c/ov5693.c | 126 ++++++++++++-------------------------------- 3 files changed, 89 insertions(+), 235 deletions(-) (limited to 'drivers/media') 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 = { .use_single_rw = true, }; -static int imx318_g_volatile_ctrl(struct v4l2_ctrl *ctrl); static int imx318_s_ctrl(struct v4l2_ctrl *ctrl); static const struct v4l2_ctrl_ops imx318_ctrl_ops = { - .g_volatile_ctrl = imx318_g_volatile_ctrl, .s_ctrl = imx318_s_ctrl, }; @@ -152,7 +150,7 @@ static struct v4l2_ctrl_config ctrl_config_list[] = { .id = TEGRA_CAMERA_CID_EEPROM_DATA, .name = "EEPROM Data", .type = V4L2_CTRL_TYPE_STRING, - .flags = V4L2_CTRL_FLAG_VOLATILE, + .flags = V4L2_CTRL_FLAG_READ_ONLY, .min = 0, .max = IMX318_EEPROM_STR_SIZE, .step = 2, @@ -726,10 +724,18 @@ static int imx318_eeprom_device_init(struct imx318 *priv) return 0; } -static int imx318_read_eeprom(struct imx318 *priv, - struct v4l2_ctrl *ctrl) +static int imx318_read_eeprom(struct imx318 *priv) { int err, i; + struct v4l2_ctrl *ctrl; + + ctrl = v4l2_ctrl_find(&priv->ctrl_handler, + TEGRA_CAMERA_CID_EEPROM_DATA); + if (!ctrl) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return -EINVAL; + } for (i = 0; i < IMX318_EEPROM_NUM_BLOCKS; i++) { err = regmap_bulk_read(priv->eeprom[i].regmap, 0, @@ -745,36 +751,6 @@ static int imx318_read_eeprom(struct imx318 *priv, return 0; } -static int imx318_write_eeprom(struct imx318 *priv, - char *string) -{ - struct device *dev = &priv->i2c_client->dev; - int err; - int i; - u8 curr[3]; - unsigned long data; - - for (i = 0; i < IMX318_EEPROM_SIZE; i++) { - curr[0] = string[i*2]; - curr[1] = string[i*2+1]; - curr[2] = '\0'; - - err = kstrtol(curr, 16, &data); - if (err) { - dev_err(dev, "invalid eeprom string\n"); - return -EINVAL; - } - - priv->eeprom_buf[i] = (u8)data; - err = regmap_write(priv->eeprom[i >> 8].regmap, - i & 0xFF, (u8)data); - if (err) - return err; - msleep(20); - } - return 0; -} - /* TODO Validate id from sensor */ static int imx318_fuse_id_setup(struct imx318 *priv) { @@ -787,10 +763,6 @@ static int imx318_fuse_id_setup(struct imx318 *priv) u8 fuse_id[IMX318_FUSE_ID_SIZE]; u8 bak = 0; - err = camera_common_s_power(priv->subdev, true); - if (err) - return -ENODEV; - for (i = 0; i < IMX318_FUSE_ID_SIZE; i++) { err |= imx318_read_reg(s_data, IMX318_FUSE_ID_START_ADDR + i, &bak); @@ -815,37 +787,9 @@ static int imx318_fuse_id_setup(struct imx318 *priv) dev_info(&client->dev, "%s, fuse id: %s\n", __func__, ctrl->p_cur.p_char); - err = camera_common_s_power(priv->subdev, false); - if (err) - return -ENODEV; - return 0; } -static int imx318_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct imx318 *priv = - container_of(ctrl->handler, struct imx318, ctrl_handler); - struct device *dev = &priv->i2c_client->dev; - int err = 0; - - if (priv->power.state == SWITCH_OFF) - return 0; - - switch (ctrl->id) { - case TEGRA_CAMERA_CID_EEPROM_DATA: - err = imx318_read_eeprom(priv, ctrl); - if (err) - return err; - break; - default: - dev_err(dev, "%s: unknown ctrl id.\n", __func__); - return -EINVAL; - } - - return err; -} - static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) { struct imx318 *priv = @@ -866,13 +810,6 @@ static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) case TEGRA_CAMERA_CID_COARSE_TIME: err = imx318_set_coarse_time(priv, ctrl->val); break; - case TEGRA_CAMERA_CID_EEPROM_DATA: - if (!ctrl->p_new.p_char[0]) - break; - err = imx318_write_eeprom(priv, ctrl->p_new.p_char); - if (err) - return err; - break; case TEGRA_CAMERA_CID_GROUP_HOLD: err = imx318_set_group_hold(priv, ctrl->val); break; @@ -889,7 +826,6 @@ static int imx318_s_ctrl(struct v4l2_ctrl *ctrl) static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) { struct i2c_client *client = priv->i2c_client; - struct camera_common_data *common_data = priv->s_data; struct v4l2_ctrl *ctrl; int num_ctrls; int err; @@ -901,16 +837,6 @@ static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) v4l2_ctrl_handler_init(&priv->ctrl_handler, num_ctrls); for (i = 0; i < num_ctrls; i++) { - /* - * Skip control 'TEGRA_CAMERA_CID_EEPROM_DATA' - * if eeprom inint err - */ - if (ctrl_config_list[i].id == TEGRA_CAMERA_CID_EEPROM_DATA) { - if (!eeprom_ctrl) { - common_data->numctrls -= 1; - continue; - } - } ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, &ctrl_config_list[i], NULL); if (ctrl == NULL) { @@ -943,15 +869,35 @@ static int imx318_ctrls_init(struct imx318 *priv, bool eeprom_ctrl) goto error; } + err = camera_common_s_power(priv->subdev, true); + if (err) { + dev_err(&client->dev, + "Error %d during power on sensor\n", err); + err = -ENODEV; + goto error; + } + + if (eeprom_ctrl) { + err = imx318_read_eeprom(priv); + if (err) { + dev_err(&client->dev, + "Error %d reading eeprom data\n", err); + goto error_hw; + } + } + err = imx318_fuse_id_setup(priv); if (err) { dev_err(&client->dev, "Error %d reading fuse id data\n", err); - goto error; + goto error_hw; } + camera_common_s_power(priv->subdev, false); return 0; +error_hw: + camera_common_s_power(priv->subdev, false); error: v4l2_ctrl_handler_free(&priv->ctrl_handler); 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) return gain; } -static int ov23850_g_volatile_ctrl(struct v4l2_ctrl *ctrl); static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl); static const struct v4l2_ctrl_ops ov23850_ctrl_ops = { - .g_volatile_ctrl = ov23850_g_volatile_ctrl, .s_ctrl = ov23850_s_ctrl, }; @@ -830,10 +828,18 @@ static int ov23850_eeprom_device_init(struct ov23850 *priv) return 0; } -static int ov23850_read_eeprom(struct ov23850 *priv, - struct v4l2_ctrl *ctrl) +static int ov23850_read_eeprom(struct ov23850 *priv) { int err, i; + struct v4l2_ctrl *ctrl; + + ctrl = v4l2_ctrl_find(&priv->ctrl_handler, + TEGRA_CAMERA_CID_EEPROM_DATA); + if (!ctrl) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return -EINVAL; + } for (i = 0; i < OV23850_EEPROM_NUM_BLOCKS; i++) { err = regmap_bulk_read(priv->eeprom[i].regmap, 0, @@ -978,10 +984,6 @@ static int ov23850_otp_setup(struct ov23850 *priv) struct v4l2_ctrl *ctrl; u8 otp_buf[OV23850_OTP_SIZE]; - err = camera_common_s_power(priv->subdev, true); - if (err) - return -ENODEV; - err = ov23850_read_otp_manual(priv, otp_buf, OV23850_OTP_START_ADDR, @@ -1000,10 +1002,6 @@ static int ov23850_otp_setup(struct ov23850 *priv) otp_buf[i]); ctrl->p_cur.p_char = ctrl->p_new.p_char; - err = camera_common_s_power(priv->subdev, false); - if (err) - return -ENODEV; - return 0; } @@ -1015,10 +1013,6 @@ static int ov23850_fuse_id_setup(struct ov23850 *priv) struct v4l2_ctrl *ctrl; u8 fuse_id[OV23850_FUSE_ID_SIZE]; - err = camera_common_s_power(priv->subdev, true); - if (err) - return -ENODEV; - err = ov23850_read_otp_manual(priv, fuse_id, OV23850_FUSE_ID_OTP_START_ADDR, @@ -1037,39 +1031,9 @@ static int ov23850_fuse_id_setup(struct ov23850 *priv) fuse_id[i]); ctrl->p_cur.p_char = ctrl->p_new.p_char; - err = camera_common_s_power(priv->subdev, false); - if (err) - return -ENODEV; - return 0; } -static int ov23850_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct ov23850 *priv = - container_of(ctrl->handler, struct ov23850, ctrl_handler); - struct device *dev = &priv->i2c_client->dev; - int err = 0; - - if (priv->power.state == SWITCH_OFF) - return 0; - - switch (ctrl->id) { - case TEGRA_CAMERA_CID_EEPROM_DATA: -#if 0 - err = ov23850_read_eeprom(priv, ctrl); - if (err) - return err; -#endif - break; - default: - dev_err(dev, "%s: unknown ctrl id.\n", __func__); - return -EINVAL; - } - - return err; -} - static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl) { struct ov23850 *priv = @@ -1101,15 +1065,6 @@ static int ov23850_s_ctrl(struct v4l2_ctrl *ctrl) err = ov23850_set_group_hold(priv); } break; - case TEGRA_CAMERA_CID_EEPROM_DATA: -#if 0 - if (!ctrl->p_new.p_char[0]) - break; - err = ov23850_write_eeprom(priv, ctrl->p_new.p_char); - if (err) - return err; -#endif - break; case TEGRA_CAMERA_CID_HDR_EN: break; default: @@ -1166,22 +1121,33 @@ static int ov23850_ctrls_init(struct ov23850 *priv) goto error; } + err = camera_common_s_power(priv->subdev, true); + if (err) { + dev_err(&client->dev, + "Error %d during power on\n", err); + err = -ENODEV; + goto error; + } + err = ov23850_otp_setup(priv); if (err) { dev_err(&client->dev, "Error %d reading otp data\n", err); - goto error; + goto error_hw; } err = ov23850_fuse_id_setup(priv); if (err) { dev_err(&client->dev, "Error %d reading fuse id data\n", err); - goto error; + goto error_hw; } + camera_common_s_power(priv->subdev, false); return 0; +error_hw: + camera_common_s_power(priv->subdev, false); error: v4l2_ctrl_handler_free(&priv->ctrl_handler); 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 = { .reg_bytes = 2, }; -static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl); static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl); static void ov5693_update_ctrl_range(struct ov5693 *priv, s32 frame_length); static const struct v4l2_ctrl_ops ov5693_ctrl_ops = { - .g_volatile_ctrl = ov5693_g_volatile_ctrl, .s_ctrl = ov5693_s_ctrl, }; @@ -190,7 +188,7 @@ static struct v4l2_ctrl_config ctrl_config_list[] = { .id = TEGRA_CAMERA_CID_EEPROM_DATA, .name = "EEPROM Data", .type = V4L2_CTRL_TYPE_STRING, - .flags = V4L2_CTRL_FLAG_VOLATILE, + .flags = V4L2_CTRL_FLAG_READ_ONLY, .min = 0, .max = OV5693_EEPROM_STR_SIZE, .step = 2, @@ -1005,10 +1003,18 @@ static int ov5693_eeprom_device_init(struct ov5693 *priv) return 0; } -static int ov5693_read_eeprom(struct ov5693 *priv, - struct v4l2_ctrl *ctrl) +static int ov5693_read_eeprom(struct ov5693 *priv) { int err, i; + struct v4l2_ctrl *ctrl; + + ctrl = v4l2_ctrl_find(&priv->ctrl_handler, + TEGRA_CAMERA_CID_EEPROM_DATA); + if (!ctrl) { + dev_err(&priv->i2c_client->dev, + "could not find device ctrl.\n"); + return -EINVAL; + } for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { err = regmap_bulk_read(priv->eeprom[i].regmap, 0, @@ -1024,36 +1030,6 @@ static int ov5693_read_eeprom(struct ov5693 *priv, return 0; } -static int ov5693_write_eeprom(struct ov5693 *priv, - char *string) -{ - struct device *dev = &priv->i2c_client->dev; - int err; - int i; - u8 curr[3]; - unsigned long data; - - for (i = 0; i < OV5693_EEPROM_SIZE; i++) { - curr[0] = string[i*2]; - curr[1] = string[i*2+1]; - curr[2] = '\0'; - - err = kstrtol(curr, 16, &data); - if (err) { - dev_err(dev, "invalid eeprom string\n"); - return -EINVAL; - } - - priv->eeprom_buf[i] = (u8)data; - err = regmap_write(priv->eeprom[i >> 8].regmap, - i & 0xFF, (u8)data); - if (err) - return err; - msleep(20); - } - return 0; -} - static int ov5693_read_otp_bank(struct ov5693 *priv, u8 *buf, int bank, u16 addr, int size) { @@ -1099,10 +1075,6 @@ static int ov5693_otp_setup(struct ov5693 *priv) struct v4l2_ctrl *ctrl; u8 otp_buf[OV5693_OTP_SIZE]; - err = camera_common_s_power(priv->subdev, true); - if (err) - return -ENODEV; - for (i = 0; i < OV5693_OTP_NUM_BANKS; i++) { err = ov5693_read_otp_bank(priv, &otp_buf[i * OV5693_OTP_BANK_SIZE], @@ -1128,8 +1100,6 @@ static int ov5693_otp_setup(struct ov5693 *priv) ctrl->p_cur.p_char = ctrl->p_new.p_char; ret: - camera_common_s_power(priv->subdev, false); - return err; } @@ -1141,10 +1111,6 @@ static int ov5693_fuse_id_setup(struct ov5693 *priv) struct v4l2_ctrl *ctrl; u8 fuse_id[OV5693_FUSE_ID_SIZE]; - err = camera_common_s_power(priv->subdev, true); - if (err) - return -ENODEV; - err = ov5693_read_otp_bank(priv, &fuse_id[0], OV5693_FUSE_ID_OTP_BANK, @@ -1168,32 +1134,6 @@ static int ov5693_fuse_id_setup(struct ov5693 *priv) ctrl->p_cur.p_char = ctrl->p_new.p_char; ret: - camera_common_s_power(priv->subdev, false); - - return err; -} - -static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct ov5693 *priv = - container_of(ctrl->handler, struct ov5693, ctrl_handler); - struct device *dev = &priv->i2c_client->dev; - int err = 0; - - if (priv->power.state == SWITCH_OFF) - return 0; - - switch (ctrl->id) { - case TEGRA_CAMERA_CID_EEPROM_DATA: - err = ov5693_read_eeprom(priv, ctrl); - if (err) - return err; - break; - default: - dev_err(dev, "%s: unknown ctrl id.\n", __func__); - return -EINVAL; - } - return err; } @@ -1228,13 +1168,6 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl) err = ov5693_set_group_hold(priv); } break; - case TEGRA_CAMERA_CID_EEPROM_DATA: - if (!ctrl->p_new.p_char[0]) - break; - err = ov5693_write_eeprom(priv, ctrl->p_new.p_char); - if (err) - return err; - break; case TEGRA_CAMERA_CID_HDR_EN: break; default: @@ -1248,7 +1181,6 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl) static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) { struct i2c_client *client = priv->i2c_client; - struct camera_common_data *common_data = priv->s_data; struct v4l2_ctrl *ctrl; int numctrls; int err; @@ -1260,17 +1192,6 @@ static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) v4l2_ctrl_handler_init(&priv->ctrl_handler, numctrls); for (i = 0; i < numctrls; i++) { - /* - * Skip control 'TEGRA_CAMERA_CID_EEPROM_DATA' - * if eeprom inint err - */ - if (ctrl_config_list[i].id == TEGRA_CAMERA_CID_EEPROM_DATA) { - if (!eeprom_ctrl) { - common_data->numctrls -= 1; - continue; - } - } - ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, &ctrl_config_list[i], NULL); if (ctrl == NULL) { @@ -1305,21 +1226,42 @@ static int ov5693_ctrls_init(struct ov5693 *priv, bool eeprom_ctrl) goto error; } + err = camera_common_s_power(priv->subdev, true); + if (err) { + dev_err(&client->dev, + "Error %d during power on\n", err); + err = -ENODEV; + goto error; + } + + if (eeprom_ctrl) { + err = ov5693_read_eeprom(priv); + if (err) { + dev_err(&client->dev, + "Error %d reading eeprom\n", err); + goto error_hw; + } + } + err = ov5693_otp_setup(priv); if (err) { dev_err(&client->dev, "Error %d reading otp data\n", err); - goto error; + goto error_hw; } err = ov5693_fuse_id_setup(priv); if (err) { dev_err(&client->dev, "Error %d reading fuse id data\n", err); - goto error; + goto error_hw; } + + camera_common_s_power(priv->subdev, false); return 0; +error_hw: + camera_common_s_power(priv->subdev, false); error: v4l2_ctrl_handler_free(&priv->ctrl_handler); return err; -- cgit v1.2.2