@@ -154,8 +154,39 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data)
154
154
return IRQ_NONE ;
155
155
}
156
156
157
+ /*
158
+ * Repeated Start Condition (Sr)
159
+ * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it
160
+ * talks about reading from a slave with 10 bit address. This is achieved by
161
+ * issuing a write (without enabling interrupts), poll the I2CS.TA flag and
162
+ * wait for it to be set, and then issue a read.
163
+ * https://github.com/raspberrypi/linux/issues/254 shows how the firmware does
164
+ * it and states that it's a workaround for a problem in the state machine.
165
+ * This is the comment in the firmware code:
166
+ *
167
+ * The I2C peripheral samples the values for rw_bit and xfer_count in the
168
+ * IDLE state if start is set.
169
+ *
170
+ * We want to generate a ReSTART not a STOP at the end of the TX phase. In
171
+ * order to do that we must ensure the state machine goes
172
+ * RACK1 -> RACK2 -> SRSTRT1 (not RACK1 -> RACK2 -> SSTOP1).
173
+ *
174
+ * So, in the RACK2 state when (TX) xfer_count==0 we must therefore have
175
+ * already set, ready to be sampled:
176
+ * READ; rw_bit <= I2CC bit 0 - must be "read"
177
+ * ST; start <= I2CC bit 7 - must be "Go" in order to not issue STOP
178
+ * DLEN; xfer_count <= I2CDLEN - must be equal to our read amount
179
+ *
180
+ * The plan to do this is:
181
+ * 1. Start the sub-address write, but don't let it finish (keep
182
+ * xfer_count > 0)
183
+ * 2. Populate READ, DLEN and ST in preparation for ReSTART read sequence
184
+ * 3. Let TX finish (write the rest of the data)
185
+ * 4. Read back data as it arrives
186
+ */
187
+
157
188
static int bcm2835_i2c_xfer_msg (struct bcm2835_i2c_dev * i2c_dev ,
158
- struct i2c_msg * msg )
189
+ struct i2c_msg * msg , struct i2c_msg * msg2 )
159
190
{
160
191
u32 c ;
161
192
unsigned long time_left ;
@@ -167,21 +198,70 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev,
167
198
168
199
bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_C , BCM2835_I2C_C_CLEAR );
169
200
170
- if (msg -> flags & I2C_M_RD ) {
171
- c = BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR ;
172
- } else {
173
- c = BCM2835_I2C_C_INTT ;
201
+ if (!(msg -> flags & I2C_M_RD ))
174
202
bcm2835_fill_txfifo (i2c_dev );
175
- }
176
- c |= BCM2835_I2C_C_ST | BCM2835_I2C_C_INTD | BCM2835_I2C_C_I2CEN ;
177
203
178
204
bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_A , msg -> addr );
179
205
bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_DLEN , msg -> len );
180
- bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_C , c );
206
+
207
+ if (!msg2 ) {
208
+ if (msg -> flags & I2C_M_RD )
209
+ c = BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR ;
210
+ else
211
+ c = BCM2835_I2C_C_INTT ;
212
+
213
+ c |= BCM2835_I2C_C_ST | BCM2835_I2C_C_INTD |
214
+ BCM2835_I2C_C_I2CEN ;
215
+ bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_C , c );
216
+ } else {
217
+ unsigned long flags ;
218
+ u32 stat , err = 0 ;
219
+
220
+ local_irq_save (flags );
221
+
222
+ /* Start write message */
223
+ c = BCM2835_I2C_C_ST | BCM2835_I2C_C_I2CEN ;
224
+ bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_C , c );
225
+
226
+ /* Wait for the transfer to become active */
227
+ for (time_left = 100 ; time_left > 0 ; time_left -- ) {
228
+ stat = bcm2835_i2c_readl (i2c_dev , BCM2835_I2C_S );
229
+
230
+ err = stat & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR );
231
+ if (err )
232
+ break ;
233
+
234
+ if (stat & BCM2835_I2C_S_TA )
235
+ break ;
236
+ }
237
+
238
+ if (err || !time_left ) {
239
+ i2c_dev -> msg_err = err ;
240
+ local_irq_restore (flags );
241
+ goto error ;
242
+ }
243
+
244
+ /* Start read message */
245
+ i2c_dev -> curr_msg = msg2 ;
246
+ i2c_dev -> msg_buf = msg2 -> buf ;
247
+ i2c_dev -> msg_buf_remaining = msg2 -> len ;
248
+ bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_DLEN , msg2 -> len );
249
+
250
+ c = BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR |
251
+ BCM2835_I2C_C_INTD | BCM2835_I2C_C_ST |
252
+ BCM2835_I2C_C_I2CEN ;
253
+
254
+ bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_C , c );
255
+
256
+ local_irq_restore (flags );
257
+ }
181
258
182
259
time_left = wait_for_completion_timeout (& i2c_dev -> completion ,
183
260
BCM2835_I2C_TIMEOUT );
261
+ error :
184
262
bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_C , BCM2835_I2C_C_CLEAR );
263
+ bcm2835_i2c_writel (i2c_dev , BCM2835_I2C_S , BCM2835_I2C_S_CLKT |
264
+ BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE );
185
265
if (!time_left ) {
186
266
dev_err (i2c_dev -> dev , "i2c transfer timed out\n" );
187
267
return - ETIMEDOUT ;
@@ -209,8 +289,17 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
209
289
int i ;
210
290
int ret = 0 ;
211
291
292
+ /* Combined write-read to the same address (smbus) */
293
+ if (num == 2 && (msgs [0 ].addr == msgs [1 ].addr ) &&
294
+ !(msgs [0 ].flags & I2C_M_RD ) && (msgs [1 ].flags & I2C_M_RD ) &&
295
+ (msgs [0 ].len <= 16 )) {
296
+ ret = bcm2835_i2c_xfer_msg (i2c_dev , & msgs [0 ], & msgs [1 ]);
297
+
298
+ return ret ? ret : 2 ;
299
+ }
300
+
212
301
for (i = 0 ; i < num ; i ++ ) {
213
- ret = bcm2835_i2c_xfer_msg (i2c_dev , & msgs [i ]);
302
+ ret = bcm2835_i2c_xfer_msg (i2c_dev , & msgs [i ], NULL );
214
303
if (ret )
215
304
break ;
216
305
}
0 commit comments