u32 i2c_timing_sla;
unsigned int t_start_su, t_start_hd;
unsigned int t_stop_su;
+ unsigned int t_sda_su;
unsigned int t_data_su, t_data_hd;
unsigned int t_scl_l, t_scl_h;
unsigned int t_sr_release;
i2c->hs_clock : i2c->fs_clock;
/*
- * FPCLK / FI2C =
- * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + {(FLT_CYCLE + 3) %
- * (CLK_DIV + 1)} * 2
+ * FPCLK / FI2C = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) +
+ * {(FLT_CYCLE + 3) - (FLT_CYCLE + 3) % (CLK_DIV + 1)} * 2
*/
t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
+
+ /*
+ * utemp0 = (FPCLK / FI2C) - (FLT_CYCLE + 3) * 2
+ */
utemp0 = (clkin / op_clk) - (t_ftl_cycle + 3) * 2;
/* CLK_DIV max is 256 */
for (div = 0; div < 256; div++) {
+ /*
+ * utemp1 = (TSCLK_L + TSCLK_H + 2)
+ */
utemp1 = (utemp0 + ((t_ftl_cycle + 3) % (div + 1)) * 2) / (div + 1);
if ((utemp1 < 512) && (utemp1 > 4)) {
return -EINVAL;
}
}
- t_scl_l = clk_cycle / 2;
- t_scl_h = clk_cycle / 2;
+
+ if (mode == HSI2C_HIGH_SPD)
+ t_scl_h = ((clk_cycle + 10) / 3) - 5;
+ else
+ t_scl_h = clk_cycle / 2;
+
+ t_scl_l = clk_cycle - t_scl_h;
t_start_su = t_scl_l;
t_start_hd = t_scl_l;
t_stop_su = t_scl_l;
+ t_sda_su = t_scl_l;
t_data_su = t_scl_l / 2;
t_data_hd = t_scl_l / 2;
t_sr_release = clk_cycle;
- i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
- i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0;
- i2c_timing_s3 = div << 16 | t_sr_release << 0;
- i2c_timing_sla = t_data_hd << 0;
+ if (mode == HSI2C_HIGH_SPD)
+ i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8 | t_sda_su;
+ else
+ i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
+
+ i2c_timing_s2 = (0xF << 16) | t_data_su << 24 | t_scl_l << 8 | t_scl_h;
+ i2c_timing_s3 = (div << 16) | t_sr_release;
+ i2c_timing_sla = t_data_hd;
dev_dbg(i2c->dev, "tSTART_SU: %X, tSTART_HD: %X, tSTOP_SU: %X\n",
t_start_su, t_start_hd, t_stop_su);