Support repeated start mode. Don't send a STOP if it's part of a group of transactions (e.g. write of register address followed by a register value read). Signed-off-by: Kelvin Lawson <klawson@xxxxxxxxxx> --- drivers/i2c/busses/i2c-qcom-cci.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index 143e44d..1032e16 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c @@ -512,7 +512,8 @@ static int cci_i2c_read(struct cci *cci, u16 addr, u8 *buf, u16 len) return 0; } -static int cci_i2c_write(struct cci *cci, u16 addr, u8 *buf, u16 len) +static int cci_i2c_write(struct cci *cci, u16 addr, u8 *buf, u16 len, + int disable_stop) { u8 master = 0; u8 queue = QUEUE_0; @@ -533,7 +534,8 @@ static int cci_i2c_write(struct cci *cci, u16 addr, u8 *buf, u16 len) writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); i = 0; - load[i++] = CCI_I2C_WRITE | len << 4; + load[i++] = (disable_stop ? CCI_I2C_WRITE_DISABLE_P : CCI_I2C_WRITE) + | len << 4; for (j = 0; j < len; j++) load[i++] = buf[j]; @@ -557,6 +559,13 @@ static int cci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) struct cci *cci = i2c_get_adapdata(adap); int i; int ret = 0; + int disable_stop = 0; + + /* + * Use repeated start (no STOP bit on writes) if this is a group of + * transactions (e.g. write register address followed by read data). + */ + disable_stop = num > 1; for (i = 0; i < num; i++) { if (msgs[i].flags & I2C_M_RD) -- 2.7.4