Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/i2c NXP Layerscape LX2160A has an almost compatible ...



details:   https://anonhg.NetBSD.org/src/rev/af8722bac924
branches:  trunk
changeset: 950334:af8722bac924
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Jan 25 12:08:47 2021 +0000

description:
NXP Layerscape LX2160A has an almost compatible controller, with a few
quirks:
 - IBCR bit 7 is "module disable" instead of "module enable".
 - Status bits in IBSR are W1C.
Add quirk flags for both.

diffstat:

 sys/dev/i2c/motoi2c.c    |  50 ++++++++++++++++++++++++++++++++++-------------
 sys/dev/i2c/motoi2cvar.h |   7 +++++-
 2 files changed, 42 insertions(+), 15 deletions(-)

diffs (163 lines):

diff -r 1d287a0f0a3e -r af8722bac924 sys/dev/i2c/motoi2c.c
--- a/sys/dev/i2c/motoi2c.c     Mon Jan 25 02:11:41 2021 +0000
+++ b/sys/dev/i2c/motoi2c.c     Mon Jan 25 12:08:47 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: motoi2c.c,v 1.9 2021/01/24 18:01:13 jmcneill Exp $ */
+/* $NetBSD: motoi2c.c,v 1.10 2021/01/25 12:08:47 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: motoi2c.c,v 1.9 2021/01/24 18:01:13 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: motoi2c.c,v 1.10 2021/01/25 12:08:47 jmcneill Exp $");
 
 #if defined(__arm__) || defined(__aarch64__)
 #include "opt_fdt.h"
@@ -109,11 +109,23 @@
        iba.iba_tag = &sc->sc_i2c;
        iba.iba_child_devices = sc->sc_child_devices;
 
-       I2C_WRITE(I2CCR, 0);            /* reset before changing anything */
+       if ((sc->sc_flags & MOTOI2C_F_ENABLE_INV) != 0) {
+               sc->sc_enable_mask = 0;
+               sc->sc_disable_mask = CR_MEN;
+       } else {
+               sc->sc_enable_mask = CR_MEN;
+               sc->sc_disable_mask = 0;
+       }
+
+       I2C_WRITE(I2CCR, sc->sc_disable_mask);  /* reset before config */
        I2C_WRITE(I2CDFSRR, i2c->i2c_dfsrr);    /* sampling units */
        I2C_WRITE(I2CFDR, i2c->i2c_fdr);        /* divider 3072 (0x31) */
        I2C_WRITE(I2CADR, i2c->i2c_adr);        /* our slave address is 0x7f */
-       I2C_WRITE(I2CSR, 0);            /* clear status flags */
+       if ((sc->sc_flags & MOTOI2C_F_STATUS_W1C) != 0) {
+               I2C_WRITE(I2CSR, I2C_READ(I2CSR)); /* clear status flags */
+       } else {
+               I2C_WRITE(I2CSR, 0);            /* clear status flags */
+       }
 
 #ifdef FDT
        if (sc->sc_phandle != 0) {
@@ -130,7 +142,7 @@
 {
        struct motoi2c_softc * const sc = v;
 
-       I2C_WRITE(I2CCR, CR_MEN);       /* enable the I2C module */
+       I2C_WRITE(I2CCR, sc->sc_enable_mask);   /* enable the I2C module */
 
        return 0;
 }
@@ -140,7 +152,7 @@
 {
        struct motoi2c_softc * const sc = v;
 
-       I2C_WRITE(I2CCR, 0);            /* reset before changing anything */
+       I2C_WRITE(I2CCR, sc->sc_disable_mask);  /* disable the I2C module */
 }
 
 static int
@@ -161,6 +173,16 @@
        return error;
 }
 
+static void
+motoi2c_clear_status(struct motoi2c_softc *sc, uint8_t sr)
+{
+       if ((sc->sc_flags & MOTOI2C_F_STATUS_W1C) != 0) {
+               I2C_WRITE(I2CSR, sr);
+       } else {
+               I2C_WRITE(I2CSR, 0);
+       }
+}
+
 /* busy waiting for byte data transfer completion */
 static int
 motoi2c_busy_wait(struct motoi2c_softc *sc, uint8_t cr)
