diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-imx.c | 41 |
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 | ||
461 | static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) | 461 | static 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) |