diff --git a/drivers/i2c/busses/i2c-k1x.c b/drivers/i2c/busses/i2c-k1x.c index d22574b5315c..5a166d452e84 100644 --- a/drivers/i2c/busses/i2c-k1x.c +++ b/drivers/i2c/busses/i2c-k1x.c @@ -98,7 +98,7 @@ static void spacemit_i2c_controller_reset(struct spacemit_i2c_dev *spacemit_i2c) static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *spacemit_i2c) { int clk_cnt = 0; - u32 bus_status; + u32 bus_status, val; /* if bus is locked, reset unit. 0: locked */ bus_status = spacemit_i2c_read_reg(spacemit_i2c, REG_BMR); @@ -119,7 +119,8 @@ static void spacemit_i2c_bus_reset(struct spacemit_i2c_dev *spacemit_i2c) break; /* if still locked, send one clk to slave to request release */ - spacemit_i2c_write_reg(spacemit_i2c, REG_RST_CYC, 0x1); + val = spacemit_i2c_read_reg(spacemit_i2c, REG_RST_CYC); + spacemit_i2c_write_reg(spacemit_i2c, REG_RST_CYC, val | 0x1); spacemit_i2c_write_reg(spacemit_i2c, REG_CR, CR_RSTREQ); usleep_range(20, 30); clk_cnt++; @@ -1337,6 +1338,9 @@ xfer_retry: spacemit_i2c_init_xfer_params(spacemit_i2c); + ret = spacemit_i2c_read_reg(spacemit_i2c, REG_RST_CYC); + spacemit_i2c_write_reg(spacemit_i2c, REG_RST_CYC, I2C_SDA_GLITCH_FIX_BYPASS | ret); + spacemit_i2c_mark_rw_flag(spacemit_i2c); reinit_completion(&spacemit_i2c->complete); diff --git a/drivers/i2c/busses/i2c-k1x.h b/drivers/i2c/busses/i2c-k1x.h index c426c6f3d39f..4b1486e6dfc8 100644 --- a/drivers/i2c/busses/i2c-k1x.h +++ b/drivers/i2c/busses/i2c-k1x.h @@ -185,6 +185,8 @@ enum spacemit_i2c_xfer_phase { #define SPACEMIT_I2C_APB_CLOCK_26M (26000000) #define SPACEMIT_I2C_APB_CLOCK_52M (52000000) +#define I2C_SDA_GLITCH_FIX_BYPASS BIT(7) + /* i2c-spacemit driver's main struct */ struct spacemit_i2c_dev { struct device *dev;