Commit a712ff9f authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] update i2c algorithm drivers

This one is from lm_sensors CVS and mostly cosmetic changes.  I it up a
bit to compile properly under latest 2.5.
parent 28db79d6
...@@ -41,27 +41,13 @@ ...@@ -41,27 +41,13 @@
#define DEBPROTO(x) if (i2c_debug>=9) { x; } #define DEBPROTO(x) if (i2c_debug>=9) { x; }
/* debug the protocol by showing transferred bits */ /* debug the protocol by showing transferred bits */
/* debugging - slow down transfer to have a look at the data .. */
/* I use this with two leds&resistors, each one connected to sda,scl */
/* respectively. This makes sure that the algorithm works. Some chips */
/* might not like this, as they have an internal timeout of some mils */
/*
#define SLO_IO jif=jiffies;while(time_before_eq(jiffies, jif+i2c_table[minor].veryslow))\
cond_resched();
*/
/* ----- global variables --------------------------------------------- */ /* ----- global variables --------------------------------------------- */
#ifdef SLO_IO
int jif;
#endif
/* module parameters: /* module parameters:
*/ */
static int i2c_debug; static int i2c_debug;
static int bit_test; /* see if the line-setting functions work */ static int bit_test; /* see if the line-setting functions work */
static int bit_scan; /* have a look at what's hanging 'round */
/* --- setting states on the bus with the right timing: --------------- */ /* --- setting states on the bus with the right timing: --------------- */
...@@ -86,9 +72,6 @@ static inline void scllo(struct i2c_algo_bit_data *adap) ...@@ -86,9 +72,6 @@ static inline void scllo(struct i2c_algo_bit_data *adap)
{ {
setscl(adap,0); setscl(adap,0);
udelay(adap->udelay); udelay(adap->udelay);
#ifdef SLO_IO
SLO_IO
#endif
} }
/* /*
...@@ -97,32 +80,28 @@ static inline void scllo(struct i2c_algo_bit_data *adap) ...@@ -97,32 +80,28 @@ static inline void scllo(struct i2c_algo_bit_data *adap)
*/ */
static inline int sclhi(struct i2c_algo_bit_data *adap) static inline int sclhi(struct i2c_algo_bit_data *adap)
{ {
int start=jiffies; unsigned long start;
setscl(adap,1); setscl(adap,1);
udelay(adap->udelay);
/* Not all adapters have scl sense line... */ /* Not all adapters have scl sense line... */
if (adap->getscl == NULL ) if (adap->getscl == NULL )
return 0; return 0;
while (! getscl(adap) ) { start=jiffies;
while (! getscl(adap) ) {
/* the hw knows how to read the clock line, /* the hw knows how to read the clock line,
* so we wait until it actually gets high. * so we wait until it actually gets high.
* This is safer as some chips may hold it low * This is safer as some chips may hold it low
* while they are processing data internally. * while they are processing data internally.
*/ */
setscl(adap,1);
if (time_after_eq(jiffies, start+adap->timeout)) { if (time_after_eq(jiffies, start+adap->timeout)) {
return -ETIMEDOUT; return -ETIMEDOUT;
} }
cond_resched(); cond_resched();
} }
DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start));
#ifdef SLO_IO udelay(adap->udelay);
SLO_IO
#endif
return 0; return 0;
} }
...@@ -175,7 +154,6 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) ...@@ -175,7 +154,6 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
/* assert: scl is low */ /* assert: scl is low */
DEB2(printk(KERN_DEBUG " i2c_outb:%2.2X\n",c&0xff));
for ( i=7 ; i>=0 ; i-- ) { for ( i=7 ; i>=0 ; i-- ) {
sb = c & ( 1 << i ); sb = c & ( 1 << i );
setsda(adap,sb); setsda(adap,sb);
...@@ -183,6 +161,7 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) ...@@ -183,6 +161,7 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
if (sclhi(adap)<0) { /* timed out */ if (sclhi(adap)<0) { /* timed out */
sdahi(adap); /* we don't want to block the net */ 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; return -ETIMEDOUT;
}; };
/* do arbitration here: /* do arbitration here:
...@@ -193,11 +172,12 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c) ...@@ -193,11 +172,12 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
} }
sdahi(adap); sdahi(adap);
if (sclhi(adap)<0){ /* timeout */ if (sclhi(adap)<0){ /* timeout */
return -ETIMEDOUT; DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff));
return -ETIMEDOUT;
}; };
/* read ack: SDA should be pulled down by slave */ /* read ack: SDA should be pulled down by slave */
ack=getsda(adap); /* ack: sda is pulled low ->success. */ ack=getsda(adap); /* ack: sda is pulled low ->success. */
DEB2(printk(KERN_DEBUG " i2c_outb: getsda() = 0x%2.2x\n", ~ack )); DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack));
DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) ); DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) );
DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") ); DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") );
...@@ -216,11 +196,10 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) ...@@ -216,11 +196,10 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
/* assert: scl is low */ /* assert: scl is low */
DEB2(printk(KERN_DEBUG "i2c_inb.\n"));
sdahi(adap); sdahi(adap);
for (i=0;i<8;i++) { for (i=0;i<8;i++) {
if (sclhi(adap)<0) { /* timeout */ if (sclhi(adap)<0) { /* timeout */
DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i));
return -ETIMEDOUT; return -ETIMEDOUT;
}; };
indata *= 2; indata *= 2;
...@@ -229,7 +208,9 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) ...@@ -229,7 +208,9 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
scllo(adap); scllo(adap);
} }
/* assert: scl is low */ /* assert: scl is low */
DEBPROTO(printk(KERN_DEBUG " %2.2x", indata & 0xff)); DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff));
DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff));
return (int) (indata & 0xff); return (int) (indata & 0xff);
} }
...@@ -337,30 +318,35 @@ static inline int try_address(struct i2c_adapter *i2c_adap, ...@@ -337,30 +318,35 @@ static inline int try_address(struct i2c_adapter *i2c_adap,
i2c_start(adap); i2c_start(adap);
udelay(adap->udelay); udelay(adap->udelay);
} }
DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: needed %d retries for %d\n", DEB2(if (i)
i,addr)); 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?" )
);
return ret; return ret;
} }
static int sendbytes(struct i2c_adapter *i2c_adap,const char *buf, int count) static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
{ {
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
char c; char c;
const char *temp = buf; const char *temp = msg->buf;
int count = msg->len;
unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
int retval; int retval;
int wrcount=0; int wrcount=0;
while (count > 0) { while (count > 0) {
c = *temp; c = *temp;
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s i2c_write: writing %2.2X\n", DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n",
i2c_adap->name, c&0xff)); i2c_adap->name, c&0xff));
retval = i2c_outb(i2c_adap,c); retval = i2c_outb(i2c_adap,c);
if (retval>0) { if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */
count--; count--;
temp++; temp++;
wrcount++; wrcount++;
} else { /* arbitration or no acknowledge */ } else { /* arbitration or no acknowledge */
printk(KERN_ERR "i2c-algo-bit.o: %s i2c_write: error - bailout.\n", printk(KERN_ERR "i2c-algo-bit.o: %s sendbytes: error - bailout.\n",
i2c_adap->name); i2c_adap->name);
i2c_stop(adap); i2c_stop(adap);
return (retval<0)? retval : -EFAULT; return (retval<0)? retval : -EFAULT;
...@@ -374,12 +360,13 @@ static int sendbytes(struct i2c_adapter *i2c_adap,const char *buf, int count) ...@@ -374,12 +360,13 @@ static int sendbytes(struct i2c_adapter *i2c_adap,const char *buf, int count)
return wrcount; return wrcount;
} }
static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count) static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
{ {
char *temp = buf;
int inval; int inval;
int rdcount=0; /* counts bytes read */ int rdcount=0; /* counts bytes read */
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
char *temp = msg->buf;
int count = msg->len;
while (count > 0) { while (count > 0) {
inval = i2c_inb(i2c_adap); inval = i2c_inb(i2c_adap);
...@@ -388,7 +375,7 @@ static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count) ...@@ -388,7 +375,7 @@ static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count)
*temp = inval; *temp = inval;
rdcount++; rdcount++;
} else { /* read timed out */ } else { /* read timed out */
printk(KERN_ERR "i2c-algo-bit.o: i2c_read: i2c_inb timed out.\n"); printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n");
break; break;
} }
...@@ -401,7 +388,7 @@ static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count) ...@@ -401,7 +388,7 @@ static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count)
} }
if (sclhi(adap)<0) { /* timeout */ if (sclhi(adap)<0) { /* timeout */
sdahi(adap); sdahi(adap);
printk(KERN_ERR "i2c-algo-bit.o: i2c_read: Timeout at ack\n"); printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
return -ETIMEDOUT; return -ETIMEDOUT;
}; };
scllo(adap); scllo(adap);
...@@ -416,31 +403,34 @@ static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count) ...@@ -416,31 +403,34 @@ static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count)
* try_address) and transmits the address in the necessary format to handle * try_address) and transmits the address in the necessary format to handle
* reads, writes as well as 10bit-addresses. * reads, writes as well as 10bit-addresses.
* returns: * returns:
* 0 everything went okay, the chip ack'ed * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
* -x an error occurred (like: -EREMOTEIO if the device did not answer, or * -x an error occurred (like: -EREMOTEIO if the device did not answer, or
* -ETIMEDOUT, for example if the lines are stuck...) * -ETIMEDOUT, for example if the lines are stuck...)
*/ */
static inline int bit_doAddress(struct i2c_adapter *i2c_adap, static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
struct i2c_msg *msg, int retries)
{ {
unsigned short flags = msg->flags; unsigned short flags = msg->flags;
unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
unsigned char addr; unsigned char addr;
int ret; int ret, retries;
retries = nak_ok ? 0 : i2c_adap->retries;
if ( (flags & I2C_M_TEN) ) { if ( (flags & I2C_M_TEN) ) {
/* a ten bit address */ /* a ten bit address */
addr = 0xf0 | (( msg->addr >> 7) & 0x03); addr = 0xf0 | (( msg->addr >> 7) & 0x03);
DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
/* try extended address code...*/ /* try extended address code...*/
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
if (ret!=1) { if ((ret != 1) && !nak_ok) {
printk(KERN_ERR "died at extended address code.\n"); printk(KERN_ERR "died at extended address code.\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
/* the remaining 8 bit address */ /* the remaining 8 bit address */
ret = i2c_outb(i2c_adap,msg->addr & 0x7f); ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
if (ret != 1) { if ((ret != 1) && !nak_ok) {
/* the chip did not ack / xmission error occurred */ /* the chip did not ack / xmission error occurred */
printk(KERN_ERR "died at 2nd address code.\n"); printk(KERN_ERR "died at 2nd address code.\n");
return -EREMOTEIO; return -EREMOTEIO;
...@@ -450,7 +440,7 @@ static inline int bit_doAddress(struct i2c_adapter *i2c_adap, ...@@ -450,7 +440,7 @@ static inline int bit_doAddress(struct i2c_adapter *i2c_adap,
/* okay, now switch into reading mode */ /* okay, now switch into reading mode */
addr |= 0x01; addr |= 0x01;
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
if (ret!=1) { if ((ret!=1) && !nak_ok) {
printk(KERN_ERR "died at extended address code.\n"); printk(KERN_ERR "died at extended address code.\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
...@@ -462,10 +452,10 @@ static inline int bit_doAddress(struct i2c_adapter *i2c_adap, ...@@ -462,10 +452,10 @@ static inline int bit_doAddress(struct i2c_adapter *i2c_adap,
if (flags & I2C_M_REV_DIR_ADDR ) if (flags & I2C_M_REV_DIR_ADDR )
addr ^= 1; addr ^= 1;
ret = try_address(i2c_adap, addr, retries); ret = try_address(i2c_adap, addr, retries);
if (ret!=1) { if ((ret!=1) && !nak_ok)
return -EREMOTEIO; return -EREMOTEIO;
}
} }
return 0; return 0;
} }
...@@ -476,31 +466,33 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ...@@ -476,31 +466,33 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
struct i2c_algo_bit_data *adap = i2c_adap->algo_data; struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
int i,ret; int i,ret;
unsigned short nak_ok;
i2c_start(adap); i2c_start(adap);
for (i=0;i<num;i++) { for (i=0;i<num;i++) {
pmsg = &msgs[i]; pmsg = &msgs[i];
nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
if (!(pmsg->flags & I2C_M_NOSTART)) { if (!(pmsg->flags & I2C_M_NOSTART)) {
if (i) { if (i) {
i2c_repstart(adap); i2c_repstart(adap);
} }
ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries); ret = bit_doAddress(i2c_adap, pmsg);
if (ret != 0) { if ((ret != 0) && !nak_ok) {
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device adr %#2x msg #%d\n" DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n"
,msgs[i].addr,i)); ,msgs[i].addr,i));
return (ret<0) ? ret : -EREMOTEIO; return (ret<0) ? ret : -EREMOTEIO;
} }
} }
if (pmsg->flags & I2C_M_RD ) { if (pmsg->flags & I2C_M_RD ) {
/* read bytes into buffer*/ /* read bytes into buffer*/
ret = readbytes(i2c_adap,pmsg->buf,pmsg->len); ret = readbytes(i2c_adap, pmsg);
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret));
if (ret < pmsg->len ) { if (ret < pmsg->len ) {
return (ret<0)? ret : -EREMOTEIO; return (ret<0)? ret : -EREMOTEIO;
} }
} else { } else {
/* write bytes from buffer */ /* write bytes from buffer */
ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len); ret = sendbytes(i2c_adap, pmsg);
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret));
if (ret < pmsg->len ) { if (ret < pmsg->len ) {
return (ret<0) ? ret : -EREMOTEIO; return (ret<0) ? ret : -EREMOTEIO;
...@@ -511,12 +503,6 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, ...@@ -511,12 +503,6 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
return num; return num;
} }
static int algo_control(struct i2c_adapter *adapter,
unsigned int cmd, unsigned long arg)
{
return 0;
}
static u32 bit_func(struct i2c_adapter *adap) static u32 bit_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
...@@ -530,7 +516,6 @@ static struct i2c_algorithm i2c_bit_algo = { ...@@ -530,7 +516,6 @@ static struct i2c_algorithm i2c_bit_algo = {
.name = "Bit-shift algorithm", .name = "Bit-shift algorithm",
.id = I2C_ALGO_BIT, .id = I2C_ALGO_BIT,
.master_xfer = bit_xfer, .master_xfer = bit_xfer,
.algo_control = algo_control,
.functionality = bit_func, .functionality = bit_func,
}; };
...@@ -539,7 +524,6 @@ static struct i2c_algorithm i2c_bit_algo = { ...@@ -539,7 +524,6 @@ static struct i2c_algorithm i2c_bit_algo = {
*/ */
int i2c_bit_add_bus(struct i2c_adapter *adap) int i2c_bit_add_bus(struct i2c_adapter *adap)
{ {
int i;
struct i2c_algo_bit_data *bit_adap = adap->algo_data; struct i2c_algo_bit_data *bit_adap = adap->algo_data;
if (bit_test) { if (bit_test) {
...@@ -559,23 +543,6 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) ...@@ -559,23 +543,6 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
adap->timeout = 100; /* default values, should */ adap->timeout = 100; /* default values, should */
adap->retries = 3; /* be replaced by defines */ adap->retries = 3; /* be replaced by defines */
/* scan bus */
if (bit_scan) {
int ack;
printk(KERN_INFO " i2c-algo-bit.o: scanning bus %s.\n",
adap->name);
for (i = 0x00; i < 0xff; i+=2) {
i2c_start(bit_adap);
ack = i2c_outb(adap,i);
i2c_stop(bit_adap);
if (ack>0) {
printk("(%02x)",i>>1);
} else
printk(".");
}
printk("\n");
}
i2c_add_adapter(adap); i2c_add_adapter(adap);
return 0; return 0;
} }
...@@ -583,14 +550,7 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) ...@@ -583,14 +550,7 @@ int i2c_bit_add_bus(struct i2c_adapter *adap)
int i2c_bit_del_bus(struct i2c_adapter *adap) int i2c_bit_del_bus(struct i2c_adapter *adap)
{ {
int res; return i2c_del_adapter(adap);
if ((res = i2c_del_adapter(adap)) < 0)
return res;
DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: adapter unregistered: %s\n",adap->name));
return 0;
} }
EXPORT_SYMBOL(i2c_bit_add_bus); EXPORT_SYMBOL(i2c_bit_add_bus);
...@@ -601,10 +561,8 @@ MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); ...@@ -601,10 +561,8 @@ MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(bit_test, "i"); MODULE_PARM(bit_test, "i");
MODULE_PARM(bit_scan, "i");
MODULE_PARM(i2c_debug,"i"); MODULE_PARM(i2c_debug,"i");
MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck");
MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
MODULE_PARM_DESC(i2c_debug, MODULE_PARM_DESC(i2c_debug,
"debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol"); "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol");
...@@ -55,20 +55,12 @@ ...@@ -55,20 +55,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/version.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include "i2c-algo-ibm_ocp.h" #include <linux/i2c-algo-ibm_ocp.h>
//ACC#include <asm/ocp.h> #include <asm/ocp.h>
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif
/* ----- global defines ----------------------------------------------- */ /* ----- global defines ----------------------------------------------- */
...@@ -79,26 +71,13 @@ MODULE_LICENSE("GPL"); ...@@ -79,26 +71,13 @@ MODULE_LICENSE("GPL");
/* debug the protocol by showing transferred bits */ /* debug the protocol by showing transferred bits */
#define DEF_TIMEOUT 5 #define DEF_TIMEOUT 5
/* debugging - slow down transfer to have a look at the data .. */
/* I use this with two leds&resistors, each one connected to sda,scl */
/* respectively. This makes sure that the algorithm works. Some chips */
/* might not like this, as they have an internal timeout of some mils */
/*
#define SLO_IO jif=jiffies;while(time_before_eq(jiffies,jif+i2c_table[minor].veryslow))\
if (need_resched) schedule();
*/
/* ----- global variables --------------------------------------------- */ /* ----- global variables --------------------------------------------- */
#ifdef SLO_IO
int jif;
#endif
/* module parameters: /* module parameters:
*/ */
static int i2c_debug=0; static int i2c_debug=0;
static int iic_scan=0; /* have a look at what's hanging 'round */
/* --- setting states on the bus with the right timing: --------------- */ /* --- setting states on the bus with the right timing: --------------- */
...@@ -758,7 +737,7 @@ static int iic_xfer(struct i2c_adapter *i2c_adap, ...@@ -758,7 +737,7 @@ static int iic_xfer(struct i2c_adapter *i2c_adap,
// Check to see if the bus is busy // Check to see if the bus is busy
// //
ret = iic_inb(adap, iic->extsts); ret = iic_inb(adap, iic->extsts);
// Mask off the irrelevant bits // Mask off the irrelevent bits
ret = ret & 0x70; ret = ret & 0x70;
// When the bus is free, the BCS bits in the EXTSTS register are 0b100 // When the bus is free, the BCS bits in the EXTSTS register are 0b100
if(ret != 0x40) return IIC_ERR_LOST_ARB; if(ret != 0x40) return IIC_ERR_LOST_ARB;
...@@ -858,17 +837,13 @@ static u32 iic_func(struct i2c_adapter *adap) ...@@ -858,17 +837,13 @@ static u32 iic_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */ /* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm iic_algo = { static struct i2c_algorithm iic_algo = {
"IBM on-chip IIC algorithm", .name = "IBM on-chip IIC algorithm",
I2C_ALGO_OCP, .id = I2C_ALGO_OCP,
iic_xfer, .master_xfer = iic_xfer,
NULL, .algo_control = algo_control,
NULL, /* slave_xmit */ .functionality = iic_func,
NULL, /* slave_recv */
algo_control, /* ioctl */
iic_func, /* functionality */
}; };
/* /*
* registering functions to load algorithms at runtime * registering functions to load algorithms at runtime
*/ */
...@@ -892,19 +867,8 @@ int i2c_ocp_add_bus(struct i2c_adapter *adap) ...@@ -892,19 +867,8 @@ int i2c_ocp_add_bus(struct i2c_adapter *adap)
adap->timeout = 100; /* default values, should */ adap->timeout = 100; /* default values, should */
adap->retries = 3; /* be replaced by defines */ adap->retries = 3; /* be replaced by defines */
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
iic_init(iic_adap); iic_init(iic_adap);
i2c_add_adapter(adap); i2c_add_adapter(adap);
/* scan bus */
/* By default scanning the bus is turned off. */
if (iic_scan) {
printk(KERN_INFO " i2c-algo-iic.o: scanning bus %s.\n",
adap->name);
}
return 0; return 0;
} }
...@@ -914,31 +878,7 @@ int i2c_ocp_add_bus(struct i2c_adapter *adap) ...@@ -914,31 +878,7 @@ int i2c_ocp_add_bus(struct i2c_adapter *adap)
// //
int i2c_ocp_del_bus(struct i2c_adapter *adap) int i2c_ocp_del_bus(struct i2c_adapter *adap)
{ {
int res; return i2c_del_adapter(adap);
if ((res = i2c_del_adapter(adap)) < 0)
return res;
DEB2(printk(KERN_DEBUG "i2c-algo-iic.o: adapter unregistered: %s\n",adap->name));
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return 0;
}
//
// Done
//
int __init i2c_algo_iic_init (void)
{
printk(KERN_INFO "IBM On-chip iic (i2c) algorithm module 2002.27.03\n");
return 0;
}
void i2c_algo_iic_exit(void)
{
return;
} }
...@@ -951,16 +891,10 @@ EXPORT_SYMBOL(i2c_ocp_del_bus); ...@@ -951,16 +891,10 @@ EXPORT_SYMBOL(i2c_ocp_del_bus);
// //
MODULE_AUTHOR("MontaVista Software <www.mvista.com>"); MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
MODULE_DESCRIPTION("PPC 405 iic algorithm"); MODULE_DESCRIPTION("PPC 405 iic algorithm");
MODULE_LICENSE("GPL");
MODULE_PARM(iic_test, "i");
MODULE_PARM(iic_scan, "i");
MODULE_PARM(i2c_debug,"i"); MODULE_PARM(i2c_debug,"i");
MODULE_PARM_DESC(iic_test, "Test if the I2C bus is available");
MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus");
MODULE_PARM_DESC(i2c_debug, MODULE_PARM_DESC(i2c_debug,
"debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol"); "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
module_init(i2c_algo_iic_init);
module_exit(i2c_algo_iic_exit);
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
/* module parameters: /* module parameters:
*/ */
static int i2c_debug=0; static int i2c_debug=0;
static int pcf_scan=0; /* have a look at what's hanging 'round */
/* --- setting states on the bus with the right timing: --------------- */ /* --- setting states on the bus with the right timing: --------------- */
...@@ -423,12 +422,6 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, ...@@ -423,12 +422,6 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
return (i); return (i);
} }
static int algo_control(struct i2c_adapter *adapter,
unsigned int cmd, unsigned long arg)
{
return 0;
}
static u32 pcf_func(struct i2c_adapter *adap) static u32 pcf_func(struct i2c_adapter *adap)
{ {
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
...@@ -438,14 +431,10 @@ static u32 pcf_func(struct i2c_adapter *adap) ...@@ -438,14 +431,10 @@ static u32 pcf_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */ /* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm pcf_algo = { static struct i2c_algorithm pcf_algo = {
"PCF8584 algorithm", .name = "PCF8584 algorithm",
I2C_ALGO_PCF, .id = I2C_ALGO_PCF,
pcf_xfer, .master_xfer = pcf_xfer,
NULL, .functionality = pcf_func,
NULL, /* slave_xmit */
NULL, /* slave_recv */
algo_control, /* ioctl */
pcf_func, /* functionality */
}; };
/* /*
...@@ -453,8 +442,8 @@ static struct i2c_algorithm pcf_algo = { ...@@ -453,8 +442,8 @@ static struct i2c_algorithm pcf_algo = {
*/ */
int i2c_pcf_add_bus(struct i2c_adapter *adap) int i2c_pcf_add_bus(struct i2c_adapter *adap)
{ {
int i, status;
struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
int rval;
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n", DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n",
adap->name)); adap->name));
...@@ -467,36 +456,10 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) ...@@ -467,36 +456,10 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
adap->timeout = 100; /* default values, should */ adap->timeout = 100; /* default values, should */
adap->retries = 3; /* be replaced by defines */ adap->retries = 3; /* be replaced by defines */
if ((i = pcf_init_8584(pcf_adap))) { rval = pcf_init_8584(pcf_adap);
return i; if (!rval)
} i2c_add_adapter(adap);
return rval;
i2c_add_adapter(adap);
/* scan bus */
if (pcf_scan) {
printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s.\n",
adap->name);
for (i = 0x00; i < 0xff; i+=2) {
if (wait_for_bb(pcf_adap)) {
printk(KERN_INFO " i2c-algo-pcf.o: scanning bus %s - TIMEOUTed.\n",
adap->name);
break;
}
i2c_outb(pcf_adap, i);
i2c_start(pcf_adap);
if ((wait_for_pin(pcf_adap, &status) >= 0) &&
((status & I2C_PCF_LRB) == 0)) {
printk("(%02x)",i>>1);
} else {
printk(".");
}
i2c_stop(pcf_adap);
udelay(pcf_adap->udelay);
}
printk("\n");
}
return 0;
} }
...@@ -512,9 +475,6 @@ MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>"); ...@@ -512,9 +475,6 @@ MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm"); MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(pcf_scan, "i");
MODULE_PARM(i2c_debug,"i"); MODULE_PARM(i2c_debug,"i");
MODULE_PARM_DESC(pcf_scan, "Scan for active chips on the bus");
MODULE_PARM_DESC(i2c_debug, MODULE_PARM_DESC(i2c_debug,
"debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment