Steve Woodford wrote:
It is looking less likely to be a hardware problem. I'll try to find some time to fire up a current kernel on an NSLU2 over the next few days to see if I can reproduce the problem.I reverted back to an older version of i2c_bitbang.c and i2c_bitbang.h, and the RTC works fine.Cheers, Steve
Here's the diff:
--- i2c_bitbang.c.hide 2008-04-15 21:51:45.000000000 -0400 +++ i2c_bitbang.c 2006-11-15 20:32:50.000000000 -0500 @@ -1,4 +1,4 @@ -/* $NetBSD: i2c_bitbang.c,v 1.9 2007/12/11 12:09:21 lukem Exp $ */ +/* $NetBSD: i2c_bitbang.c,v 1.6 2006/11/16 01:32:50 christos Exp $ *//** Copyright (c) 2003 Wasabi Systems, Inc. @@ -39,9 +39,6 @@ * Common module for bit-bang'ing an I2C bus. */-#include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i2c_bitbang.c,v 1.9 2007/12/11 12:09:21 lukem Exp $");- #include <sys/param.h>#include <dev/i2c/i2cvar.h>@@ -56,47 +53,17 @@#define OUTPUT ops->ibo_bits[I2C_BIT_OUTPUT] /* SDA is output */ #define INPUT ops->ibo_bits[I2C_BIT_INPUT] /* SDA is input */ -#ifndef SCL_BAIL_COUNT-#define SCL_BAIL_COUNT 1000 -#endif - -static inline int i2c_wait_for_scl(void *, i2c_bitbang_ops_t); - -static inline int -i2c_wait_for_scl(void *v, i2c_bitbang_ops_t ops) -{ - int bail = 0; - - DIR(INPUT); - - while (((READ & SCL) == 0) && (bail < SCL_BAIL_COUNT)) { - - delay(1); - bail++; - } - if (bail == SCL_BAIL_COUNT) { - - i2c_bitbang_send_stop(v, 0, ops); - return EIO; - } - return 0; -} - /*ARGSUSED*/ int i2c_bitbang_send_start(void *v, int flags, i2c_bitbang_ops_t ops) {DIR(OUTPUT);+ SETBITS(SDA | SCL); delay(5); /* bus free time (4.7 uS) */ SETBITS( SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); /* start hold time (4.0 uS) */ - - DIR(OUTPUT); SETBITS( 0); delay(5); /* clock low time (4.7 uS) */@@ -109,6 +76,7 @@{DIR(OUTPUT);+ SETBITS( SCL); delay(4); /* stop setup time (4.0 uS) */ SETBITS(SDA | SCL); @@ -163,40 +131,25 @@ uint8_t val = 0; uint32_t bit;- DIR(OUTPUT);+ DIR(INPUT); SETBITS(SDA );for (i = 0; i < 8; i++) {val <<= 1; - - DIR(OUTPUT); SETBITS(SDA | SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); /* clock high time (4.0 uS) */ - - DIR(INPUT); if (READ & SDA) val |= 1; - - DIR(OUTPUT); SETBITS(SDA ); delay(5); /* clock low time (4.7 uS) */ }bit = (flags & I2C_F_LAST) ? SDA : 0;- DIR(OUTPUT); SETBITS(bit ); delay(1); /* data setup time (250 nS) */ SETBITS(bit | SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); /* clock high time (4.0 uS) */ - - DIR(OUTPUT); SETBITS(bit ); delay(5); /* clock low time (4.7 uS) */@@ -219,36 +172,25 @@uint8_t mask; int error;+ DIR(OUTPUT);+ for (mask = 0x80; mask != 0; mask >>= 1) { bit = (val & mask) ? SDA : 0; - - DIR(OUTPUT); SETBITS(bit ); delay(1); /* data setup time (250 nS) */ SETBITS(bit | SCL); - - if (i2c_wait_for_scl(v, ops)) - return EIO; delay(4); /* clock high time (4.0 uS) */ - - DIR(OUTPUT); SETBITS(bit ); delay(5); /* clock low time (4.7 uS) */ }- DIR(OUTPUT);+ DIR(INPUT); + SETBITS(SDA ); delay(5); SETBITS(SDA | SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); - - DIR(INPUT); error = (READ & SDA) ? EIO : 0; - - DIR(OUTPUT); SETBITS(SDA ); delay(5);
--- i2c_bitbang.c.hide 2008-04-15 21:51:45.000000000 -0400 +++ i2c_bitbang.c 2006-11-15 20:32:50.000000000 -0500 @@ -1,4 +1,4 @@ -/* $NetBSD: i2c_bitbang.c,v 1.9 2007/12/11 12:09:21 lukem Exp $ */ +/* $NetBSD: i2c_bitbang.c,v 1.6 2006/11/16 01:32:50 christos Exp $ */ /* * Copyright (c) 2003 Wasabi Systems, Inc. @@ -39,9 +39,6 @@ * Common module for bit-bang'ing an I2C bus. */ -#include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: i2c_bitbang.c,v 1.9 2007/12/11 12:09:21 lukem Exp $"); - #include <sys/param.h> #include <dev/i2c/i2cvar.h> @@ -56,47 +53,17 @@ #define OUTPUT ops->ibo_bits[I2C_BIT_OUTPUT] /* SDA is output */ #define INPUT ops->ibo_bits[I2C_BIT_INPUT] /* SDA is input */ -#ifndef SCL_BAIL_COUNT -#define SCL_BAIL_COUNT 1000 -#endif - -static inline int i2c_wait_for_scl(void *, i2c_bitbang_ops_t); - -static inline int -i2c_wait_for_scl(void *v, i2c_bitbang_ops_t ops) -{ - int bail = 0; - - DIR(INPUT); - - while (((READ & SCL) == 0) && (bail < SCL_BAIL_COUNT)) { - - delay(1); - bail++; - } - if (bail == SCL_BAIL_COUNT) { - - i2c_bitbang_send_stop(v, 0, ops); - return EIO; - } - return 0; -} - /*ARGSUSED*/ int i2c_bitbang_send_start(void *v, int flags, i2c_bitbang_ops_t ops) { DIR(OUTPUT); + SETBITS(SDA | SCL); delay(5); /* bus free time (4.7 uS) */ SETBITS( SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); /* start hold time (4.0 uS) */ - - DIR(OUTPUT); SETBITS( 0); delay(5); /* clock low time (4.7 uS) */ @@ -109,6 +76,7 @@ { DIR(OUTPUT); + SETBITS( SCL); delay(4); /* stop setup time (4.0 uS) */ SETBITS(SDA | SCL); @@ -163,40 +131,25 @@ uint8_t val = 0; uint32_t bit; - DIR(OUTPUT); + DIR(INPUT); SETBITS(SDA ); for (i = 0; i < 8; i++) { val <<= 1; - - DIR(OUTPUT); SETBITS(SDA | SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); /* clock high time (4.0 uS) */ - - DIR(INPUT); if (READ & SDA) val |= 1; - - DIR(OUTPUT); SETBITS(SDA ); delay(5); /* clock low time (4.7 uS) */ } bit = (flags & I2C_F_LAST) ? SDA : 0; - DIR(OUTPUT); SETBITS(bit ); delay(1); /* data setup time (250 nS) */ SETBITS(bit | SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); /* clock high time (4.0 uS) */ - - DIR(OUTPUT); SETBITS(bit ); delay(5); /* clock low time (4.7 uS) */ @@ -219,36 +172,25 @@ uint8_t mask; int error; + DIR(OUTPUT); + for (mask = 0x80; mask != 0; mask >>= 1) { bit = (val & mask) ? SDA : 0; - - DIR(OUTPUT); SETBITS(bit ); delay(1); /* data setup time (250 nS) */ SETBITS(bit | SCL); - - if (i2c_wait_for_scl(v, ops)) - return EIO; delay(4); /* clock high time (4.0 uS) */ - - DIR(OUTPUT); SETBITS(bit ); delay(5); /* clock low time (4.7 uS) */ } - DIR(OUTPUT); + DIR(INPUT); + SETBITS(SDA ); delay(5); SETBITS(SDA | SCL); - - if (i2c_wait_for_scl(v, ops) != 0) - return EIO; delay(4); - - DIR(INPUT); error = (READ & SDA) ? EIO : 0; - - DIR(OUTPUT); SETBITS(SDA ); delay(5);