aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-01-17 05:31:05 -0500
committerWolfram Sang <w.sang@pengutronix.de>2013-01-27 23:26:42 -0500
commit17a76b4b32aca7c19df6988213dfe2eb4b631431 (patch)
tree06a41fa292a7af4e8001ee1157bcb9574fd0d932 /drivers/i2c
parent5c38dc8911b86b7c49305e2f2b631cd1241f2d87 (diff)
i2c-designware: always set the STOP bit after last byte
If IC_EMPTYFIFO_HOLD_MASTER_EN is set to one, the DesignWare I2C controller doesn't generate STOP on the bus when the FIFO is empty. This violates the rules of Linux I2C stack as it requires that the STOP is issued once the i2c_transfer() is finished. However, there is no way to detect this from the hardware registers, so we must make sure that the STOP bit is always set once the last byte of the last message is transferred. This patch is based on the work of Dirk Brandewie. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index f5258c205de5..94fd81875409 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -413,11 +413,23 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
413 rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); 413 rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR);
414 414
415 while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { 415 while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
416 u32 cmd = 0;
417
418 /*
419 * If IC_EMPTYFIFO_HOLD_MASTER_EN is set we must
420 * manually set the stop bit. However, it cannot be
421 * detected from the registers so we set it always
422 * when writing/reading the last byte.
423 */
424 if (dev->msg_write_idx == dev->msgs_num - 1 &&
425 buf_len == 1)
426 cmd |= BIT(9);
427
416 if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { 428 if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
417 dw_writel(dev, 0x100, DW_IC_DATA_CMD); 429 dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD);
418 rx_limit--; 430 rx_limit--;
419 } else 431 } else
420 dw_writel(dev, *buf++, DW_IC_DATA_CMD); 432 dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD);
421 tx_limit--; buf_len--; 433 tx_limit--; buf_len--;
422 } 434 }
423 435