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);