diff options
| author | Andriy Gapon <avg@FreeBSD.org> | 2020-09-07 06:32:03 +0000 |
|---|---|---|
| committer | Andriy Gapon <avg@FreeBSD.org> | 2020-09-07 06:32:03 +0000 |
| commit | 6305020526cee4adcedec1fc64f901a6f0eb6406 (patch) | |
| tree | bd9f928623cf49b54019b179ba6824b128f25177 /sys/dev | |
| parent | e21a4ccfd1fd41dca59e89002f336adf554ad897 (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/iicbus/twsi/a10_twsi.c | 4 | ||||
| -rw-r--r-- | sys/dev/iicbus/twsi/twsi.c | 16 | ||||
| -rw-r--r-- | sys/dev/iicbus/twsi/twsi.h | 1 |
3 files changed, 14 insertions, 7 deletions
diff --git a/sys/dev/iicbus/twsi/a10_twsi.c b/sys/dev/iicbus/twsi/a10_twsi.c index e70e33fbe2290..17f551f27234e 100644 --- a/sys/dev/iicbus/twsi/a10_twsi.c +++ b/sys/dev/iicbus/twsi/a10_twsi.c @@ -122,6 +122,10 @@ a10_twsi_attach(device_t dev) sc->reg_soft_reset = TWI_SRST; sc->need_ack = true; + + if (ofw_bus_is_compatible(dev, "allwinner,sun6i-a31-i2c") || + ofw_bus_is_compatible(dev, "allwinner,sun6i-a83t-i2c")) + sc->iflag_w1c = true; return (twsi_attach(dev)); } diff --git a/sys/dev/iicbus/twsi/twsi.c b/sys/dev/iicbus/twsi/twsi.c index 9d1a17f43103c..a606c2aefd361 100644 --- a/sys/dev/iicbus/twsi/twsi.c +++ b/sys/dev/iicbus/twsi/twsi.c @@ -147,7 +147,11 @@ twsi_clear_iflg(struct twsi_softc *sc) { DELAY(1000); - twsi_control_clear(sc, TWSI_CONTROL_IFLG); + /* There are two ways of clearing IFLAG. */ + if (sc->iflag_w1c) + twsi_control_set(sc, TWSI_CONTROL_IFLG); + else + twsi_control_clear(sc, TWSI_CONTROL_IFLG); DELAY(1000); } @@ -667,13 +671,11 @@ twsi_intr(void *arg) } debugf(sc->dev, "Refresh reg_control\n"); - /* - * Fix silicon bug on > Allwinner A20 by doing a read and writing - * again to the control register + /* + * Newer Allwinner chips clear IFLG after writing 1 to it. */ - status = TWSI_READ(sc, sc->reg_status); - TWSI_WRITE(sc, sc->reg_control, - sc->control_val | TWSI_CONTROL_IFLG); + TWSI_WRITE(sc, sc->reg_control, sc->control_val | + (sc->iflag_w1c ? TWSI_CONTROL_IFLG : 0)); debugf(sc->dev, "Done with interrupts\n\n"); if (transfer_done == 1) { diff --git a/sys/dev/iicbus/twsi/twsi.h b/sys/dev/iicbus/twsi/twsi.h index a0c4958b47de7..631486fb3f0c3 100644 --- a/sys/dev/iicbus/twsi/twsi.h +++ b/sys/dev/iicbus/twsi/twsi.h @@ -66,6 +66,7 @@ struct twsi_softc { int error; uint32_t control_val; bool need_ack; + bool iflag_w1c; bus_size_t reg_data; bus_size_t reg_slave_addr; |
