Просмотр исходного кода

[i2c] Generalise i2c bit-bashing support to addressless devices

Some devices (e.g. the Atmel AT24C11) have no concept of a device
address; they respond to every device address and use this value as
the word address.  Some other devices use part of the device address
field to extend the word address field.

Generalise the i2c bit-bashing support to handle this by defining the
device address length and word address length as properties of an i2c
device.  The word address is assumed to overflow into the device
address field if the address used exceeds the width of the word
address field.

Also add a bus reset mechanism.  i2c chips don't usually have a reset
line, so rebooting the host will not clear any bizarre state that the
chip may be in.  We reset the bus by clocking SCL until we see SDA
high, at which point we know we can generate a start condition and
have it seen by all devices.  We then generate a stop condition to
leave the bus in a known state prior to use.

Finally, add some extra debugging messages to i2c_bit.c.
tags/v0.9.6
Michael Brown 15 лет назад
Родитель
Сommit
9dccbc0af2
3 измененных файлов: 174 добавлений и 47 удалений
  1. 108
    39
      src/drivers/bitbash/i2c_bit.c
  2. 3
    3
      src/drivers/net/etherfabric.c
  3. 63
    5
      src/include/gpxe/i2c.h

+ 108
- 39
src/drivers/bitbash/i2c_bit.c Просмотреть файл

19
 #include <stddef.h>
19
 #include <stddef.h>
20
 #include <stdint.h>
20
 #include <stdint.h>
21
 #include <errno.h>
21
 #include <errno.h>
22
+#include <string.h>
22
 #include <assert.h>
23
 #include <assert.h>
23
 #include <unistd.h>
24
 #include <unistd.h>
24
 #include <gpxe/bitbash.h>
25
 #include <gpxe/bitbash.h>
49
  * @v state		New state of SCL
50
  * @v state		New state of SCL
50
  */
51
  */
51
 static void setscl ( struct bit_basher *basher, int state ) {
52
 static void setscl ( struct bit_basher *basher, int state ) {
53
+	DBG2 ( "%c", ( state ? '/' : '\\' ) );
52
 	write_bit ( basher, I2C_BIT_SCL, state );
54
 	write_bit ( basher, I2C_BIT_SCL, state );
53
 	i2c_delay();
55
 	i2c_delay();
54
 }
56
 }
60
  * @v state		New state of SDA
62
  * @v state		New state of SDA
61
  */
63
  */
62
 static void setsda ( struct bit_basher *basher, int state ) {
64
 static void setsda ( struct bit_basher *basher, int state ) {
65
+	DBG2 ( "%c", ( state ? '1' : '0' ) );
63
 	write_bit ( basher, I2C_BIT_SDA, state );
66
 	write_bit ( basher, I2C_BIT_SDA, state );
64
 	i2c_delay();
67
 	i2c_delay();
65
 }
68
 }
71
  * @ret state		State of SDA
74
  * @ret state		State of SDA
72
  */
75
  */
73
 static int getsda ( struct bit_basher *basher ) {
76
 static int getsda ( struct bit_basher *basher ) {
74
-	return read_bit ( basher, I2C_BIT_SDA );
77
+	int state;
78
+	state = read_bit ( basher, I2C_BIT_SDA );
79
+	DBG2 ( "%c", ( state ? '+' : '-' ) );
80
+	return state;
75
 }
81
 }
76
 
82
 
77
 /**
83
 /**
137
  */
143
  */
138
 static int i2c_send_byte ( struct bit_basher *basher, uint8_t byte ) {
144
 static int i2c_send_byte ( struct bit_basher *basher, uint8_t byte ) {
139
 	int i;
145
 	int i;
140
-	
146
+	int ack;
147
+
141
 	/* Send byte */
148
 	/* Send byte */
149
+	DBG2 ( "[send %02x]", byte );
142
 	for ( i = 8 ; i ; i-- ) {
150
 	for ( i = 8 ; i ; i-- ) {
143
 		i2c_send_bit ( basher, byte & 0x80 );
151
 		i2c_send_bit ( basher, byte & 0x80 );
144
 		byte <<= 1;
152
 		byte <<= 1;
145
 	}
153
 	}
146
 
154
 
147
 	/* Check for acknowledgement from slave */
155
 	/* Check for acknowledgement from slave */
148
-	return ( i2c_recv_bit ( basher ) == 0 ? 0 : -EIO );
156
+	ack = ( i2c_recv_bit ( basher ) == 0 );
157
+	DBG2 ( "%s", ( ack ? "[acked]" : "[not acked]" ) );
158
+
159
+	return ( ack ? 0 : -EIO );
149
 }
160
 }
