#define ID_ARBLOST (1 << 3)
#define ID_NACK (1 << 4)
/* persistent flags */
+#define ID_P_REP_AFTER_RD BIT(29)
#define ID_P_NO_RXDMA BIT(30) /* HW forbids RXDMA sometimes */
#define ID_P_PM_BLOCKED BIT(31)
-#define ID_P_MASK GENMASK(31, 30)
+#define ID_P_MASK GENMASK(31, 29)
enum rcar_i2c_type {
I2C_RCAR_GEN1,
rcar_i2c_write(priv, ICMSR, 0);
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
} else {
- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+ if (priv->flags & ID_P_REP_AFTER_RD)
+ priv->flags &= ~ID_P_REP_AFTER_RD;
+ else
+ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
rcar_i2c_write(priv, ICMSR, 0);
}
rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
priv->pos++;
}
- /*
- * If next received data is the _LAST_, go to STOP phase. Might be
- * overwritten by REP START when setting up a new msg. Not elegant
- * but the only stable sequence for REP START I have found so far.
- * If you want to change this code, make sure sending one transfer with
- * four messages (WR-RD-WR-RD) works!
- */
- if (priv->pos + 1 >= msg->len)
- rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
+ /* If next received data is the _LAST_, go to new phase. */
+ if (priv->pos + 1 == msg->len) {
+ if (priv->flags & ID_LAST_MSG) {
+ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
+ } else {
+ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+ priv->flags |= ID_P_REP_AFTER_RD;
+ }
+ }
if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG))
rcar_i2c_next_msg(priv);
struct rcar_i2c_priv *priv = ptr;
u32 msr, val;
- /* Clear START or STOP as soon as we can */
- val = rcar_i2c_read(priv, ICMCR);
- rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA);
+ /* Clear START or STOP immediately, except for REPSTART after read */
+ if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) {
+ val = rcar_i2c_read(priv, ICMCR);
+ rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA);
+ }
msr = rcar_i2c_read(priv, ICMSR);