From 1ecac07abaca1a4084d0259d4a15b55188852a2e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 May 2007 23:26:28 +0200 Subject: i2c-algo-bit: Always send a stop condition before leaving The i2c-algo-bit driver doesn't behave well on read errors: it'll bail out without even sending a stop condition on the bus, so the bus will be stuck. So make sure that we always send a stop condition on the bus before we leave. The best way to make sure is to always send it at the end of function bit_xfer. Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/i2c/algos/i2c-algo-bit.c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 95aa5395a5b..28b7e25ca79 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -312,12 +312,10 @@ static int try_address(struct i2c_adapter *i2c_adap, int i,ret = -1; for (i=0;i<=retries;i++) { ret = i2c_outb(i2c_adap,addr); - if (ret==1) - break; /* success! */ + if (ret == 1 || i == retries) + break; i2c_stop(adap); udelay(5/*adap->udelay*/); - if (i==retries) /* no success */ - break; i2c_start(adap); udelay(adap->udelay); } @@ -331,7 +329,6 @@ static int try_address(struct i2c_adapter *i2c_adap, static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { - struct i2c_algo_bit_data *adap = i2c_adap->algo_data; char c; const char *temp = msg->buf; int count = msg->len; @@ -349,7 +346,6 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) wrcount++; } else { /* arbitration or no acknowledge */ dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n"); - i2c_stop(adap); return (retval<0)? retval : -EFAULT; /* got a better one ?? */ } @@ -480,27 +476,34 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, if ((ret != 0) && !nak_ok) { DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n" ,msgs[i].addr,i)); - return (ret<0) ? ret : -EREMOTEIO; + goto bailout; } } if (pmsg->flags & I2C_M_RD ) { /* read bytes into buffer*/ ret = readbytes(i2c_adap, pmsg); DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); - if (ret < pmsg->len ) { - return (ret<0)? ret : -EREMOTEIO; + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EREMOTEIO; + goto bailout; } } else { /* write bytes from buffer */ ret = sendbytes(i2c_adap, pmsg); DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); - if (ret < pmsg->len ) { - return (ret<0) ? ret : -EREMOTEIO; + if (ret < pmsg->len) { + if (ret >= 0) + ret = -EREMOTEIO; + goto bailout; } } } + ret = i; + +bailout: i2c_stop(adap); - return num; + return ret; } static u32 bit_func(struct i2c_adapter *adap) -- cgit From 3c4bb241d34ee3d9ab87aad265734885385f179b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 May 2007 23:26:29 +0200 Subject: i2c-algo-bit: Emulate SMBus block read Now that i2c-core lets the i2c bus drivers emulate the SMBus block read and SMBus block process call transaction types, let's implement that in the popular i2c bit-banging driver. This will also act as a reference implementation for other bus drivers which want to do the same. Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/i2c/algos/i2c-algo-bit.c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 28b7e25ca79..fcef6ff3d28 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -391,6 +391,21 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }; scllo(adap); sdahi(adap); + + /* Some SMBus transactions require that we receive the + transaction length as the first read byte. */ + if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) { + if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { + printk(KERN_ERR "i2c-algo-bit: readbytes: " + "invalid block length (%d)\n", inval); + return -EREMOTEIO; + } + /* The original count value accounts for the extra + bytes, that is, either 1 for a regular transaction, + or 2 for a PEC transaction. */ + count += inval; + msg->len += inval; + } } return rdcount; } @@ -509,6 +524,8 @@ bailout: static u32 bit_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_SMBUS_READ_BLOCK_DATA | + I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; } -- cgit From 0f3b48385213355a2d4408bec1b481ffcf0e8638 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 May 2007 23:26:31 +0200 Subject: i2c-algo-bit: Add i2c_bit_add_numbered_bus Add i2c_bit_add_numbered_bus(), which is equivalent to i2c_bit_add_bus except that it calls i2c_add_numbered_adapter() at the end instead of i2c_add_adapter(). Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers/i2c/algos/i2c-algo-bit.c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index fcef6ff3d28..fc16f9d268a 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -540,7 +540,7 @@ static const struct i2c_algorithm i2c_bit_algo = { /* * registering functions to load algorithms at runtime */ -int i2c_bit_add_bus(struct i2c_adapter *adap) +static int i2c_bit_prepare_bus(struct i2c_adapter *adap) { struct i2c_algo_bit_data *bit_adap = adap->algo_data; @@ -558,10 +558,33 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ + return 0; +} + +int i2c_bit_add_bus(struct i2c_adapter *adap) +{ + int err; + + err = i2c_bit_prepare_bus(adap); + if (err) + return err; + return i2c_add_adapter(adap); } EXPORT_SYMBOL(i2c_bit_add_bus); +int i2c_bit_add_numbered_bus(struct i2c_adapter *adap) +{ + int err; + + err = i2c_bit_prepare_bus(adap); + if (err) + return err; + + return i2c_add_numbered_adapter(adap); +} +EXPORT_SYMBOL(i2c_bit_add_numbered_bus); + MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); MODULE_LICENSE("GPL"); -- cgit From 424ed67c7dae37e8115e1bebc3261e86a624dff2 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 May 2007 23:26:33 +0200 Subject: i2c-algo-bit: Implement a 50/50 SCL duty cycle The original i2c-algo-bit implementation uses a 33/66 SCL duty cycle when bits are being written on the bus. While the I2C specification doesn't forbid it, this prevents us from driving the I2C bus to its max speed, limiting us to 66 kbps max on standard I2C busses. Implementing a 50/50 duty cycle instead lets us max out the bandwidth up to the theoretical max of 100 kbps on standard I2C busses. This is particularly important when large amounts of data need to be transfered over the bus, as is the case with some TV adapters when the firmware is being uploaded. In fact this change even allows, at least in theory, fast-mode I2C support at 125, 166 and 250 kbps. There's no way to reach the theoretical max of 400 kbps with this implementation. But I don't think we want to put efforts in that direction anyway: software-driven I2C is very CPU-intensive and bad for latency. Other timing changes: * Don't set SDA high explicitly on error, we're going to issue a stop condition before we leave anyway. * If an error occurs when sending the slave address, yield the CPU before retrying, and remove the additional delay after the new start condition. Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 42 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'drivers/i2c/algos/i2c-algo-bit.c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index fc16f9d268a..d9d0ec49e60 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -57,19 +57,19 @@ static int bit_test; /* see if the line-setting functions work */ static inline void sdalo(struct i2c_algo_bit_data *adap) { setsda(adap,0); - udelay(adap->udelay); + udelay((adap->udelay + 1) / 2); } static inline void sdahi(struct i2c_algo_bit_data *adap) { setsda(adap,1); - udelay(adap->udelay); + udelay((adap->udelay + 1) / 2); } static inline void scllo(struct i2c_algo_bit_data *adap) { setscl(adap,0); - udelay(adap->udelay); + udelay(adap->udelay / 2); } /* @@ -111,18 +111,19 @@ static void i2c_start(struct i2c_algo_bit_data *adap) { /* assert: scl, sda are high */ DEBPROTO(printk("S ")); - sdalo(adap); + setsda(adap, 0); + udelay(adap->udelay); scllo(adap); } static void i2c_repstart(struct i2c_algo_bit_data *adap) { - /* scl, sda may not be high */ + /* assert: scl is low */ DEBPROTO(printk(" Sr ")); - setsda(adap,1); + sdahi(adap); sclhi(adap); - - sdalo(adap); + setsda(adap, 0); + udelay(adap->udelay); scllo(adap); } @@ -133,7 +134,8 @@ static void i2c_stop(struct i2c_algo_bit_data *adap) /* assert: scl is low */ sdalo(adap); sclhi(adap); - sdahi(adap); + setsda(adap, 1); + udelay(adap->udelay); } @@ -156,18 +158,16 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) for ( i=7 ; i>=0 ; i-- ) { sb = c & ( 1 << i ); setsda(adap,sb); - udelay(adap->udelay); + udelay((adap->udelay + 1) / 2); DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); if (sclhi(adap)<0) { /* timed out */ - sdahi(adap); /* we don't want to block the net */ DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i)); return -ETIMEDOUT; }; /* do arbitration here: * if ( sb && ! getsda(adap) ) -> ouch! Get out of here. */ - setscl(adap, 0 ); - udelay(adap->udelay); + scllo(adap); } sdahi(adap); if (sclhi(adap)<0){ /* timeout */ @@ -204,7 +204,8 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) indata *= 2; if ( getsda(adap) ) indata |= 0x01; - scllo(adap); + setscl(adap, 0); + udelay(i == 7 ? adap->udelay / 2 : adap->udelay); } /* assert: scl is low */ DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff)); @@ -315,9 +316,9 @@ static int try_address(struct i2c_adapter *i2c_adap, if (ret == 1 || i == retries) break; i2c_stop(adap); - udelay(5/*adap->udelay*/); - i2c_start(adap); udelay(adap->udelay); + yield(); + i2c_start(adap); } DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n", @@ -377,20 +378,21 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) if (msg->flags & I2C_M_NO_RD_ACK) continue; + /* assert: sda is high */ if ( count > 0 ) { /* send ack */ - sdalo(adap); + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); DEBPROTO(printk(" Am ")); } else { - sdahi(adap); /* neg. ack on last byte */ + /* neg. ack on last byte */ + udelay((adap->udelay + 1) / 2); DEBPROTO(printk(" NAm ")); } if (sclhi(adap)<0) { /* timeout */ - sdahi(adap); printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n"); return -ETIMEDOUT; }; scllo(adap); - sdahi(adap); /* Some SMBus transactions require that we receive the transaction length as the first read byte. */ -- cgit From 494dbb64dc5b369cc28542f4c4d634e57b0d7f18 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 1 May 2007 23:26:33 +0200 Subject: i2c-algo-bit: Improve debugging Improve the debugging features of the i2c-algo-bit driver: * Make it possible to compile the driver without debugging support at all, making it much smaller. * Use dev_dbg() for debugging messages where possible, and dev_err() for error messages. * Remove redundant debugging messages. These changes allowed for minor code cleanups, which are included as well. Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 185 ++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 90 deletions(-) (limited to 'drivers/i2c/algos/i2c-algo-bit.c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index d9d0ec49e60..8a5f5825bb7 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -33,19 +33,30 @@ /* ----- global defines ----------------------------------------------- */ -#define DEB(x) if (i2c_debug>=1) x; -#define DEB2(x) if (i2c_debug>=2) x; -#define DEBSTAT(x) if (i2c_debug>=3) x; /* print several statistical values*/ -#define DEBPROTO(x) if (i2c_debug>=9) { x; } - /* debug the protocol by showing transferred bits */ +#ifdef DEBUG +#define bit_dbg(level, dev, format, args...) \ + do { \ + if (i2c_debug >= level) \ + dev_dbg(dev, format, ##args); \ + } while (0) +#else +#define bit_dbg(level, dev, format, args...) \ + do {} while (0) +#endif /* DEBUG */ /* ----- global variables --------------------------------------------- */ -/* module parameters: - */ -static int i2c_debug; static int bit_test; /* see if the line-setting functions work */ +module_param(bit_test, bool, 0); +MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); + +#ifdef DEBUG +static int i2c_debug = 1; +module_param(i2c_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose"); +#endif /* --- setting states on the bus with the right timing: --------------- */ @@ -98,7 +109,11 @@ static int sclhi(struct i2c_algo_bit_data *adap) } cond_resched(); } - DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); +#ifdef DEBUG + if (jiffies != start && i2c_debug >= 3) + pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go " + "high\n", jiffies - start); +#endif done: udelay(adap->udelay); @@ -110,7 +125,6 @@ done: static void i2c_start(struct i2c_algo_bit_data *adap) { /* assert: scl, sda are high */ - DEBPROTO(printk("S ")); setsda(adap, 0); udelay(adap->udelay); scllo(adap); @@ -119,7 +133,6 @@ static void i2c_start(struct i2c_algo_bit_data *adap) static void i2c_repstart(struct i2c_algo_bit_data *adap) { /* assert: scl is low */ - DEBPROTO(printk(" Sr ")); sdahi(adap); sclhi(adap); setsda(adap, 0); @@ -130,7 +143,6 @@ static void i2c_repstart(struct i2c_algo_bit_data *adap) static void i2c_stop(struct i2c_algo_bit_data *adap) { - DEBPROTO(printk("P\n")); /* assert: scl is low */ sdalo(adap); sclhi(adap); @@ -147,7 +159,7 @@ static void i2c_stop(struct i2c_algo_bit_data *adap) * 0 if the device did not ack * -ETIMEDOUT if an error occurred (while raising the scl line) */ -static int i2c_outb(struct i2c_adapter *i2c_adap, char c) +static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) { int i; int sb; @@ -156,12 +168,12 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) /* assert: scl is low */ for ( i=7 ; i>=0 ; i-- ) { - sb = c & ( 1 << i ); + sb = (c >> i) & 1; setsda(adap,sb); udelay((adap->udelay + 1) / 2); - DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); if (sclhi(adap)<0) { /* timed out */ - DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i)); + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at bit #%d\n", (int)c, i); return -ETIMEDOUT; }; /* do arbitration here: @@ -171,17 +183,17 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) } sdahi(adap); if (sclhi(adap)<0){ /* timeout */ - DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff)); - return -ETIMEDOUT; + bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " + "timeout at ack\n", (int)c); + return -ETIMEDOUT; }; /* read ack: SDA should be pulled down by slave */ - ack=getsda(adap); /* ack: sda is pulled low ->success. */ - DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack)); + ack = !getsda(adap); /* ack: sda is pulled low -> success */ + bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, + ack ? "A" : "NA"); - DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) ); - DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") ); scllo(adap); - return 0==ack; /* return 1 if device acked */ + return ack; /* assert: scl is low (sda undef) */ } @@ -198,7 +210,8 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) sdahi(adap); for (i=0;i<8;i++) { if (sclhi(adap)<0) { /* timeout */ - DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i)); + bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " + "#%d\n", 7 - i); return -ETIMEDOUT; }; indata *= 2; @@ -208,10 +221,7 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) udelay(i == 7 ? adap->udelay / 2 : adap->udelay); } /* assert: scl is low */ - DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff)); - - DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff)); - return (int) (indata & 0xff); + return indata; } /* @@ -222,73 +232,67 @@ static int test_bus(struct i2c_algo_bit_data *adap, char* name) { int scl,sda; if (adap->getscl==NULL) - printk(KERN_INFO "i2c-algo-bit.o: Testing SDA only, " - "SCL is not readable.\n"); + pr_info("%s: Testing SDA only, SCL is not readable\n", name); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); - printk(KERN_DEBUG "i2c-algo-bit.o: (0) scl=%d, sda=%d\n",scl,sda); if (!scl || !sda ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name); + printk(KERN_WARNING "%s: bus seems to be busy\n", name); goto bailout; } sdalo(adap); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); - printk(KERN_DEBUG "i2c-algo-bit.o: (1) scl=%d, sda=%d\n",scl,sda); if ( 0 != sda ) { - printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck high!\n"); + printk(KERN_WARNING "%s: SDA stuck high!\n", name); goto bailout; } if ( 0 == scl ) { - printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " - "while pulling SDA low!\n"); + printk(KERN_WARNING "%s: SCL unexpected low " + "while pulling SDA low!\n", name); goto bailout; } sdahi(adap); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); - printk(KERN_DEBUG "i2c-algo-bit.o: (2) scl=%d, sda=%d\n",scl,sda); if ( 0 == sda ) { - printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck low!\n"); + printk(KERN_WARNING "%s: SDA stuck low!\n", name); goto bailout; } if ( 0 == scl ) { - printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " - "while pulling SDA high!\n"); + printk(KERN_WARNING "%s: SCL unexpected low " + "while pulling SDA high!\n", name); goto bailout; } scllo(adap); sda=getsda(adap); scl=(adap->getscl==NULL?0:getscl(adap)); - printk(KERN_DEBUG "i2c-algo-bit.o: (3) scl=%d, sda=%d\n",scl,sda); if ( 0 != scl ) { - printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck high!\n"); + printk(KERN_WARNING "%s: SCL stuck high!\n", name); goto bailout; } if ( 0 == sda ) { - printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " - "while pulling SCL low!\n"); + printk(KERN_WARNING "%s: SDA unexpected low " + "while pulling SCL low!\n", name); goto bailout; } sclhi(adap); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); - printk(KERN_DEBUG "i2c-algo-bit.o: (4) scl=%d, sda=%d\n",scl,sda); if ( 0 == scl ) { - printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck low!\n"); + printk(KERN_WARNING "%s: SCL stuck low!\n", name); goto bailout; } if ( 0 == sda ) { - printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " - "while pulling SCL high!\n"); + printk(KERN_WARNING "%s: SDA unexpected low " + "while pulling SCL high!\n", name); goto bailout; } - printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name); + pr_info("%s: Test OK\n", name); return 0; bailout: sdahi(adap); @@ -315,32 +319,31 @@ static int try_address(struct i2c_adapter *i2c_adap, ret = i2c_outb(i2c_adap,addr); if (ret == 1 || i == retries) break; + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); i2c_stop(adap); udelay(adap->udelay); yield(); + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); i2c_start(adap); } - DEB2(if (i) - printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n", - i+1, addr & 1 ? "read" : "write", addr>>1, - ret==1 ? "success" : ret==0 ? "no ack" : "failed, timeout?" ) - ); + if (i && ret) + bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " + "0x%02x: %s\n", i + 1, + addr & 1 ? "read from" : "write to", addr >> 1, + ret == 1 ? "success" : "failed, timeout?"); return ret; } static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { - char c; - const char *temp = msg->buf; + const unsigned char *temp = msg->buf; int count = msg->len; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; int retval; int wrcount=0; while (count > 0) { - c = *temp; - DEB2(dev_dbg(&i2c_adap->dev, "sendbytes: writing %2.2X\n", c&0xff)); - retval = i2c_outb(i2c_adap,c); + retval = i2c_outb(i2c_adap, *temp); if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */ count--; temp++; @@ -359,7 +362,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) int inval; int rdcount=0; /* counts bytes read */ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - char *temp = msg->buf; + unsigned char *temp = msg->buf; int count = msg->len; while (count > 0) { @@ -368,28 +371,26 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) *temp = inval; rdcount++; } else { /* read timed out */ - printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n"); break; } temp++; count--; - if (msg->flags & I2C_M_NO_RD_ACK) + if (msg->flags & I2C_M_NO_RD_ACK) { + bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n", + inval); continue; + } /* assert: sda is high */ - if ( count > 0 ) { /* send ack */ + if (count) /* send ack */ setsda(adap, 0); - udelay((adap->udelay + 1) / 2); - DEBPROTO(printk(" Am ")); - } else { - /* neg. ack on last byte */ - udelay((adap->udelay + 1) / 2); - DEBPROTO(printk(" NAm ")); - } + udelay((adap->udelay + 1) / 2); + bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval, + count ? "A" : "NA"); if (sclhi(adap)<0) { /* timeout */ - printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n"); + dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n"); return -ETIMEDOUT; }; scllo(adap); @@ -398,8 +399,8 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) transaction length as the first read byte. */ if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) { if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { - printk(KERN_ERR "i2c-algo-bit: readbytes: " - "invalid block length (%d)\n", inval); + dev_err(&i2c_adap->dev, "readbytes: invalid " + "block length (%d)\n", inval); return -EREMOTEIO; } /* The original count value accounts for the extra @@ -434,27 +435,31 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) if ( (flags & I2C_M_TEN) ) { /* a ten bit address */ addr = 0xf0 | (( msg->addr >> 7) & 0x03); - DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); + bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); if ((ret != 1) && !nak_ok) { - printk(KERN_ERR "died at extended address code.\n"); + dev_err(&i2c_adap->dev, + "died at extended address code\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ ret = i2c_outb(i2c_adap,msg->addr & 0x7f); if ((ret != 1) && !nak_ok) { /* the chip did not ack / xmission error occurred */ - printk(KERN_ERR "died at 2nd address code.\n"); + dev_err(&i2c_adap->dev, "died at 2nd address code\n"); return -EREMOTEIO; } if ( flags & I2C_M_RD ) { + bit_dbg(3, &i2c_adap->dev, "emitting repeated " + "start condition\n"); i2c_repstart(adap); /* okay, now switch into reading mode */ addr |= 0x01; ret = try_address(i2c_adap, addr, retries); if ((ret!=1) && !nak_ok) { - printk(KERN_ERR "died at extended address code.\n"); + dev_err(&i2c_adap->dev, + "died at repeated address code\n"); return -EREMOTEIO; } } @@ -481,25 +486,31 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, int i,ret; unsigned short nak_ok; + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); i2c_start(adap); for (i=0;iflags & I2C_M_IGNORE_NAK; if (!(pmsg->flags & I2C_M_NOSTART)) { if (i) { + bit_dbg(3, &i2c_adap->dev, "emitting " + "repeated start condition\n"); i2c_repstart(adap); } ret = bit_doAddress(i2c_adap, pmsg); if ((ret != 0) && !nak_ok) { - DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n" - ,msgs[i].addr,i)); + bit_dbg(1, &i2c_adap->dev, "NAK from " + "device addr 0x%02x msg #%d\n", + msgs[i].addr, i); goto bailout; } } if (pmsg->flags & I2C_M_RD ) { /* read bytes into buffer*/ ret = readbytes(i2c_adap, pmsg); - DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", + ret, ret == 1 ? "" : "s"); if (ret < pmsg->len) { if (ret >= 0) ret = -EREMOTEIO; @@ -508,7 +519,9 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, } else { /* write bytes from buffer */ ret = sendbytes(i2c_adap, pmsg); - DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); + if (ret >= 1) + bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", + ret, ret == 1 ? "" : "s"); if (ret < pmsg->len) { if (ret >= 0) ret = -EREMOTEIO; @@ -519,6 +532,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ret = i; bailout: + bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); i2c_stop(adap); return ret; } @@ -552,8 +566,6 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap) return -ENODEV; } - DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); - /* register new adapter to i2c module... */ adap->algo = &i2c_bit_algo; @@ -590,10 +602,3 @@ EXPORT_SYMBOL(i2c_bit_add_numbered_bus); MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); MODULE_LICENSE("GPL"); - -module_param(bit_test, bool, 0); -module_param(i2c_debug, int, S_IRUGO | S_IWUSR); - -MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); -MODULE_PARM_DESC(i2c_debug, - "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol"); -- cgit