150
 
161
 
151
 /**
162
 /**
157
  * Receives a byte via the I2C bus and sends NACK to the slave device.
168
  * Receives a byte via the I2C bus and sends NACK to the slave device.
158
  */
169
  */
159
 static uint8_t i2c_recv_byte ( struct bit_basher *basher ) {
170
 static uint8_t i2c_recv_byte ( struct bit_basher *basher ) {
160
-	uint8_t value = 0;
171
+	uint8_t byte = 0;
161
 	int i;
172
 	int i;
162
 
173
 
163
 	/* Receive byte */
174
 	/* Receive byte */
164
 	for ( i = 8 ; i ; i-- ) {
175
 	for ( i = 8 ; i ; i-- ) {
165
-		value <<= 1;
166
-		value |= ( i2c_recv_bit ( basher ) & 0x1 );
176
+		byte <<= 1;
177
+		byte |= ( i2c_recv_bit ( basher ) & 0x1 );
167
 	}
178
 	}
168
 
179
 
169
 	/* Send NACK */
180
 	/* Send NACK */
170
 	i2c_send_bit ( basher, 1 );
181
 	i2c_send_bit ( basher, 1 );
171
 
182
 
172
-	return value;
183
+	DBG2 ( "[rcvd %02x]", byte );
184
+	return byte;
173
 }
185
 }
174
 
186
 
175
 /**
187
 /**
177
  *
189
  *
178
  * @v basher		Bit-bashing interface
190
  * @v basher		Bit-bashing interface
179
  * @v i2cdev		I2C device
191
  * @v i2cdev		I2C device
192
+ * @v offset		Starting offset within the device
180
  * @v direction		I2C_READ or I2C_WRITE
193
  * @v direction		I2C_READ or I2C_WRITE
181
  * @ret rc		Return status code
194
  * @ret rc		Return status code
182
  */
195
  */
183
 static int i2c_select ( struct bit_basher *basher, struct i2c_device *i2cdev,
196
 static int i2c_select ( struct bit_basher *basher, struct i2c_device *i2cdev,
184
-			unsigned int direction ) {
197
+			unsigned int offset, unsigned int direction ) {
185
 	unsigned int address;
198
 	unsigned int address;
199
+	int shift;
200
+	unsigned int byte;
186
 	int rc;
201
 	int rc;
187
 
202
 
188
 	i2c_start ( basher );
203
 	i2c_start ( basher );
189
 
204
 
190
-	/* First byte of the address */
191
-	address = i2cdev->address;
192
-	if ( i2cdev->tenbit ) {
193
-		address |= I2C_TENBIT_ADDRESS;
194
-		address >>= 8;
195
-	}
196
-	if ( ( rc = i2c_send_byte ( basher, 
197
-				    ( ( address << 1 ) | direction ) ) ) != 0 )
198
-		return rc;
205
+	/* Calculate address to appear on bus */
206
+	address = ( ( ( i2cdev->dev_addr |
207
+			( offset >> ( 8 * i2cdev->word_addr_len ) ) ) << 1 )
208
+		    | direction );
199
 
209
 
200
-	/* Second byte of the address (10-bit addresses only) */
201
-	if ( i2cdev->tenbit ) {
202
-		if ( ( rc = i2c_send_byte ( basher,
203
-					    ( i2cdev->address & 0xff ) ) ) !=0)
210
+	/* Send address a byte at a time */
211
+	for ( shift = ( 8 * ( i2cdev->dev_addr_len - 1 ) ) ;
212
+	      shift >= 0 ; shift -= 8 ) {
213
+		byte = ( ( address >> shift ) & 0xff );
214
+		if ( ( rc = i2c_send_byte ( basher, byte ) ) != 0 )
204
 			return rc;
215
 			return rc;
205
 	}
216
 	}
206
 
217
 
207
 	return 0;
218
 	return 0;
208
 }
219
 }
