Skip to content

Commit 9f85577

Browse files
Akhil Rwsakernel
authored andcommitted
i2c: tegra: Fix PEC support for SMBUS block read
Update the msg->len value correctly for SMBUS block read. The discrepancy went unnoticed as msg->len is used in SMBUS transfers only when a PEC byte is added. Fixes: d7583c8 ("i2c: tegra: Add SMBus block read function") Signed-off-by: Akhil R <akhilrajeev@nvidia.com> Acked-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Wolfram Sang <wsa@kernel.org>
1 parent 825a071 commit 9f85577

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

drivers/i2c/busses/i2c-tegra.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,10 @@ struct tegra_i2c_hw_feature {
242242
* @is_dvc: identifies the DVC I2C controller, has a different register layout
243243
* @is_vi: identifies the VI I2C controller, has a different register layout
244244
* @msg_complete: transfer completion notifier
245+
* @msg_buf_remaining: size of unsent data in the message buffer
246+
* @msg_len: length of message in current transfer
245247
* @msg_err: error code for completed message
246248
* @msg_buf: pointer to current message data
247-
* @msg_buf_remaining: size of unsent data in the message buffer
248249
* @msg_read: indicates that the transfer is a read access
249250
* @timings: i2c timings information like bus frequency
250251
* @multimaster_mode: indicates that I2C controller is in multi-master mode
@@ -277,6 +278,7 @@ struct tegra_i2c_dev {
277278

278279
struct completion msg_complete;
279280
size_t msg_buf_remaining;
281+
unsigned int msg_len;
280282
int msg_err;
281283
u8 *msg_buf;
282284

@@ -1169,7 +1171,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
11691171
else
11701172
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
11711173

1172-
packet_header = msg->len - 1;
1174+
packet_header = i2c_dev->msg_len - 1;
11731175

11741176
if (i2c_dev->dma_mode && !i2c_dev->msg_read)
11751177
*dma_buf++ = packet_header;
@@ -1242,20 +1244,32 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12421244
return err;
12431245

12441246
i2c_dev->msg_buf = msg->buf;
1247+
i2c_dev->msg_len = msg->len;
12451248

1246-
/* The condition true implies smbus block read and len is already read */
1247-
if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE)
1248-
i2c_dev->msg_buf = msg->buf + 1;
1249-
1250-
i2c_dev->msg_buf_remaining = msg->len;
12511249
i2c_dev->msg_err = I2C_ERR_NONE;
12521250
i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
12531251
reinit_completion(&i2c_dev->msg_complete);
12541252

1253+
/*
1254+
* For SMBUS block read command, read only 1 byte in the first transfer.
1255+
* Adjust that 1 byte for the next transfer in the msg buffer and msg
1256+
* length.
1257+
*/
1258+
if (msg->flags & I2C_M_RECV_LEN) {
1259+
if (end_state == MSG_END_CONTINUE) {
1260+
i2c_dev->msg_len = 1;
1261+
} else {
1262+
i2c_dev->msg_buf += 1;
1263+
i2c_dev->msg_len -= 1;
1264+
}
1265+
}
1266+
1267+
i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
1268+
12551269
if (i2c_dev->msg_read)
1256-
xfer_size = msg->len;
1270+
xfer_size = i2c_dev->msg_len;
12571271
else
1258-
xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
1272+
xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
12591273

12601274
xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
12611275

@@ -1295,7 +1309,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12951309
if (!i2c_dev->msg_read) {
12961310
if (i2c_dev->dma_mode) {
12971311
memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
1298-
msg->buf, msg->len);
1312+
msg->buf, i2c_dev->msg_len);
12991313

13001314
dma_sync_single_for_device(i2c_dev->dma_dev,
13011315
i2c_dev->dma_phys,
@@ -1352,7 +1366,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
13521366
i2c_dev->dma_phys,
13531367
xfer_size, DMA_FROM_DEVICE);
13541368

1355-
memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len);
1369+
memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
13561370
}
13571371
}
13581372

@@ -1408,8 +1422,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
14081422
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
14091423
if (ret)
14101424
break;
1411-
/* Set the read byte as msg len */
1412-
msgs[i].len = msgs[i].buf[0];
1425+
/* Set the msg length from first byte */
1426+
msgs[i].len += msgs[i].buf[0];
14131427
dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
14141428
}
14151429
ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type);

0 commit comments

Comments
 (0)