summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-designware-master.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-master.c')
-rw-r--r--drivers/i2c/busses/i2c-designware-master.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index cb3ac1f39cb6..6b64e3d01fd9 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -45,6 +45,11 @@ static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
dw_writel(dev, dev->master_cfg, DW_IC_CON);
}
+static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
+{
+ return i2c_dw_set_sda_hold(dev);
+}
+
/**
* i2c_dw_init() - Initialize the designware I2C master hardware
* @dev: device private data
@@ -57,7 +62,7 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
{
u32 ic_clk = i2c_dw_clk_rate(dev);
u32 hcnt, lcnt;
- u32 reg, comp_param1;
+ u32 comp_param1;
u32 sda_falling_time, scl_falling_time;
int ret;
@@ -133,27 +138,9 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
}
}
- /* Configure SDA Hold Time if required */
- reg = dw_readl(dev, DW_IC_COMP_VERSION);
- if (reg >= DW_IC_SDA_HOLD_MIN_VERS) {
- if (!dev->sda_hold_time) {
- /* Keep previous hold time setting if no one set it */
- dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD);
- }
- /*
- * Workaround for avoiding TX arbitration lost in case I2C
- * slave pulls SDA down "too quickly" after falling egde of
- * SCL by enabling non-zero SDA RX hold. Specification says it
- * extends incoming SDA low to high transition while SCL is
- * high but it apprears to help also above issue.
- */
- if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK))
- dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT;
+ /* Write SDA hold time if supported */
+ if (dev->sda_hold_time)
dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
- } else if (dev->sda_hold_time) {
- dev_warn(dev->dev,
- "Hardware too old to adjust SDA hold time.\n");
- }
i2c_dw_configure_fifo_master(dev);
i2c_dw_release_lock(dev);
@@ -672,6 +659,10 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
if (ret)
return ret;
+ ret = i2c_dw_set_timings_master(dev);
+ if (ret)
+ return ret;
+
ret = dev->init(dev);
if (ret)
return ret;