summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authormario.six@gdsys.cc <mario.six@gdsys.cc>2016-07-21 11:57:11 +0200
committerHeiko Schocher <hs@denx.de>2016-07-26 10:20:19 +0200
commit24f9c6bbc7d5e5e276dea32a81ade71f0e6b56ae (patch)
tree4c4b2f5ed0b474e3641be7d5979277c4df5e2f6a /drivers/i2c
parent14a6ff2c4f22010e5d67f25508f09e3b53a1f1c4 (diff)
i2c: mvtwsi: Handle zero-length offsets properly
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> Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/mvtwsi.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index f694527ec6..8552fba7b6 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -449,16 +449,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, expected_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);
/* Receive actual data bytes; set NAK if we if we have nothing more to
* read */
while ((status == 0) && length--)