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
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
Home |
Main Index |
Thread Index |
Old Index