Port-arm archive

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

Re: NSLU2 not reading real-time clock on bootup



Izumi Tsutsui wrote:
don%donhayford.com@localhost wrote:

Chris Gilbert wrote:
Donald T Hayford wrote:
I built a kerrnel to add usb audio.  Source was retrieved June 2, 1800
EDT.  The startup messages on the console and an attempt to set the
clock from the command line indicate that the I2C driver isn't talking
to the clock again.

Random stab in the dark, what happens is you roll back:
src/sys/dev/i2c: i2c_bitbang.c

As there were some changes made to it recently:
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/i2c/i2c_bitbang.c

Thanks,
Chris
It boots correctly when I revert back to v1.10 of i2c_bitbang.c.   Thanks.

Isn't it better to fix MD backend rather than breaking another I2C device?
---

Index: nslu2_iic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/nslu2/nslu2_iic.c,v
retrieving revision 1.5
diff -u -r1.5 nslu2_iic.c
--- nslu2_iic.c 28 Apr 2008 20:23:17 -0000      1.5
+++ nslu2_iic.c 6 Jun 2008 14:12:12 -0000
@@ -49,9 +49,7 @@
        struct i2c_controller sc_ic;
        struct i2c_bitbang_ops sc_ibo;
        kmutex_t sc_lock;
-#ifdef DIAGNOSTIC
        uint32_t sc_dirout;
-#endif
 };
static int
@@ -120,42 +118,70 @@
 static void
 slugiic_set_dir(void *arg, uint32_t bits)
 {
-#ifdef DIAGNOSTIC
        struct slugiic_softc *sc = arg;
+       uint32_t reg;
+       int s;
+
+       if (sc->sc_dirout == bits)
+               return;
+
+       s = splhigh();
sc->sc_dirout = bits;
-#endif
+
+       if (sc->sc_dirout) {
+               /* SDA is output; enable SDA output if SDA OUTR is low */
+               reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR);
+               if ((reg & GPIO_I2C_SDA_BIT) == 0) {
+                       reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
+                       reg |= GPIO_I2C_SDA_BIT;
+                       GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg);
+               }
+       } else {
+               /* SDA is input; disable SDA output */
+               reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
+               reg &= ~GPIO_I2C_SDA_BIT;
+               GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg);
+       }
+
+       splx(s);
 }
static void
 slugiic_set_bits(void *arg, uint32_t bits)
 {
-       uint32_t reg;
-       int s;
-
-#ifdef DIAGNOSTIC
        struct slugiic_softc *sc = arg;
-       if (sc->sc_dirout == 0 && (bits & GPIO_I2C_SDA_BIT) == 0) {
-               printf("slugiic_set_bits: SDA low in input mode!\n");
-               bits |= GPIO_I2C_SDA_BIT;
-       }
-#endif
+       uint32_t oer, outr;
+       int s;
s = splhigh(); - reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR);
-       reg &= ~(GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT);
-       GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, reg | bits);
-
        /*
-        * Enable output only if the SDA/SCL lines are to be driven low.
-        * Otherwise switch to input and allow the pullup resistors
-        * to hold them high.
+        * Enable SCL output if the SCL line is to be driven low.
+        * Enable SDA output if the SDA line is to be driven low and
+        * SDA direction is output.
+        * Otherwise switch them to input even if directions are output
+        * so that we can emulate open collector output with the pullup
+        * resistors.
+        * If lines are to be set to high, disable OER first then set OUTR.
+        * If lines are to be set to low, set OUTR first then enable OER.
         */
-       reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
-       reg &= ~(GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT);
-       reg |= bits & (GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT);
-       GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg);
+       oer = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
+       if ((bits & GPIO_I2C_SCL_BIT) != 0)
+               oer &= ~GPIO_I2C_SCL_BIT;
+       if ((bits & GPIO_I2C_SDA_BIT) != 0)
+               oer &= ~GPIO_I2C_SDA_BIT;
+       GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, oer);
+
+       outr = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR);
+       outr &= ~(GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT);
+       GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, outr | bits);
+
+       if ((bits & GPIO_I2C_SCL_BIT) == 0)
+               oer |= GPIO_I2C_SCL_BIT;
+       if ((bits & GPIO_I2C_SDA_BIT) == 0 && sc->sc_dirout)
+               oer |= GPIO_I2C_SDA_BIT;
+       GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, oer);
splx(s);
 }
@@ -165,12 +191,6 @@
 {
        uint32_t reg;
-#ifdef DIAGNOSTIC
-       struct slugiic_softc *sc = arg;
-       if (sc->sc_dirout)
-               printf("slugiic_read_bits: Read in output mode\n");
-#endif
-
        reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPINR);
        return (reg & (GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT));
 }
@@ -230,9 +250,7 @@
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); -#ifdef DIAGNOSTIC
        sc->sc_dirout = 0;
-#endif
/*
         * Defer until ixp425_softc has been initialised

---
Izumi Tsutsui
This patch appears to work correctly.

Thanks - Don


Home | Main Index | Thread Index | Old Index