Port-arm archive

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

NSLU2 I2C patch




Hi,

I believe that the code in nslu2_iic.c is based on the incorrect assumption that setting a bit in the GPIO output enable register configures the corresponding pin as an output.

According to the IXP425 documentation from Intel, setting a bit in GPOER configures the relevant pin as an input.

The bug seems to prevent accessing the real-time clock, at least on my device. Please test the patch that follows.

Thanks,
Piotr

--- usr/src/sys/arch/evbarm/nslu2/nslu2_iic.c.orig      2008-06-23 
19:58:57.000000000 +0200
+++ usr/src/sys/arch/evbarm/nslu2/nslu2_iic.c   2008-06-24 01:19:48.000000000 
+0200
@@ -134,13 +134,18 @@
                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 high; 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);
                }
        } else {
                /* SDA is input; disable SDA output */
                reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
-               reg &= ~GPIO_I2C_SDA_BIT;
+               reg |= GPIO_I2C_SDA_BIT;
                GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg);
        }

@@ -168,9 +173,9 @@
         */
        oer = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER);
        if ((bits & GPIO_I2C_SCL_BIT) != 0)
-               oer &= ~GPIO_I2C_SCL_BIT;
+               oer |= GPIO_I2C_SCL_BIT;
        if ((bits & GPIO_I2C_SDA_BIT) != 0)
-               oer &= ~GPIO_I2C_SDA_BIT;
+               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);
@@ -178,9 +183,9 @@
        GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, outr | bits);

        if ((bits & GPIO_I2C_SCL_BIT) == 0)
-               oer |= GPIO_I2C_SCL_BIT;
+               oer &= ~GPIO_I2C_SCL_BIT;
        if ((bits & GPIO_I2C_SDA_BIT) == 0 && sc->sc_dirout)
-               oer |= GPIO_I2C_SDA_BIT;
+               oer &= ~GPIO_I2C_SDA_BIT;
        GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, oer);

        splx(s);


Home | Main Index | Thread Index | Old Index