aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2020-09-07 06:32:03 +0000
committerAndriy Gapon <avg@FreeBSD.org>2020-09-07 06:32:03 +0000
commit6305020526cee4adcedec1fc64f901a6f0eb6406 (patch)
treebd9f928623cf49b54019b179ba6824b128f25177 /sys/dev
parente21a4ccfd1fd41dca59e89002f336adf554ad897 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/iicbus/twsi/a10_twsi.c4
-rw-r--r--sys/dev/iicbus/twsi/twsi.c16
-rw-r--r--sys/dev/iicbus/twsi/twsi.h1
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;