Skip to content

Commit 8c906cc

Browse files
Camel Guowsakernel
authored andcommitted
i2c: exynos5: Calculate t_scl_l, t_scl_h according to i2c spec
Previously the duty cycle was divided equally into h_scl_l, t_scl_h. This makes the low period of the SCL clock in Fast Mode is only 1.25us which is way lower than the minimal value (1.3) specified in i2c specification. In order to make sure t_scl_l, t_scl_h always fullfill i2c specification, this commit calculates t_scl_l using this formula: t_scl_l = clk_cycle * ((t_low_min + (scl_clock - t_low_min - t_high_min) / 2) / scl_clock) where: t_low_min is the minimal value of low period of the SCL clock in us; t_high_min is the minimal value of high period of the SCL clock in us; scl_clock is converted from SCL clock frequency into us. Signed-off-by: Camel Guo <[email protected]> Tested-by: Marek Szyprowski <[email protected]> Reviewed-by: Marek Szyprowski <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 80e56b8 commit 8c906cc

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

drivers/i2c/busses/i2c-exynos5.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ static void exynos5_i2c_clr_pend_irq(struct exynos5_i2c *i2c)
270270
* exynos5_i2c_set_timing: updates the registers with appropriate
271271
* timing values calculated
272272
*
273-
* Timing values for operation are calculated against either 100kHz
273+
* Timing values for operation are calculated against 100kHz, 400kHz
274274
* or 1MHz controller operating frequency.
275275
*
276276
* Returns 0 on success, -EINVAL if the cycle length cannot
@@ -333,6 +333,23 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
333333
*
334334
* Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
335335
*
336+
* To split SCL clock into low, high periods appropriately, one
337+
* proportion factor for each I2C mode is used, which is calculated
338+
* using this formula.
339+
* ```
340+
* ((t_low_min + (scl_clock - t_low_min - t_high_min) / 2) / scl_clock)
341+
* ```
342+
* where:
343+
* t_low_min is the minimal value of low period of the SCL clock in us;
344+
* t_high_min is the minimal value of high period of the SCL clock in us;
345+
* scl_clock is converted from SCL clock frequency into us.
346+
*
347+
* Below are the proportion factors for these I2C modes:
348+
* t_low_min, t_high_min, scl_clock, proportion
349+
* Standard Mode: 4.7us, 4.0us, 10us, 0.535
350+
* Fast Mode: 1.3us, 0.6us, 2.5us, 0.64
351+
* Fast-Plus Mode: 0.5us, 0.26us, 1us, 0.62
352+
*
336353
*/
337354
t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
338355
temp = clkin / op_clk - 8 - t_ftl_cycle;
@@ -346,8 +363,19 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
346363
return -EINVAL;
347364
}
348365

349-
t_scl_l = clk_cycle / 2;
350-
t_scl_h = clk_cycle / 2;
366+
/*
367+
* Scale clk_cycle to get t_scl_l using the proption factors for individual I2C modes.
368+
*/
369+
if (op_clk <= I2C_MAX_STANDARD_MODE_FREQ)
370+
t_scl_l = clk_cycle * 535 / 1000;
371+
else if (op_clk <= I2C_MAX_FAST_MODE_FREQ)
372+
t_scl_l = clk_cycle * 64 / 100;
373+
else
374+
t_scl_l = clk_cycle * 62 / 100;
375+
376+
if (t_scl_l > 0xFF)
377+
t_scl_l = 0xFF;
378+
t_scl_h = clk_cycle - t_scl_l;
351379
t_start_su = t_scl_l;
352380
t_start_hd = t_scl_l;
353381
t_stop_su = t_scl_l;

0 commit comments

Comments
 (0)