@@ -41,20 +41,32 @@ static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
41
41
regmap_write (dev -> map , DW_IC_CON , dev -> master_cfg );
42
42
}
43
43
44
- static u16 clock_calc ( struct dw_i2c_dev * dev , bool want_high )
44
+ static u32 linear_interpolate ( u32 x , u32 x1 , u32 x2 , u32 y1 , u32 y2 )
45
45
{
46
- struct i2c_timings * t = & dev -> timings ;
47
- u32 wanted_speed = t -> bus_freq_hz ;
48
- u32 clk_khz = i2c_dw_clk_rate (dev );
49
- u32 extra_ns = want_high ? t -> scl_fall_ns : t -> scl_rise_ns ;
50
- u32 extra_cycles = (u32 )((u64 )clk_khz * extra_ns / 1000000 );
51
- u32 period = ((u64 )clk_khz * 1000 + wanted_speed - 1 ) / wanted_speed ;
52
- u32 cycles = (period + want_high )/2 - extra_cycles ;
46
+ return ((x - x1 ) * y2 + (x2 - x ) * y1 ) / (x2 - x1 );
47
+ }
53
48
54
- if (cycles > 0xffff )
55
- cycles = 0xffff ;
49
+ static u16 u16_clamp (u32 v )
50
+ {
51
+ return (u16 )min (v , 0xffff );
52
+ }
56
53
57
- return (u16 )cycles ;
54
+ static void clock_calc (struct dw_i2c_dev * dev , u32 * hcnt , u32 * lcnt )
55
+ {
56
+ struct i2c_timings * t = & dev -> timings ;
57
+ u32 wanted_khz = (dev -> wanted_bus_speed ?: t -> bus_freq_hz )/1000 ;
58
+ u32 clk_khz = i2c_dw_clk_rate (dev );
59
+ u32 min_high_ns = (wanted_khz <= 100 ) ? 4000 :
60
+ (wanted_khz <= 400 ) ?
61
+ linear_interpolate (wanted_khz , 100 , 400 , 4000 , 600 ) :
62
+ linear_interpolate (wanted_khz , 400 , 1000 , 600 , 260 );
63
+ u32 high_cycles = (u32 )(((u64 )clk_khz * min_high_ns + 999999 ) / 1000000 ) + 1 ;
64
+ u32 extra_high_cycles = (u32 )((u64 )clk_khz * t -> scl_fall_ns / 1000000 );
65
+ u32 extra_low_cycles = (u32 )((u64 )clk_khz * t -> scl_rise_ns / 1000000 );
66
+ u32 period = ((u64 )clk_khz + wanted_khz - 1 ) / wanted_khz ;
67
+
68
+ * hcnt = u16_clamp (high_cycles - extra_high_cycles );
69
+ * lcnt = u16_clamp (period - high_cycles - extra_low_cycles );
58
70
}
59
71
60
72
static int i2c_dw_set_timings_master (struct dw_i2c_dev * dev )
@@ -80,8 +92,7 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
80
92
sda_falling_time = t -> sda_fall_ns ?: 300 ; /* ns */
81
93
scl_falling_time = t -> scl_fall_ns ?: 300 ; /* ns */
82
94
83
- hcnt = clock_calc (dev , true);
84
- lcnt = clock_calc (dev , false);
95
+ clock_calc (dev , & hcnt , & lcnt );
85
96
86
97
/* Calculate SCL timing parameters for standard mode if not set */
87
98
if (!dev -> ss_hcnt || !dev -> ss_lcnt ) {
0 commit comments