diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-core.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 14c4b30d4ccc..22e92c3d3d07 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -218,7 +218,7 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) * * If your hardware is free from tHD;STA issue, try this one. */ - return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; + return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset; else /* * Conditional expression: @@ -234,7 +234,8 @@ i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) * The reason why we need to take into account "tf" here, * is the same as described in i2c_dw_scl_lcnt(). */ - return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; + return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000 + - 3 + offset; } static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) @@ -250,7 +251,7 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) * account the fall time of SCL signal (tf). Default tf value * should be 0.3 us, for safety. */ - return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; + return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset; } static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) @@ -287,6 +288,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) u32 input_clock_khz; u32 hcnt, lcnt; u32 reg; + u32 sda_falling_time, scl_falling_time; input_clock_khz = dev->get_clk_rate_khz(dev); @@ -308,15 +310,18 @@ int i2c_dw_init(struct dw_i2c_dev *dev) /* set standard and fast speed deviders for high/low periods */ + sda_falling_time = dev->sda_falling_time ?: 300; /* ns */ + scl_falling_time = dev->scl_falling_time ?: 300; /* ns */ + /* Standard-mode */ hcnt = i2c_dw_scl_hcnt(input_clock_khz, - 40, /* tHD;STA = tHIGH = 4.0 us */ - 3, /* tf = 0.3 us */ + 4000, /* tHD;STA = tHIGH = 4.0 us */ + sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ lcnt = i2c_dw_scl_lcnt(input_clock_khz, - 47, /* tLOW = 4.7 us */ - 3, /* tf = 0.3 us */ + 4700, /* tLOW = 4.7 us */ + scl_falling_time, 0); /* No offset */ /* Allow platforms to specify the ideal HCNT and LCNT values */ @@ -330,13 +335,13 @@ int i2c_dw_init(struct dw_i2c_dev *dev) /* Fast-mode */ hcnt = i2c_dw_scl_hcnt(input_clock_khz, - 6, /* tHD;STA = tHIGH = 0.6 us */ - 3, /* tf = 0.3 us */ + 600, /* tHD;STA = tHIGH = 0.6 us */ + sda_falling_time, 0, /* 0: DW default, 1: Ideal */ 0); /* No offset */ lcnt = i2c_dw_scl_lcnt(input_clock_khz, - 13, /* tLOW = 1.3 us */ - 3, /* tf = 0.3 us */ + 1300, /* tLOW = 1.3 us */ + scl_falling_time, 0); /* No offset */ if (dev->fs_hcnt && dev->fs_lcnt) { |