@@ -149,7 +149,7 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
149
149
static inline void bcm2708_bsc_setup (struct bcm2708_i2c * bi )
150
150
{
151
151
unsigned long bus_hz ;
152
- u32 cdiv ;
152
+ u32 cdiv , s ;
153
153
u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1 ;
154
154
155
155
bus_hz = clk_get_rate (bi -> clk );
@@ -163,6 +163,30 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
163
163
bcm2708_wr (bi , BSC_DIV , cdiv );
164
164
bcm2708_wr (bi , BSC_A , bi -> msg -> addr );
165
165
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
+ }
166
190
bcm2708_wr (bi , BSC_C , c );
167
191
}
168
192
0 commit comments