aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index 8a5f5825bb72..7f0a0a62cf60 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)
357 return wrcount; 357 return wrcount;
358} 358}
359 359
360static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
361{
362 struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
363
364 /* assert: sda is high */
365 if (is_ack) /* send ack */
366 setsda(adap, 0);
367 udelay((adap->udelay + 1) / 2);
368 if (sclhi(adap) < 0) { /* timeout */
369 dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
370 return -ETIMEDOUT;
371 }
372 scllo(adap);
373 return 0;
374}
375
360static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) 376static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
361{ 377{
362 int inval; 378 int inval;
363 int rdcount=0; /* counts bytes read */ 379 int rdcount=0; /* counts bytes read */
364 struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
365 unsigned char *temp = msg->buf; 380 unsigned char *temp = msg->buf;
366 int count = msg->len; 381 int count = msg->len;
382 const unsigned flags = msg->flags;
367 383
368 while (count > 0) { 384 while (count > 0) {
369 inval = i2c_inb(i2c_adap); 385 inval = i2c_inb(i2c_adap);
@@ -377,28 +393,12 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
377 temp++; 393 temp++;
378 count--; 394 count--;
379 395
380 if (msg->flags & I2C_M_NO_RD_ACK) {
381 bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n",
382 inval);
383 continue;
384 }
385
386 /* assert: sda is high */
387 if (count) /* send ack */
388 setsda(adap, 0);
389 udelay((adap->udelay + 1) / 2);
390 bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval,
391 count ? "A" : "NA");
392 if (sclhi(adap)<0) { /* timeout */
393 dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n");
394 return -ETIMEDOUT;
395 };
396 scllo(adap);
397
398 /* Some SMBus transactions require that we receive the 396 /* Some SMBus transactions require that we receive the
399 transaction length as the first read byte. */ 397 transaction length as the first read byte. */
400 if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) { 398 if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {
401 if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { 399 if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
400 if (!(flags & I2C_M_NO_RD_ACK))
401 acknak(i2c_adap, 0);
402 dev_err(&i2c_adap->dev, "readbytes: invalid " 402 dev_err(&i2c_adap->dev, "readbytes: invalid "
403 "block length (%d)\n", inval); 403 "block length (%d)\n", inval);
404 return -EREMOTEIO; 404 return -EREMOTEIO;
@@ -409,6 +409,18 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
409 count += inval; 409 count += inval;
410 msg->len += inval; 410 msg->len += inval;
411 } 411 }
412
413 bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",
414 inval,
415 (flags & I2C_M_NO_RD_ACK)
416 ? "(no ack/nak)"
417 : (count ? "A" : "NA"));
418
419 if (!(flags & I2C_M_NO_RD_ACK)) {
420 inval = acknak(i2c_adap, count);
421 if (inval < 0)
422 return inval;
423 }
412 } 424 }
413 return rdcount; 425 return rdcount;
414} 426}