209
 
220
 
221
+/**
222
+ * Reset I2C bus
223
+ *
224
+ * @v basher		Bit-bashing interface
225
+ * @ret rc		Return status code
226
+ *
227
+ * i2c devices often don't have a reset line, so even a reboot or
228
+ * system power cycle is sometimes not enough to bring them back to a
229
+ * known state.
230
+ */
231
+static int i2c_reset ( struct bit_basher *basher ) {
232
+	unsigned int i;
233
+	int sda;
234
+
235
+	/* Clock through several cycles, waiting for an opportunity to
236
+	 * pull SDA low while SCL is high (which creates a start
237
+	 * condition).
238
+	 */
239
+	setscl ( basher, 0 );
240
+	setsda ( basher, 1 );
241
+	for ( i = 0 ; i < I2C_RESET_MAX_CYCLES ; i++ ) {
242
+		setscl ( basher, 1 );
243
+		sda = getsda ( basher );
244
+		if ( sda ) {
245
+			/* Now that the device will see a start, issue it */
246
+			i2c_start ( basher );
247
+			/* Stop the bus to leave it in a known good state */
248
+			i2c_stop ( basher );
249
+			DBGC ( basher, "I2CBIT %p reset after %d attempts\n",
250
+			       basher, ( i + 1 ) );
251
+			return 0;
252
+		}
253
+		setscl ( basher, 0 );
254
+	}
255
+
256
+	DBGC ( basher, "I2CBIT %p could not reset after %d attempts\n",
257
+	       basher, i );
258
+	return -ETIMEDOUT;
259
+}
260
+
210
 /**
261
 /**
211
  * Read data from I2C device via bit-bashing interface
262
  * Read data from I2C device via bit-bashing interface
212
  *
263
  *
228
 	struct bit_basher *basher = &i2cbit->basher;
279
 	struct bit_basher *basher = &i2cbit->basher;
229
 	int rc = 0;
280
 	int rc = 0;
230
 
281
 
231
-	DBG ( "Reading from I2C device %x: ", i2cdev->address );
282
+	DBGC ( basher, "I2CBIT %p reading from device %x: ",
283
+	       basher, i2cdev->dev_addr );
232
 
284
 
233
-	while ( 1 ) {
285
+	for ( ; ; data++, offset++ ) {
234
 
286
 
235
 		/* Select device for writing */
287
 		/* Select device for writing */
236
-		if ( ( rc = i2c_select ( basher, i2cdev, I2C_WRITE ) ) != 0 )
288
+		if ( ( rc = i2c_select ( basher, i2cdev, offset,
289
+					 I2C_WRITE ) ) != 0 )
237
 			break;
290
 			break;
238
 
291
 
239
 		/* Abort at end of data */
292
 		/* Abort at end of data */
241
 			break;
294
 			break;
242
 
295
 
243
 		/* Select offset */
296
 		/* Select offset */
244
-		if ( ( rc = i2c_send_byte ( basher, offset++ ) ) != 0 )
297
+		if ( ( rc = i2c_send_byte ( basher, offset ) ) != 0 )
245
 			break;
298
 			break;
246
 		
299
 		
247
 		/* Select device for reading */
300
 		/* Select device for reading */
248
-		if ( ( rc = i2c_select ( basher, i2cdev, I2C_READ ) ) != 0 )
301
+		if ( ( rc = i2c_select ( basher, i2cdev, offset,
302
+					 I2C_READ ) ) != 0 )
249
 			break;
303
 			break;
250
 
304
 
251
 		/* Read byte */
305
 		/* Read byte */
252
-		*data++ = i2c_recv_byte ( basher );
253
-		DBG ( "%02x ", *(data - 1) );
306
+		*data = i2c_recv_byte ( basher );
307
+		DBGC ( basher, "%02x ", *data );
254
 	}
308
 	}
255
 	
309
 	
256
-	DBG ( "%s\n", ( rc ? "failed" : "" ) );
310
+	DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) );
257
 	i2c_stop ( basher );
311
 	i2c_stop ( basher );
258
 	return rc;
312
 	return rc;
259
 }
313
 }
279
 	struct bit_basher *basher = &i2cbit->basher;
