Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 64752
b: refs/heads/master
c: 939bc49
h: refs/heads/master
v: v3
  • Loading branch information
David Brownell authored and Jean Delvare committed Sep 9, 2007
1 parent 51b1aa6 commit c959956
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 51e5709ad46127da9476f31336113b5401f94dba
refs/heads/master: 939bc4943d0483961edc45b63a7d27b4ffe547e3
52 changes: 32 additions & 20 deletions trunk/drivers/i2c/algos/i2c-algo-bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit c959956

Please sign in to comment.