@@ -168,6 +168,7 @@ enum i2c_type_exynos {
168168 I2C_TYPE_EXYNOS5 ,
169169 I2C_TYPE_EXYNOS7 ,
170170 I2C_TYPE_EXYNOSAUTOV9 ,
171+ I2C_TYPE_EXYNOS8895 ,
171172};
172173
173174struct exynos5_i2c {
@@ -240,6 +241,11 @@ static const struct exynos_hsi2c_variant exynosautov9_hsi2c_data = {
240241 .hw = I2C_TYPE_EXYNOSAUTOV9 ,
241242};
242243
244+ static const struct exynos_hsi2c_variant exynos8895_hsi2c_data = {
245+ .fifo_depth = 64 ,
246+ .hw = I2C_TYPE_EXYNOS8895 ,
247+ };
248+
243249static const struct of_device_id exynos5_i2c_match [] = {
244250 {
245251 .compatible = "samsung,exynos5-hsi2c" ,
@@ -256,6 +262,9 @@ static const struct of_device_id exynos5_i2c_match[] = {
256262 }, {
257263 .compatible = "samsung,exynosautov9-hsi2c" ,
258264 .data = & exynosautov9_hsi2c_data
265+ }, {
266+ .compatible = "samsung,exynos8895-hsi2c" ,
267+ .data = & exynos8895_hsi2c_data
259268 }, {},
260269};
261270MODULE_DEVICE_TABLE (of , exynos5_i2c_match );
@@ -331,6 +340,14 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
331340 * clk_cycle := TSCLK_L + TSCLK_H
332341 * temp := (CLK_DIV + 1) * (clk_cycle + 2)
333342 *
343+ * In case of HSI2C controllers in Exynos8895
344+ * FPCLK / FI2C =
345+ * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) +
346+ * 2 * ((FLT_CYCLE + 3) - (FLT_CYCLE + 3) % (CLK_DIV + 1))
347+ *
348+ * clk_cycle := TSCLK_L + TSCLK_H
349+ * temp := (FPCLK / FI2C) - (FLT_CYCLE + 3) * 2
350+ *
334351 * Constraints: 4 <= temp, 0 <= CLK_DIV < 256, 2 <= clk_cycle <= 510
335352 *
336353 * To split SCL clock into low, high periods appropriately, one
@@ -352,11 +369,19 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
352369 *
353370 */
354371 t_ftl_cycle = (readl (i2c -> regs + HSI2C_CONF ) >> 16 ) & 0x7 ;
355- temp = clkin / op_clk - 8 - t_ftl_cycle ;
356- if (i2c -> variant -> hw != I2C_TYPE_EXYNOS7 )
357- temp -= t_ftl_cycle ;
372+ if (i2c -> variant -> hw == I2C_TYPE_EXYNOS8895 )
373+ temp = clkin / op_clk - (t_ftl_cycle + 3 ) * 2 ;
374+ else if (i2c -> variant -> hw == I2C_TYPE_EXYNOS7 )
375+ temp = clkin / op_clk - 8 - t_ftl_cycle ;
376+ else
377+ temp = clkin / op_clk - 8 - (t_ftl_cycle * 2 );
358378 div = temp / 512 ;
359- clk_cycle = temp / (div + 1 ) - 2 ;
379+
380+ if (i2c -> variant -> hw == I2C_TYPE_EXYNOS8895 )
381+ clk_cycle = (temp + ((t_ftl_cycle + 3 ) % (div + 1 )) * 2 ) /
382+ (div + 1 ) - 2 ;
383+ else
384+ clk_cycle = temp / (div + 1 ) - 2 ;
360385 if (temp < 4 || div >= 256 || clk_cycle < 2 ) {
361386 dev_err (i2c -> dev , "%s clock set-up failed\n" ,
362387 hs_timings ? "HS" : "FS" );
@@ -491,6 +516,8 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
491516 switch (i2c -> variant -> hw ) {
492517 case I2C_TYPE_EXYNOSAUTOV9 :
493518 fallthrough ;
519+ case I2C_TYPE_EXYNOS8895 :
520+ fallthrough ;
494521 case I2C_TYPE_EXYNOS7 :
495522 if (int_status & HSI2C_INT_TRANS_DONE ) {
496523 i2c -> trans_done = 1 ;
0 commit comments