diff options
Diffstat (limited to 'drivers/i2c/algos')
-rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 52 |
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 | ||
360 | static 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 | |||
360 | static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | 376 | static 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 | } |