X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=drivers%2Fi2c%2Fbusses%2Fi2c-designware-core.c;h=dbecf08399f86dd30baa7fa7b8964e2daf616bcb;hb=31f7c3a688f75bceaf2fd009efc489659ad6aa61;hp=ad46616de29ec8638aeb2a17c6ff231d59c57596;hpb=f9ed432c929f005110c23eb00702265fc4c08e66;p=~andy%2Flinux 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 */