From 9a3180e70e35ff69586ada5421b5e7bad52f60e4 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 9 Sep 2007 22:29:13 +0200 Subject: [PATCH 1/3] i2c-gpio: Fix adapter number It turns out that platform_device.id is a "u32" so testing it for being nonnegative is useless when setting up an i2c bitbang device. Instead, do what the platform_bus code does and test it against the value "-1". Signed-off-by: David Brownell Acked-by: Atsushi Nemoto Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 025f19423faffe..44e1cd21bb0130 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -147,7 +147,7 @@ static int __init i2c_gpio_probe(struct platform_device *pdev) * The reason to do so is to avoid sysfs names that only make * sense when there are multiple adapters. */ - adap->nr = pdev->id >= 0 ? pdev->id : 0; + adap->nr = (pdev->id != -1) ? pdev->id : 0; ret = i2c_bit_add_numbered_bus(adap); if (ret) goto err_add_bus; From 51e5709ad46127da9476f31336113b5401f94dba Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 9 Sep 2007 22:29:13 +0200 Subject: [PATCH 2/3] i2c-pxa: Fix adapter number It turns out that platform_device.id is a "u32" so testing it for being nonnegative is useless when setting up an i2c adapte. Instead, do what the platform_bus code does and test it against the value "-1". Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-pxa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 9d6b790d43210f..bb5466b27b59ab 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -926,7 +926,7 @@ static int i2c_pxa_probe(struct platform_device *dev) * The reason to do so is to avoid sysfs names that only make * sense when there are multiple adapters. */ - i2c->adap.nr = dev->id >= 0 ? dev->id : 0; + i2c->adap.nr = dev->id != -1 ? dev->id : 0; ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { From 939bc4943d0483961edc45b63a7d27b4ffe547e3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 9 Sep 2007 22:29:14 +0200 Subject: [PATCH 3/3] i2c-algo-bit: Read block data bugfix This fixes a bug in the way i2c-algo-bit handles I2C_M_RECV_LEN, used to implement i2c_smbus_read_block_data(). Previously, in the absence of PEC (rarely used!) it would NAK the "length" byte: S addr Rd [A] [length] NA That prevents the subsequent data bytes from being read: S addr Rd [A] [length] { A [data] }* NA The primary fix just reorders two code blocks, so the length used in the "should I NAK now?" check incorporates the data which it just read from the slave device. However, that move also highlighted other fault handling glitches. This fixes those by abstracting the RX path ack/nak logic, so it can be used in more than one location. Also, a few CodingStyle issues were also resolved. Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- drivers/i2c/algos/i2c-algo-bit.c | 52 ++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 8a5f5825bb7294..7f0a0a62cf60fc 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -357,13 +357,29 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) return wrcount; } +static int acknak(struct i2c_adapter *i2c_adap, int is_ack) +{ + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + + /* assert: sda is high */ + if (is_ack) /* send ack */ + setsda(adap, 0); + udelay((adap->udelay + 1) / 2); + if (sclhi(adap) < 0) { /* timeout */ + dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n"); + return -ETIMEDOUT; + } + scllo(adap); + return 0; +} + 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; unsigned char *temp = msg->buf; int count = msg->len; + const unsigned flags = msg->flags; while (count > 0) { inval = i2c_inb(i2c_adap); @@ -377,28 +393,12 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) temp++; count--; - 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) /* send ack */ - setsda(adap, 0); - 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 */ - dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n"); - return -ETIMEDOUT; - }; - scllo(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 (rdcount == 1 && (flags & I2C_M_RECV_LEN)) { if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { + if (!(flags & I2C_M_NO_RD_ACK)) + acknak(i2c_adap, 0); dev_err(&i2c_adap->dev, "readbytes: invalid " "block length (%d)\n", inval); return -EREMOTEIO; @@ -409,6 +409,18 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) count += inval; msg->len += inval; } + + bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", + inval, + (flags & I2C_M_NO_RD_ACK) + ? "(no ack/nak)" + : (count ? "A" : "NA")); + + if (!(flags & I2C_M_NO_RD_ACK)) { + inval = acknak(i2c_adap, count); + if (inval < 0) + return inval; + } } return rdcount; }