@@ -186,7 +208,7 @@
                    __func__, sr, 1000 - timo));
                error = EIO;
        }
-       I2C_WRITE(I2CSR, 0);
+       motoi2c_clear_status(sc, sr);
        return error;
 }
 
@@ -228,13 +250,13 @@
        }
 
        /* reset interrupt and arbitration-lost flags (all others are RO) */
-       I2C_WRITE(I2CSR, 0);
+       motoi2c_clear_status(sc, sr);
        sr = I2C_READ(I2CSR);
 
        /*
         * Generate start condition
         */
-       cr = CR_MEN | CR_MTX | CR_MSTA;
+       cr = sc->sc_enable_mask | CR_MTX | CR_MSTA;
        I2C_WRITE(I2CCR, cr);
 
        DPRINTF(("%s: started: sr=%#x cr=%#x/%#x\n",
@@ -244,9 +266,9 @@
        if (sr & SR_MAL) {
                DPRINTF(("%s: lost bus: sr=%#x cr=%#x/%#x\n",
                    __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));
-               I2C_WRITE(I2CCR, 0);
+               I2C_WRITE(I2CCR, sc->sc_disable_mask);
                DELAY(10);
-               I2C_WRITE(I2CCR, CR_MEN | CR_MTX | CR_MSTA);
+               I2C_WRITE(I2CCR, sc->sc_enable_mask | CR_MTX | CR_MSTA);
                DELAY(10);
                sr = I2C_READ(I2CSR);
                if (sr & SR_MAL) {
@@ -329,14 +351,14 @@
                                cr |= CR_TXAK;
                                I2C_WRITE(I2CCR, cr);
                        } else if (i == datalen - 1 && I2C_OP_STOP_P(op)) {
-                               cr = CR_MEN | CR_TXAK;
+                               cr = sc->sc_enable_mask | CR_TXAK;
                                I2C_WRITE(I2CCR, cr);
                        }
                        *dataptr++ = I2C_READ(I2CDR);
                }
                if (datalen == 0) {
                        if (I2C_OP_STOP_P(op)) {
-                               cr = CR_MEN | CR_TXAK;
+                               cr = sc->sc_enable_mask | CR_TXAK;
                                I2C_WRITE(I2CCR, cr);
                        }
                        (void)I2C_READ(I2CDR);  /* dummy read */
@@ -366,7 +388,7 @@
         * send a STOP.
         */
        if (error || (cr & CR_TXAK) || ((cr & CR_MSTA) && I2C_OP_STOP_P(op))) {
-               cr = CR_MEN;
+               cr = sc->sc_enable_mask;
                I2C_WRITE(I2CCR, cr);
                motoi2c_stop_wait(sc);
                DPRINTF(("%s: stopping: cr=%#x/%#x\n", __func__,
diff -r 1d287a0f0a3e -r af8722bac924 sys/dev/i2c/motoi2cvar.h
--- a/sys/dev/i2c/motoi2cvar.h  Mon Jan 25 02:11:41 2021 +0000
+++ b/sys/dev/i2c/motoi2cvar.h  Mon Jan 25 12:08:47 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: motoi2cvar.h,v 1.7 2021/01/24 18:01:13 jmcneill Exp $ */
+/* $NetBSD: motoi2cvar.h,v 1.8 2021/01/25 12:08:47 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc.
@@ -52,6 +52,11 @@
        motoi2c_iowr_t          sc_iowr;
        int                     sc_phandle;
        prop_array_t            sc_child_devices;
+       int                     sc_flags;
+#define        MOTOI2C_F_ENABLE_INV    __BIT(0)
+#define        MOTOI2C_F_STATUS_W1C    __BIT(1)
+       uint8_t                 sc_enable_mask;
+       uint8_t                 sc_disable_mask;
 };
 
 #define        MOTOI2C_ADR_DEFAULT     (0x7e << 1)



Home | Main Index | Thread Index | Old Index