Skip to content

Commit 7ca20a9

Browse files
committed
Merge pull request #318 from cbeytas/rpi-3.6.y
Perform I2C combined transactions when possible
2 parents 2a8d45e + e1d60dd commit 7ca20a9

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

drivers/i2c/busses/i2c-bcm2708.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
149149
static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
150150
{
151151
unsigned long bus_hz;
152-
u32 cdiv;
152+
u32 cdiv, s;
153153
u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
154154

155155
bus_hz = clk_get_rate(bi->clk);
@@ -163,6 +163,30 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
163163
bcm2708_wr(bi, BSC_DIV, cdiv);
164164
bcm2708_wr(bi, BSC_A, bi->msg->addr);
165165
bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
166+
/* Do the next two messages meet combined transaction criteria?
167+
- Current message is a write, next message is a read
168+
- Both messages to same slave address
169+
- Write message can fit inside FIFO (16 bytes or less) */
170+
if ( (bi->nmsgs > 1) &&
171+
!(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
172+
(bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
173+
/* Clear FIFO and fill with entire write message */
174+
bcm2708_wr(bi, BSC_C, BSC_C_CLEAR_1);
175+
while (bi->pos < bi->msg->len)
176+
bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
177+
/* Start write transfer (no interrupts) */
178+
bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);
179+
/* poll for transfer start bit (should only take 1-60 polls) */
180+
do {
181+
s = bcm2708_rd(bi, BSC_S);
182+
} while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)));
183+
/* Send next read message before the write transfer finishes. */
184+
bi->nmsgs--;
185+
bi->msg++;
186+
bi->pos = 0;
187+
bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
188+
c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
189+
}
166190
bcm2708_wr(bi, BSC_C, c);
167191
}
168192

0 commit comments

Comments
 (0)