summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChew, Chiau Ee <chiau.ee.chew@intel.com>2013-06-21 15:05:28 +0800
committerWolfram Sang <wsa@the-dreams.de>2013-08-07 16:58:07 +0200
commit825642455367e5498da82a8044dd345ac7869c8d (patch)
tree999b3a3e79b0b5cfb8059a54720127427bda4b7a
parent9d3dda5c0d092d6bc9911bf24de81350d47c6be6 (diff)
i2c: designware: Manually set RESTART bit between messages
If both IC_EMPTYFIFO_HOLD_MASTER_EN and IC_RESTART_EN are set to 1, the Designware I2C controller doesn't generate RESTART unless user specifically requests it by setting RESTART bit in IC_DATA_CMD register. Since IC_EMPTYFIFO_HOLD_MASTER_EN setting can't be detected from hardware register, we must always manually set the restart bit between messages. Signed-off-by: Chew, Chiau Ee <chiau.ee.chew@intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index ad46616de29e..f325ec7abfb1 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -416,6 +416,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
u32 addr = msgs[dev->msg_write_idx].addr;
u32 buf_len = dev->tx_buf_len;
u8 *buf = dev->tx_buf;
+ bool need_restart = false;
intr_mask = DW_IC_INTR_DEFAULT_MASK;
@@ -443,6 +444,14 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
/* new i2c_msg */
buf = msgs[dev->msg_write_idx].buf;
buf_len = msgs[dev->msg_write_idx].len;
+
+ /* If both IC_EMPTYFIFO_HOLD_MASTER_EN and
+ * IC_RESTART_EN are set, we must manually
+ * set restart bit between messages.
+ */
+ if ((dev->master_cfg & DW_IC_CON_RESTART_EN) &&
+ (dev->msg_write_idx > 0))
+ need_restart = true;
}
tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR);
@@ -461,6 +470,11 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
buf_len == 1)
cmd |= BIT(9);
+ if (need_restart) {
+ cmd |= BIT(10);
+ need_restart = false;
+ }
+
if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
/* avoid rx buffer overrun */