333
 	struct bit_basher *basher = &i2cbit->basher;
280
 	int rc = 0;
334
 	int rc = 0;
281
 
335
 
282
-	DBG ( "Writing to I2C device %x: ", i2cdev->address );
336
+	DBGC ( basher, "I2CBIT %p writing to device %x: ",
337
+	       basher, i2cdev->dev_addr );
283
 
338
 
284
-	while ( 1 ) {
339
+	for ( ; ; data++, offset++ ) {
285
 
340
 
286
 		/* Select device for writing */
341
 		/* Select device for writing */
287
-		if ( ( rc = i2c_select ( basher, i2cdev, I2C_WRITE ) ) != 0 )
342
+		if ( ( rc = i2c_select ( basher, i2cdev, offset,
343
+					 I2C_WRITE ) ) != 0 )
288
 			break;
344
 			break;
289
 		
345
 		
290
 		/* Abort at end of data */
346
 		/* Abort at end of data */
292
 			break;
348
 			break;
293
 
349
 
294
 		/* Select offset */
350
 		/* Select offset */
295
-		if ( ( rc = i2c_send_byte ( basher, offset++ ) ) != 0 )
351
+		if ( ( rc = i2c_send_byte ( basher, offset ) ) != 0 )
296
 			break;
352
 			break;
297
 		
353
 		
298
 		/* Write data to device */
354
 		/* Write data to device */
299
-		DBG ( "%02x ", *data );
300
-		if ( ( rc = i2c_send_byte ( basher, *data++ ) ) != 0 )
355
+		DBGC ( basher, "%02x ", *data );
356
+		if ( ( rc = i2c_send_byte ( basher, *data ) ) != 0 )
301
 			break;
357
 			break;
302
 	}
358
 	}
303
 	
359
 	
304
-	DBG ( "%s\n", ( rc ? "failed" : "" ) );
360
+	DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) );
305
 	i2c_stop ( basher );
361
 	i2c_stop ( basher );
306
 	return rc;
362
 	return rc;
307
 }
363
 }
310
  * Initialise I2C bit-bashing interface
366
  * Initialise I2C bit-bashing interface
311
  *
367
  *
312
  * @v i2cbit		I2C bit-bashing interface
368
  * @v i2cbit		I2C bit-bashing interface
369
+ * @v bash_op		Bit-basher operations
313
  */
370
  */
314
-void init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit ) {
371
+int init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit,
372
+			  struct bit_basher_operations *bash_op ) {
315
 	struct bit_basher *basher = &i2cbit->basher;
373
 	struct bit_basher *basher = &i2cbit->basher;
316
-	
374
+	int rc;
375
+
376
+	/* Initialise data structures */
377
+	basher->op = bash_op;
317
 	assert ( basher->op->read != NULL );
378
 	assert ( basher->op->read != NULL );
318
 	assert ( basher->op->write != NULL );
379
 	assert ( basher->op->write != NULL );
319
 	i2cbit->i2c.read = i2c_bit_read;
380
 	i2cbit->i2c.read = i2c_bit_read;
320
 	i2cbit->i2c.write = i2c_bit_write;
381
 	i2cbit->i2c.write = i2c_bit_write;
321
-	i2c_stop ( basher );
382
+
383
+	/* Reset I2C bus */
384
+	if ( ( rc = i2c_reset ( basher ) ) != 0 ) {
385
+		DBGC ( basher, "I2CBIT %p could not reset I2C bus: %s\n",
386
+		       basher, strerror ( rc ) );
387
+		return rc;
388
+	}
389
+
390
+	return 0;
322
 }
391
 }

+ 3
- 3
src/drivers/net/etherfabric.c Просмотреть файл

1069
 };
1069
 };
1070
 
1070
 
1071
 static void ef1002_init_eeprom ( struct efab_nic *efab ) {
1071
 static void ef1002_init_eeprom ( struct efab_nic *efab ) {
1072
-	efab->ef1002_i2c.basher.op = &ef1002_basher_ops;
1073
-	init_i2c_bit_basher ( &efab->ef1002_i2c );
1074
-	efab->ef1002_eeprom.address = EF1_EEPROM_I2C_ID;
1072
+	init_i2c_bit_basher ( &efab->ef1002_i2c,
1073
+			      &ef1002_basher_ops );
1074
+	init_i2c_eeprom ( &efab->ef1002_eeprom, EF1_EEPROM_I2C_ID );
1075
 }
1075
 }
