@@ -38,13 +38,30 @@ static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
3838 regmap_write (dev -> map , DW_IC_CON , dev -> master_cfg );
3939}
4040
41+ static u16 clock_calc (struct dw_i2c_dev * dev , bool want_high )
42+ {
43+ struct i2c_timings * t = & dev -> timings ;
44+ u32 wanted_speed = t -> bus_freq_hz ;
45+ u32 clk_khz = i2c_dw_clk_rate (dev );
46+ u32 extra_ns = want_high ? t -> scl_fall_ns : t -> scl_rise_ns ;
47+ u32 extra_cycles = (u32 )((u64 )clk_khz * extra_ns / 1000000 );
48+ u32 period = ((u64 )clk_khz * 1000 + wanted_speed - 1 ) / wanted_speed ;
49+ u32 cycles = (period + want_high )/2 - extra_cycles ;
50+
51+ if (cycles > 0xffff )
52+ cycles = 0xffff ;
53+
54+ return (u16 )cycles ;
55+ }
56+
4157static int i2c_dw_set_timings_master (struct dw_i2c_dev * dev )
4258{
4359 unsigned int comp_param1 ;
4460 u32 sda_falling_time , scl_falling_time ;
4561 struct i2c_timings * t = & dev -> timings ;
4662 const char * fp_str = "" ;
4763 u32 ic_clk ;
64+ u32 hcnt , lcnt ;
4865 int ret ;
4966
5067 ret = i2c_dw_acquire_lock (dev );
@@ -60,6 +77,9 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
6077 sda_falling_time = t -> sda_fall_ns ?: 300 ; /* ns */
6178 scl_falling_time = t -> scl_fall_ns ?: 300 ; /* ns */
6279
80+ hcnt = clock_calc (dev , true);
81+ lcnt = clock_calc (dev , false);
82+
6383 /* Calculate SCL timing parameters for standard mode if not set */
6484 if (!dev -> ss_hcnt || !dev -> ss_lcnt ) {
6585 ic_clk = i2c_dw_clk_rate (dev );
@@ -75,6 +95,8 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
7595 scl_falling_time ,
7696 0 ); /* No offset */
7797 }
98+ dev -> ss_hcnt = hcnt ;
99+ dev -> ss_lcnt = lcnt ;
78100 dev_dbg (dev -> dev , "Standard Mode HCNT:LCNT = %d:%d\n" ,
79101 dev -> ss_hcnt , dev -> ss_lcnt );
80102
@@ -125,6 +147,8 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
125147 scl_falling_time ,
126148 0 ); /* No offset */
127149 }
150+ dev -> fs_hcnt = hcnt ;
151+ dev -> fs_lcnt = lcnt ;
128152 dev_dbg (dev -> dev , "Fast Mode%s HCNT:LCNT = %d:%d\n" ,
129153 fp_str , dev -> fs_hcnt , dev -> fs_lcnt );
130154
@@ -153,6 +177,8 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
153177 scl_falling_time ,
154178 0 ); /* No offset */
155179 }
180+ dev -> hs_hcnt = hcnt ;
181+ dev -> hs_lcnt = lcnt ;
156182 dev_dbg (dev -> dev , "High Speed Mode HCNT:LCNT = %d:%d\n" ,
157183 dev -> hs_hcnt , dev -> hs_lcnt );
158184 }
0 commit comments