i2c: designware: Calculate SCL timing parameter for High Speed Mode
authorWan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>
Tue, 7 Apr 2020 13:34:39 +0000 (21:34 +0800)
committerWolfram Sang <wsa@the-dreams.de>
Wed, 15 Apr 2020 11:13:39 +0000 (13:13 +0200)
Custom parameters for HCNT/LCNT are not available for OF based system.
Thus, we will use existing SCL timing parameter calculation functions
for High Speed Mode too.

The value for the parameters tSYMBOL and tLOW is taken from DesignWare
DW_apb_i2c Databook v2.01a, section 3.15.4.6. The calculation should
assume higher bus load since it gives slower timing parameter.

Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/busses/i2c-designware-master.c

index 23038d7..b6c17b5 100644 (file)
@@ -129,10 +129,22 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
                        dev->master_cfg |= DW_IC_CON_SPEED_FAST;
                        dev->hs_hcnt = 0;
                        dev->hs_lcnt = 0;
-               } else if (dev->hs_hcnt && dev->hs_lcnt) {
-                       dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
-                               dev->hs_hcnt, dev->hs_lcnt);
+               } else if (!dev->hs_hcnt || !dev->hs_lcnt) {
+                       ic_clk = i2c_dw_clk_rate(dev);
+                       dev->hs_hcnt =
+                               i2c_dw_scl_hcnt(ic_clk,
+                                               160,    /* tHIGH = 160 ns */
+                                               sda_falling_time,
+                                               0,      /* DW default */
+                                               0);     /* No offset */
+                       dev->hs_lcnt =
+                               i2c_dw_scl_lcnt(ic_clk,
+                                               320,    /* tLOW = 320 ns */
+                                               scl_falling_time,
+                                               0);     /* No offset */
                }
+               dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
+                       dev->hs_hcnt, dev->hs_lcnt);
        }
 
        ret = i2c_dw_set_sda_hold(dev);