diff mbox

[U-Boot,11/13] i2c: mvtwsi: Handle zero-length offsets properly

Message ID 20160718082802.10600-12-mario.six@gdsys.cc
State Accepted
Delegated to: Heiko Schocher
Headers show

Commit Message

Mario Six July 18, 2016, 8:28 a.m. UTC
Zero-length offsets are not properly handled by the driver. When a read
operation with a zero-length offset is started, a START condition is
asserted, and since no offset bytes are transferred, a repeated START is
issued immediately after, which confuses the controller.

To fix this, we send the first START only if any address bytes need to
be sent, and keep track of the expected start status accordingly.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---
 drivers/i2c/mvtwsi.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
diff mbox

Patch

diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index c81e9d4..11b5a5c 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -450,16 +450,21 @@  static int __twsi_i2c_read(struct mvtwsi_registers *twsi, uchar chip,
 {
 	int status = 0;
 	int stop_status;
-
-	/* Begin i2c write to send the address bytes */
-	status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1));
-	/* Send address bytes */
-	while ((status == 0) && alen--)
-		status = twsi_send(twsi, *(addr++), MVTWSI_STATUS_DATA_W_ACK);
+	int expected_start = MVTWSI_STATUS_START;
+
+	if (alen > 0) {
+		/* Begin i2c write to send the address bytes */
+		status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1));
+		/* Send address bytes */
+		while ((status == 0) && alen--)
+			status = twsi_send(twsi, *(addr++),
+					   MVTWSI_STATUS_DATA_W_ACK);
+		/* Send repeated STARTs after the initial START */
+		expected_start = MVTWSI_STATUS_REPEATED_START;
+	}
 	/* Begin i2c read to receive data bytes */
 	if (status == 0)
-		status = i2c_begin(twsi, MVTWSI_STATUS_REPEATED_START,
-				   (chip << 1) | 1);
+		status = i2c_begin(twsi, expected_start, (chip << 1) | 1, tick);
 	/* Receive actual data bytes; set NAK if we if we have nothing more to
 	 * read */
 	while ((status == 0) && length--)