X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fi2c%2Falgos%2Fi2c-algo-bit.c;h=95aa5395a5bedb02fcf99b5eaa45fd03c929a9e0;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=efcb775246f1c6d6819010d9871f17b0f86b330b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index efcb77524..95aa5395a 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -76,17 +76,15 @@ static inline void scllo(struct i2c_algo_bit_data *adap) * Raise scl line, and do checking for delays. This is necessary for slower * devices. */ -static inline int sclhi(struct i2c_algo_bit_data *adap) +static int sclhi(struct i2c_algo_bit_data *adap) { unsigned long start; setscl(adap,1); /* Not all adapters have scl sense line... */ - if (adap->getscl == NULL ) { - udelay(adap->udelay); - return 0; - } + if (!adap->getscl) + goto done; start=jiffies; while (! getscl(adap) ) { @@ -101,6 +99,8 @@ static inline int sclhi(struct i2c_algo_bit_data *adap) cond_resched(); } DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); + +done: udelay(adap->udelay); return 0; } @@ -121,7 +121,6 @@ static void i2c_repstart(struct i2c_algo_bit_data *adap) DEBPROTO(printk(" Sr ")); setsda(adap,1); sclhi(adap); - udelay(adap->udelay); sdalo(adap); scllo(adap); @@ -306,7 +305,7 @@ bailout: * 0 chip did not answer * -x transmission error */ -static inline int try_address(struct i2c_adapter *i2c_adap, +static int try_address(struct i2c_adapter *i2c_adap, unsigned char addr, int retries) { struct i2c_algo_bit_data *adap = i2c_adap->algo_data; @@ -354,15 +353,11 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) return (retval<0)? retval : -EFAULT; /* got a better one ?? */ } -#if 0 - /* from asm/delay.h */ - __delay(adap->mdelay * (loops_per_sec / 1000) ); -#endif } return wrcount; } -static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int inval; int rdcount=0; /* counts bytes read */ @@ -372,7 +367,6 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) while (count > 0) { inval = i2c_inb(i2c_adap); -/*printk("%#02x ",inval); if ( ! (count % 16) ) printk("\n"); */ if (inval>=0) { *temp = inval; rdcount++; @@ -381,7 +375,13 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) break; } - if ( count > 1 ) { /* send ack */ + temp++; + count--; + + if (msg->flags & I2C_M_NO_RD_ACK) + continue; + + if ( count > 0 ) { /* send ack */ sdalo(adap); DEBPROTO(printk(" Am ")); } else { @@ -395,8 +395,6 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }; scllo(adap); sdahi(adap); - temp++; - count--; } return rdcount; } @@ -409,7 +407,7 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) * -x an error occurred (like: -EREMOTEIO if the device did not answer, or * -ETIMEDOUT, for example if the lines are stuck...) */ -static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { unsigned short flags = msg->flags; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; @@ -507,16 +505,14 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, static u32 bit_func(struct i2c_adapter *adap) { - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | - I2C_FUNC_PROTOCOL_MANGLING; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | + I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; } /* -----exported algorithm data: ------------------------------------- */ -static struct i2c_algorithm i2c_bit_algo = { - .name = "Bit-shift algorithm", - .id = I2C_ALGO_BIT, +static const struct i2c_algorithm i2c_bit_algo = { .master_xfer = bit_xfer, .functionality = bit_func, }; @@ -537,32 +533,21 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); /* register new adapter to i2c module... */ - - adap->id |= i2c_bit_algo.id; adap->algo = &i2c_bit_algo; adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - i2c_add_adapter(adap); - return 0; -} - - -int i2c_bit_del_bus(struct i2c_adapter *adap) -{ - return i2c_del_adapter(adap); + return i2c_add_adapter(adap); } - EXPORT_SYMBOL(i2c_bit_add_bus); -EXPORT_SYMBOL(i2c_bit_del_bus); MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); MODULE_LICENSE("GPL"); -MODULE_PARM(bit_test, "i"); -MODULE_PARM(i2c_debug,"i"); +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,