summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0496-Fixes-i2c_bcm2708-Write-to-FIFO-correctly-v2-1574.patch
blob: da46d86f09b8b1f02415e2d92308021b96590d24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
From 1b6ee2ac8f1d55cb7ceeaa606e3d4868cfde363d Mon Sep 17 00:00:00 2001
From: Simon Maes <simonn.maes@gmail.com>
Date: Mon, 29 Aug 2016 21:11:01 +0200
Subject: [PATCH] Fixes i2c_bcm2708: Write to FIFO correctly - v2 (#1574)

* i2c: fix i2c_bcm2708: Clear FIFO before sending data

Make sure FIFO gets cleared before trying to send
data in case of a repeated start (COMBINED=Y).

* i2c: fix i2c_bcm2708: Only write to FIFO when not full

Check if FIFO can accept data before writing.
To avoid a peripheral read on the last iteration of a loop,
both bcm2708_bsc_fifo_fill and ~drain are changed as well.
---
 drivers/i2c/busses/i2c-bcm2708.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/i2c/busses/i2c-bcm2708.c
+++ b/drivers/i2c/busses/i2c-bcm2708.c
@@ -115,13 +115,13 @@ static inline void bcm2708_bsc_reset(str
 
 static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi)
 {
-	while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len))
+	while ((bi->pos < bi->msg->len) && (bcm2708_rd(bi, BSC_S) & BSC_S_RXD))
 		bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO);
 }
 
 static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
 {
-	while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len))
+	while ((bi->pos < bi->msg->len) && (bcm2708_rd(bi, BSC_S) & BSC_S_TXD))
 		bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
 }
 
@@ -155,6 +155,10 @@ static inline int bcm2708_bsc_setup(stru
 		if ( (bi->nmsgs > 1) &&
 			!(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
 			 (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
+
+			/* Clear FIFO */
+			bcm2708_wr(bi, BSC_C, BSC_C_CLEAR_1);
+
 			/* Fill FIFO with entire write message (16 byte FIFO) */
 			while (bi->pos < bi->msg->len) {
 				bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);