Skip to content
Snippets Groups Projects
Commit 6bdc3f38 authored by Clark Wang's avatar Clark Wang Committed by Dong Aisheng
Browse files

MLK-24495 i2c: lpi2c: fix i2c timing issue


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.

Reviewed-by: default avatarFugang Duan <fugang.duan@nxp.com>
Signed-off-by: default avatarClark Wang <xiaoning.wang@nxp.com>
parent e12ad0b8
No related branches found
No related tags found
No related merge requests found
...@@ -73,17 +73,17 @@ ...@@ -73,17 +73,17 @@
#define MCFGR1_IGNACK BIT(9) #define MCFGR1_IGNACK BIT(9)
#define MRDR_RXEMPTY BIT(14) #define MRDR_RXEMPTY BIT(14)
#define I2C_CLK_RATIO 2 #define I2C_CLK_RATIO 24 / 59
#define CHUNK_DATA 256 #define CHUNK_DATA 256
#define I2C_PM_TIMEOUT 1000 /* ms */ #define I2C_PM_TIMEOUT 1000 /* ms */
enum lpi2c_imx_mode { enum lpi2c_imx_mode {
STANDARD, /* 100+Kbps */ STANDARD, /* <=100Kbps */
FAST, /* 400+Kbps */ FAST, /* <=400Kbps */
FAST_PLUS, /* 1.0+Mbps */ FAST_PLUS, /* <=1.0Mbps */
HS, /* 3.4+Mbps */ HS, /* <=3.4Mbps */
ULTRA_FAST, /* 5.0+Mbps */ ULTRA_FAST, /* <=5.0Mbps */
}; };
enum lpi2c_imx_pincfg { enum lpi2c_imx_pincfg {
...@@ -156,13 +156,13 @@ static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx) ...@@ -156,13 +156,13 @@ static void lpi2c_imx_set_mode(struct lpi2c_imx_struct *lpi2c_imx)
unsigned int bitrate = lpi2c_imx->bitrate; unsigned int bitrate = lpi2c_imx->bitrate;
enum lpi2c_imx_mode mode; enum lpi2c_imx_mode mode;
if (bitrate < I2C_MAX_FAST_MODE_FREQ) if (bitrate <= I2C_MAX_STANDARD_MODE_FREQ)
mode = STANDARD; mode = STANDARD;
else if (bitrate < I2C_MAX_FAST_MODE_PLUS_FREQ) else if (bitrate <= I2C_MAX_FAST_MODE_FREQ)
mode = FAST; mode = FAST;
else if (bitrate < I2C_MAX_HIGH_SPEED_MODE_FREQ) else if (bitrate <= I2C_MAX_FAST_MODE_PLUS_FREQ)
mode = FAST_PLUS; mode = FAST_PLUS;
else if (bitrate < I2C_MAX_ULTRA_FAST_MODE_FREQ) else if (bitrate <= I2C_MAX_HIGH_SPEED_MODE_FREQ)
mode = HS; mode = HS;
else else
mode = ULTRA_FAST; mode = ULTRA_FAST;
...@@ -209,7 +209,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx) ...@@ -209,7 +209,8 @@ static void lpi2c_imx_stop(struct lpi2c_imx_struct *lpi2c_imx)
} while (1); } 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) static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
{ {
u8 prescale, filt, sethold, clkhi, clklo, datavd; u8 prescale, filt, sethold, clkhi, clklo, datavd;
...@@ -232,8 +233,8 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) ...@@ -232,8 +233,8 @@ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx)
for (prescale = 0; prescale <= 7; prescale++) { for (prescale = 0; prescale <= 7; prescale++) {
clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate) clk_cycle = clk_rate / ((1 << prescale) * lpi2c_imx->bitrate)
- 3 - (filt >> 1); - (2 + filt) / (1 << prescale);
clkhi = (clk_cycle + I2C_CLK_RATIO) / (I2C_CLK_RATIO + 1); clkhi = clk_cycle * I2C_CLK_RATIO;
clklo = clk_cycle - clkhi; clklo = clk_cycle - clkhi;
if (clklo < 64) if (clklo < 64)
break; break;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment