diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-11 13:43:03 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-11 13:43:03 +0200 |
commit | ad4fa274907bbc78ebabb015b4351d5f9226f081 (patch) | |
tree | 3eb033a3d6bedb50459ea0181e5180e1531d00e8 /drivers/i2c | |
parent | 3fcf4400a7b051bdbe9fc175b88336519099ff22 (diff) | |
parent | 3a0f44a7839d475c58720c4091d5e008215cd166 (diff) | |
download | barebox-ad4fa274907bbc78ebabb015b4351d5f9226f081.tar.gz barebox-ad4fa274907bbc78ebabb015b4351d5f9226f081.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-bcm283x.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/i2c/busses/i2c-bcm283x.c b/drivers/i2c/busses/i2c-bcm283x.c index 097f73d983..fdba3b91bd 100644 --- a/drivers/i2c/busses/i2c-bcm283x.c +++ b/drivers/i2c/busses/i2c-bcm283x.c @@ -147,7 +147,7 @@ static int bcm283x_i2c_msg_xfer(struct bcm283x_i2c *bcm_i2c, if (ret) { dev_err(dev, "timeout: 10bit read initilization\n"); - return ret; + goto out; } if (reg_s & BSC_S_ERR) goto nack; @@ -178,7 +178,7 @@ static int bcm283x_i2c_msg_xfer(struct bcm283x_i2c *bcm_i2c, if (ret) { dev_err(dev, "timeout: waiting for data in FIFO\n"); - return ret; + goto out; } if (reg_s & BSC_S_ERR) goto nack; @@ -197,7 +197,7 @@ static int bcm283x_i2c_msg_xfer(struct bcm283x_i2c *bcm_i2c, if (ret) { dev_err(dev, "timeout: waiting for space in FIFO\n"); - return ret; + goto out; } if (reg_s & BSC_S_ERR) goto nack; @@ -216,16 +216,23 @@ static int bcm283x_i2c_msg_xfer(struct bcm283x_i2c *bcm_i2c, if (ret) { dev_err(dev, "timeout: waiting for transfer to end\n"); - return ret; + goto out; } if (reg_s & BSC_S_ERR) goto nack; - writel(BSC_S_DONE | BSC_S_ERR | BSC_S_CLKT, &bcm_i2c->regs->s); - writel(BSC_C_CLEAR1 | BSC_C_I2CEN, &bcm_i2c->regs->c); - return 0; + goto out; nack: dev_dbg(dev, "device with addr %x didn't ACK\n", msg->addr); - return -EREMOTEIO; + writel(BSC_S_ERR, &bcm_i2c->regs->s); + timeout = calc_byte_timeout_us(bcm_i2c->bitrate); + // Wait for end of transfer so BSC has time to send STOP condition + readl_poll_timeout(&bcm_i2c->regs->s, reg_s, ~reg_s & BSC_S_TA, timeout); + ret = -EREMOTEIO; +out: + // Return to default state for next xfer + writel(BSC_S_DONE | BSC_S_ERR | BSC_S_CLKT, &bcm_i2c->regs->s); + writel(BSC_C_CLEAR1 | BSC_C_I2CEN, &bcm_i2c->regs->c); + return ret; } static int bcm283x_i2c_xfer(struct i2c_adapter *adapter, |