aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-imx.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 886217f1ba61..5f4bc7008251 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -458,7 +458,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
458 return 0; 458 return 0;
459} 459}
460 460
461static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) 461static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool is_lastmsg)
462{ 462{
463 int i, result; 463 int i, result;
464 unsigned int temp; 464 unsigned int temp;
@@ -515,15 +515,30 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
515 msgs->len += len; 515 msgs->len += len;
516 } 516 }
517 if (i == (msgs->len - 1)) { 517 if (i == (msgs->len - 1)) {
518 /* It must generate STOP before read I2DR to prevent 518 if (is_lastmsg) {
519 controller from generating another clock cycle */ 519 /*
520 dev_dbg(&i2c_imx->adapter.dev, 520 * It must generate STOP before read I2DR to prevent
521 "<%s> clear MSTA\n", __func__); 521 * controller from generating another clock cycle
522 temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); 522 */
523 temp &= ~(I2CR_MSTA | I2CR_MTX); 523 dev_dbg(&i2c_imx->adapter.dev,
524 imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); 524 "<%s> clear MSTA\n", __func__);
525 i2c_imx_bus_busy(i2c_imx, 0); 525 temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
526 i2c_imx->stopped = 1; 526 temp &= ~(I2CR_MSTA | I2CR_MTX);
527 imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
528 i2c_imx_bus_busy(i2c_imx, 0);
529 i2c_imx->stopped = 1;
530 } else {
531 /*
532 * For i2c master receiver repeat restart operation like:
533 * read -> repeat MSTA -> read/write
534 * The controller must set MTX before read the last byte in
535 * the first read operation, otherwise the first read cost
536 * one extra clock cycle.
537 */
538 temp = readb(i2c_imx->base + IMX_I2C_I2CR);
539 temp |= I2CR_MTX;
540 writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
541 }
527 } else if (i == (msgs->len - 2)) { 542 } else if (i == (msgs->len - 2)) {
528 dev_dbg(&i2c_imx->adapter.dev, 543 dev_dbg(&i2c_imx->adapter.dev,
529 "<%s> set TXAK\n", __func__); 544 "<%s> set TXAK\n", __func__);
@@ -547,6 +562,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
547{ 562{
548 unsigned int i, temp; 563 unsigned int i, temp;
549 int result; 564 int result;
565 bool is_lastmsg = false;
550 struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter); 566 struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);
551 567
552 dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); 568 dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
@@ -558,6 +574,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
558 574
559 /* read/write data */ 575 /* read/write data */
560 for (i = 0; i < num; i++) { 576 for (i = 0; i < num; i++) {
577 if (i == num - 1)
578 is_lastmsg = true;
579
561 if (i) { 580 if (i) {
562 dev_dbg(&i2c_imx->adapter.dev, 581 dev_dbg(&i2c_imx->adapter.dev,
563 "<%s> repeated start\n", __func__); 582 "<%s> repeated start\n", __func__);
@@ -588,7 +607,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
588 (temp & I2SR_RXAK ? 1 : 0)); 607 (temp & I2SR_RXAK ? 1 : 0));
589#endif 608#endif
590 if (msgs[i].flags & I2C_M_RD) 609 if (msgs[i].flags & I2C_M_RD)
591 result = i2c_imx_read(i2c_imx, &msgs[i]); 610 result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);
592 else 611 else
593 result = i2c_imx_write(i2c_imx, &msgs[i]); 612 result = i2c_imx_write(i2c_imx, &msgs[i]);
594 if (result) 613 if (result)