diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-09-27 11:56:14 -0300 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-09-27 11:56:14 -0300 |
commit | 1025c04cecd19882e28f16c4004034b475c372c5 (patch) | |
tree | 2b7402887e86d54bff5a123228c9059eae5e32bd /drivers/i2c/busses/i2c-designware-core.c | |
parent | 4375f1037d52602413142e290608d0d84671ad36 (diff) | |
parent | 5bcecf325378218a8e248bb6bcae96ec7362f8ef (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Conflicts:
net/bluetooth/hci_core.c
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-core.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index ad46616de29..dbecf08399f 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -317,6 +317,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev) 47, /* tLOW = 4.7 us */ 3, /* tf = 0.3 us */ 0); /* No offset */ + + /* Allow platforms to specify the ideal HCNT and LCNT values */ + if (dev->ss_hcnt && dev->ss_lcnt) { + hcnt = dev->ss_hcnt; + lcnt = dev->ss_lcnt; + } dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT); dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT); dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); @@ -331,6 +337,11 @@ int i2c_dw_init(struct dw_i2c_dev *dev) 13, /* tLOW = 1.3 us */ 3, /* tf = 0.3 us */ 0); /* No offset */ + + if (dev->fs_hcnt && dev->fs_lcnt) { + hcnt = dev->fs_hcnt; + lcnt = dev->fs_lcnt; + } dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT); dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT); dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); @@ -416,6 +427,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 +455,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 +481,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 */ |