summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2011-12-20 02:49:01 +0000
committeradrian <adrian@FreeBSD.org>2011-12-20 02:49:01 +0000
commit943f0fd2d31fd1a7dd68ffe51021b477003ce1be (patch)
tree8cc5375f2f11f31e02cddfae17ee99de4ed9e851
parentf90cdf352e585c30ae3efc2a2606810e8f532bd1 (diff)
downloadFreeBSD-src-943f0fd2d31fd1a7dd68ffe51021b477003ce1be.zip
FreeBSD-src-943f0fd2d31fd1a7dd68ffe51021b477003ce1be.tar.gz
IIC bitbang changes - prepare to make the bit delay configurable; debug print changes.
* Right now the delay is hard coded at 10uS. This is a bit long when doing lots of periodic i2c transactions. So create a 'udelay' parameter and initialise it to 10. This can be tuned later. * Add a newline after a transaction finishes, so the debugging output isn't so horrible.
-rw-r--r--sys/dev/iicbus/iicbb.c73
1 files changed, 42 insertions, 31 deletions
diff --git a/sys/dev/iicbus/iicbb.c b/sys/dev/iicbus/iicbb.c
index 2bc6321..a7eb2a0 100644
--- a/sys/dev/iicbus/iicbb.c
+++ b/sys/dev/iicbus/iicbb.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
struct iicbb_softc {
device_t iicbus;
+ int udelay; /* signal toggle delay in usec */
};
static int iicbb_attach(device_t);
@@ -123,6 +124,7 @@ iicbb_attach(device_t dev)
sc->iicbus = device_add_child(dev, "iicbus", -1);
if (!sc->iicbus)
return (ENXIO);
+ sc->udelay = 10; /* 10 uS default */
bus_generic_attach(dev);
return (0);
@@ -184,20 +186,18 @@ iicbb_print_child(device_t bus, device_t dev)
return (retval);
}
-#define IIC_DELAY 10
-
-#define I2C_SETSDA(dev,val) do { \
+#define I2C_SETSDA(sc,dev,val) do { \
IICBB_SETSDA(device_get_parent(dev), val); \
- DELAY(IIC_DELAY); \
+ DELAY(sc->udelay); \
} while (0)
#define I2C_SETSCL(dev,val) do { \
iicbb_setscl(dev, val, 100); \
} while (0)
-#define I2C_SET(dev,ctrl,data) do { \
+#define I2C_SET(sc,dev,ctrl,data) do { \
I2C_SETSCL(dev, ctrl); \
- I2C_SETSDA(dev, data); \
+ I2C_SETSDA(sc, dev, data); \
} while (0)
#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
@@ -216,34 +216,39 @@ static int i2c_debug = 0;
static void
iicbb_setscl(device_t dev, int val, int timeout)
{
+ struct iicbb_softc *sc = device_get_softc(dev);
int k = 0;
IICBB_SETSCL(device_get_parent(dev), val);
- DELAY(IIC_DELAY);
+ DELAY(sc->udelay);
while (val && !I2C_GETSCL(dev) && k++ < timeout) {
IICBB_SETSCL(device_get_parent(dev), val);
- DELAY(IIC_DELAY);
+ DELAY(sc->udelay);
}
-
+
return;
}
static void
iicbb_one(device_t dev, int timeout)
{
- I2C_SET(dev,0,1);
- I2C_SET(dev,1,1);
- I2C_SET(dev,0,1);
+ struct iicbb_softc *sc = device_get_softc(dev);
+
+ I2C_SET(sc,dev,0,1);
+ I2C_SET(sc,dev,1,1);
+ I2C_SET(sc,dev,0,1);
return;
}
static void
iicbb_zero(device_t dev, int timeout)
{
- I2C_SET(dev,0,0);
- I2C_SET(dev,1,0);
- I2C_SET(dev,0,0);
+ struct iicbb_softc *sc = device_get_softc(dev);
+
+ I2C_SET(sc,dev,0,0);
+ I2C_SET(sc,dev,1,0);
+ I2C_SET(sc,dev,0,0);
return;
}
@@ -264,20 +269,21 @@ iicbb_zero(device_t dev, int timeout)
static int
iicbb_ack(device_t dev, int timeout)
{
+ struct iicbb_softc *sc = device_get_softc(dev);
int noack;
int k = 0;
-
- I2C_SET(dev,0,1);
- I2C_SET(dev,1,1);
+
+ I2C_SET(sc,dev,0,1);
+ I2C_SET(sc,dev,1,1);
do {
noack = I2C_GETSDA(dev);
if (!noack)
break;
- DELAY(10);
- k += 10;
+ DELAY(1);
+ k++;
} while (k < timeout);
- I2C_SET(dev,0,1);
+ I2C_SET(sc,dev,0,1);
I2C_DEBUG(printf("%c ",noack?'-':'+'));
return (noack);
@@ -302,16 +308,17 @@ iicbb_sendbyte(device_t dev, u_char data, int timeout)
static u_char
iicbb_readbyte(device_t dev, int last, int timeout)
{
+ struct iicbb_softc *sc = device_get_softc(dev);
int i;
unsigned char data=0;
-
- I2C_SET(dev,0,1);
+
+ I2C_SET(sc,dev,0,1);
for (i=7; i>=0; i--)
{
- I2C_SET(dev,1,1);
+ I2C_SET(sc,dev,1,1);
if (I2C_GETSDA(dev))
data |= (1<<i);
- I2C_SET(dev,0,1);
+ I2C_SET(sc,dev,0,1);
}
if (last) {
iicbb_one(dev, timeout);
@@ -337,13 +344,14 @@ iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
static int
iicbb_start(device_t dev, u_char slave, int timeout)
{
+ struct iicbb_softc *sc = device_get_softc(dev);
int error;
I2C_DEBUG(printf("<"));
- I2C_SET(dev,1,1);
- I2C_SET(dev,1,0);
- I2C_SET(dev,0,0);
+ I2C_SET(sc,dev,1,1);
+ I2C_SET(sc,dev,1,0);
+ I2C_SET(sc,dev,0,0);
/* send address */
iicbb_sendbyte(dev, slave, timeout);
@@ -364,10 +372,13 @@ error:
static int
iicbb_stop(device_t dev)
{
- I2C_SET(dev,0,0);
- I2C_SET(dev,1,0);
- I2C_SET(dev,1,1);
+ struct iicbb_softc *sc = device_get_softc(dev);
+
+ I2C_SET(sc,dev,0,0);
+ I2C_SET(sc,dev,1,0);
+ I2C_SET(sc,dev,1,1);
I2C_DEBUG(printf(">"));
+ I2C_DEBUG(printf("\n"));
return (0);
}
OpenPOWER on IntegriCloud