The clkhi and clklo ratio was not very precise before that can make the time of START/STOP/HIGH LEVEL out of specification. Therefore, the calculation of these times has been modified in this patch. At the same time, the mode rate definition of i2c is corrected. Signed-off-by: Clark Wang <xiaoning.wang@xxxxxxx> Reviewed-by: Fugang Duan <fugang.duan@xxxxxxx> --- V2 changes: - No change. --- drivers/i2c/busses/i2c-imx-lpi2c.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 77dd6ee5a4a8..d124c4000823 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -73,17 +73,17 @@ #define MCFGR1_IGNACK BIT(9) #define MRDR_RXEMPTY BIT(14) -#define I2C_CLK_RATIO 2 +#define I2C_CLK_RATIO 24 / 59 #define CHUNK_DATA 256 #define I2C_PM_TIMEOUT 1000 /* ms */ enum lpi2c_imx_mode { - STANDARD, /* 100+Kbps */ - FAST, /* 400+Kbps */ - FAST_PLUS, /* 1.0+Mbps */ - HS, /* 3.4+Mbps */ - ULTRA_FAST, /* 5.0+Mbps */ + STANDARD, /* <=100Kbps */ + FAST, /* <=400Kbps */ + FAST_PLUS, /* <=1.0Mbps */ + HS, /* <=3.4Mbps */ + ULTRA_FAST, /* <=5.0Mbps */ }; enum lpi2c_imx_pincfg { @@ -156,13 +156,13 @@ static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx) unsigned int bitrate = lpi2c_imx->bitrate; enum lpi2c_imx_mode mode; - if (bitrate < I2C_MAX_FAST_MODE_FREQ) + if (bitrate <= I2C_MAX_STANDARD_MODE_FREQ) mode = STANDARD; - else if (bitrate < I2C_MAX_FAST_MODE_PLUS_FREQ) + else if (bitrate <= I2C_MAX_FAST_MODE_FREQ) mode = FAST; - else if (bitrate < I2C_MAX_HIGH_SPEED_MODE_FREQ) + else if (bitrate <= I2C_MAX_FAST_MODE_PLUS_FREQ) mode = FAST_PLUS; - else if (bitrate < I2C_MAX_ULTRA_FAST_MODE_FREQ) + else if (bitrate <= I2C_MAX_HIGH_SPEED_MODE_FREQ) mode = HS; else mode = ULTRA_FAST; @@ -209,7 +209,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx) } while (1); } -/* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */ +/* CLKLO = (1 - I2C_CLK_RATIO) * clk_cycle, SETHOLD = CLKHI, DATAVD = CLKHI/2 + CLKHI = I2C_CLK_RATIO * clk_cycle */ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) { u8 prescale, filt, sethold, clkhi, clklo, datavd; @@ -232,8 +233,8 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) for (prescale = 0; prescale <= 7; prescale++) { clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate) - - 3 - (filt >> 1); - clkhi = (clk_cycle + I2C_CLK_RATIO) / (I2C_CLK_RATIO + 1); + - (2 + filt) / (1 << prescale); + clkhi = clk_cycle * I2C_CLK_RATIO; clklo = clk_cycle - clkhi; if (clklo < 64) break; -- 2.25.1