1076
 
1076
 
1077
 /**
1077
 /**

+ 63
- 5
src/include/gpxe/i2c.h Просмотреть файл

8
  */
8
  */
9
 
9
 
10
 #include <stdint.h>
10
 #include <stdint.h>
11
+#include <gpxe/bitbash.h>
11
 
12
 
12
 /** An I2C device
13
 /** An I2C device
13
  *
14
  *
15
  * is accessed via an I2C interface.
16
  * is accessed via an I2C interface.
16
  */
17
  */
17
 struct i2c_device {
18
 struct i2c_device {
18
-	/** Address of this device */
19
-	unsigned int address;
20
-	/** Flag indicating a ten-bit address format */
21
-	int tenbit;
19
+	/** Address of this device
20
+	 *
21
+	 * The actual address sent on the bus will look like
22
+	 *
23
+	 *    <start> <device address> <word address overflow> <r/w>
24
+	 *
25
+	 * The "word address overflow" is any excess bits from the
26
+	 * word address, i.e. any portion that does not fit within the
27
+	 * defined word address length.
28
+	 */
29
+	unsigned int dev_addr;
30
+	/** Device address length, in bytes
31
+	 *
32
+	 * This is the number of bytes that comprise the device
33
+	 * address, defined to be the portion that terminates with the
34
+	 * read/write bit.
35
+	 */
36
+	unsigned int dev_addr_len;
37
+	/** Word adddress length, in bytes
38
+	 *
39
+	 * This is the number of bytes that comprise the word address,
40
+	 * defined to be the portion that starts after the read/write
41
+	 * bit and ends before the first data byte.
42
+	 *
43
+	 * For some devices, this length will be zero (i.e. the word
44
+	 * address is contained entirely within the "word address
45
+	 * overflow").
46
+	 */
47
+	unsigned int word_addr_len;
22
 };
48
 };
23
 
49
 
24
 /** An I2C interface
50
 /** An I2C interface
91
 /** Delay required for bit-bashing operation */
117
 /** Delay required for bit-bashing operation */
92
 #define I2C_UDELAY 5
118
 #define I2C_UDELAY 5
93
 
119
 
120
+/** Maximum number of cycles to use when attempting a bus reset */
121
+#define I2C_RESET_MAX_CYCLES 32
122
+
94
 /**
123
 /**
95
  * Check presence of I2C device
124
  * Check presence of I2C device
96
  *
125
  *
106
 	return i2c->write ( i2c, i2cdev, 0, NULL, 0 );
135
 	return i2c->write ( i2c, i2cdev, 0, NULL, 0 );
107
 }
136
 }
108
 
137
 
109
-extern void init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit );
138
+extern int init_i2c_bit_basher ( struct i2c_bit_basher *i2cbit,
139
+				 struct bit_basher_operations *bash_op );
140
+
141
+/**
142
+ * Initialise generic I2C EEPROM device
143
+ *
144
+ * @v i2cdev		I2C device
145
+ */
146
+static inline __always_inline void
147
+init_i2c_eeprom ( struct i2c_device *i2cdev, unsigned int dev_addr ) {
148
+	i2cdev->dev_addr = dev_addr;
149
+	i2cdev->dev_addr_len = 1;
150
+	i2cdev->word_addr_len = 1;
151
+}
152
+
153
+/**
154
+ * Initialise Atmel AT24C11
155
+ *
156
+ * @v i2cdev		I2C device
157
+ */
158
+static inline __always_inline void
159
+init_at24c11 ( struct i2c_device *i2cdev ) {
160
+	/* This chip has no device address; it must be the only chip
161
+	 * on the bus.  The word address is contained entirely within
162
+	 * the device address field.
163
+	 */
164
+	i2cdev->dev_addr = 0;
165
+	i2cdev->dev_addr_len = 1;
166
+	i2cdev->word_addr_len = 0;
167
+}
110
 
168
 
111
 #endif /* _GPXE_I2C_H */
169
 #endif /* _GPXE_I2C_H */

Загрузка…
Отмена
Сохранить