From 24af85aaf679a87d09fa86d5a3fd0d43b6b631b8 Mon Sep 17 00:00:00 2001 From: Paolo Pisati Date: Thu, 5 Apr 2018 13:41:58 +0200 Subject: [PATCH] UBUNTU: SAUCE: media: ov5645: skip address change if dt addr == default addr BugLink: http://bugs.launchpad.net/bugs/1763040 Signed-off-by: Paolo Pisati Acked-by: Seth Forshee Acked-by: Thadeu Lima de Souza Cascardo Signed-off-by: Thadeu Lima de Souza Cascardo --- drivers/media/i2c/ov5645.c | 61 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c index 8135d4a4e8b1..d6392953117a 100644 --- a/drivers/media/i2c/ov5645.c +++ b/drivers/media/i2c/ov5645.c @@ -593,6 +593,45 @@ static void ov5645_regulators_disable(struct ov5645 *ov5645) dev_err(ov5645->dev, "io regulator disable failed\n"); } +static int ov5645_read_reg_from(struct ov5645 *ov5645, u16 reg, u8 *val, + u16 i2c_addr) +{ + u8 regbuf[2] = { + reg >> 8, + reg & 0xff, + }; + struct i2c_msg req = { + .addr = i2c_addr, + .flags = 0, + .len = 2, + .buf = regbuf + }; + struct i2c_msg read = { + .addr = i2c_addr, + .flags = I2C_M_RD, + .len = 1, + .buf = val + }; + int ret; + + ret = i2c_transfer(ov5645->i2c_client->adapter, &req, 1); + if (ret < 0) + dev_err(ov5645->dev, + "%s: req reg error %d on addr 0x%x: reg=0x%x\n", + __func__, ret, i2c_addr, reg); + + + ret = i2c_transfer(ov5645->i2c_client->adapter, &read, 1); + if (ret < 0) { + dev_err(ov5645->dev, + "%s: read reg error %d on addr 0x%x: reg=0x%x\n", + __func__, ret, i2c_addr, reg); + return ret; + } + + return ret; +} + static int ov5645_write_reg_to(struct ov5645 *ov5645, u16 reg, u8 val, u16 i2c_addr) { @@ -749,6 +788,7 @@ static int ov5645_s_power(struct v4l2_subdev *sd, int on) { struct ov5645 *ov5645 = to_ov5645(sd); int ret = 0; + u8 addr; mutex_lock(&ov5645->power_lock); @@ -765,16 +805,31 @@ static int ov5645_s_power(struct v4l2_subdev *sd, int on) goto exit; } - ret = ov5645_write_reg_to(ov5645, 0x3100, - ov5645->i2c_client->addr << 1, 0x3c); + ret = ov5645_read_reg_from(ov5645, 0x3100, &addr, 0x3c); if (ret < 0) { dev_err(ov5645->dev, - "could not change i2c address\n"); + "could not read sensor address\n"); ov5645_set_power_off(ov5645); mutex_unlock(&ov5645_lock); goto exit; } + /* + * change sensor address only if the one supplied in the + * DT is different from the default one + */ + if (addr != ov5645->i2c_client->addr) { + ret = ov5645_write_reg_to(ov5645, 0x3100, + ov5645->i2c_client->addr << 1, 0x3c); + if (ret < 0) { + dev_err(ov5645->dev, + "could not change i2c address\n"); + ov5645_set_power_off(ov5645); + mutex_unlock(&ov5645_lock); + goto exit; + } + } + mutex_unlock(&ov5645_lock); ret = ov5645_set_register_array(ov5645, -- 2.39.2