iPXE
i2c_bit.c File Reference

I2C bit-bashing interface. More...

#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <ipxe/bitbash.h>
#include <ipxe/i2c.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void i2c_delay (void)
 Delay between output state changes.
static void setscl (struct bit_basher *basher, int state)
 Set state of I2C SCL line.
static void setsda (struct bit_basher *basher, int state)
 Set state of I2C SDA line.
static int getsda (struct bit_basher *basher)
 Get state of I2C SDA line.
static void i2c_start (struct bit_basher *basher)
 Send an I2C start condition.
static void i2c_send_bit (struct bit_basher *basher, int bit)
 Send an I2C data bit.
static int i2c_recv_bit (struct bit_basher *basher)
 Receive an I2C data bit.
static void i2c_stop (struct bit_basher *basher)
 Send an I2C stop condition.
static int i2c_send_byte (struct bit_basher *basher, uint8_t byte)
 Send byte via I2C bus and check for acknowledgement.
static uint8_t i2c_recv_byte (struct bit_basher *basher)
 Receive byte via I2C bus.
static int i2c_select (struct bit_basher *basher, struct i2c_device *i2cdev, unsigned int offset, unsigned int direction)
 Select I2C device for reading or writing.
static int i2c_reset (struct bit_basher *basher)
 Reset I2C bus.
static int i2c_bit_read (struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, uint8_t *data, unsigned int len)
 Read data from I2C device via bit-bashing interface.
static int i2c_bit_write (struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, const uint8_t *data, unsigned int len)
 Write data to I2C device via bit-bashing interface.
int init_i2c_bit_basher (struct i2c_bit_basher *i2cbit, struct bit_basher_operations *bash_op)
 Initialise I2C bit-bashing interface.

Detailed Description

I2C bit-bashing interface.

This implements a simple I2C master via a bit-bashing interface that provides two lines: SCL (clock) and SDA (data).

Definition in file i2c_bit.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ i2c_delay()

void i2c_delay ( void )
static

Delay between output state changes.

Max rated i2c speed (for the basic i2c protocol) is 100kbps, i.e. 200k clock transitions per second.

Definition at line 49 of file i2c_bit.c.

49 {
51}
#define I2C_UDELAY
Delay required for bit-bashing operation.
Definition i2c.h:120
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61

References I2C_UDELAY, and udelay().

Referenced by setscl(), and setsda().

◆ setscl()

void setscl ( struct bit_basher * basher,
int state )
static

Set state of I2C SCL line.

Parameters
basherBit-bashing interface
stateNew state of SCL

Definition at line 59 of file i2c_bit.c.

59 {
60 DBG2 ( "%c", ( state ? '/' : '\\' ) );
61 write_bit ( basher, I2C_BIT_SCL, state );
62 i2c_delay();
63}
void write_bit(struct bit_basher *basher, unsigned int bit_id, unsigned long data)
Set/clear output bit.
Definition bitbash.c:45
uint8_t state
State.
Definition eth_slow.h:36
#define DBG2(...)
Definition compiler.h:515
@ I2C_BIT_SCL
Serial clock.
Definition i2c.h:114
static void i2c_delay(void)
Delay between output state changes.
Definition i2c_bit.c:49

References DBG2, I2C_BIT_SCL, i2c_delay(), state, and write_bit().

Referenced by i2c_recv_bit(), i2c_reset(), i2c_send_bit(), i2c_start(), and i2c_stop().

◆ setsda()

void setsda ( struct bit_basher * basher,
int state )
static

Set state of I2C SDA line.

Parameters
basherBit-bashing interface
stateNew state of SDA

Definition at line 71 of file i2c_bit.c.

71 {
72 DBG2 ( "%c", ( state ? '1' : '0' ) );
73 write_bit ( basher, I2C_BIT_SDA, state );
74 i2c_delay();
75}
@ I2C_BIT_SDA
Serial data.
Definition i2c.h:116

References DBG2, I2C_BIT_SDA, i2c_delay(), state, and write_bit().

Referenced by i2c_reset(), i2c_send_bit(), i2c_start(), and i2c_stop().

◆ getsda()

int getsda ( struct bit_basher * basher)
static

Get state of I2C SDA line.

Parameters
basherBit-bashing interface
Return values
stateState of SDA

Definition at line 83 of file i2c_bit.c.

83 {
84 int state;
85 state = read_bit ( basher, I2C_BIT_SDA );
86 DBG2 ( "%c", ( state ? '+' : '-' ) );
87 return state;
88}
int read_bit(struct bit_basher *basher, unsigned int bit_id)
Read input bit.
Definition bitbash.c:61

References DBG2, I2C_BIT_SDA, read_bit(), and state.

Referenced by i2c_recv_bit(), and i2c_reset().

◆ i2c_start()

void i2c_start ( struct bit_basher * basher)
static

Send an I2C start condition.

Parameters
basherBit-bashing interface

Definition at line 95 of file i2c_bit.c.

95 {
96 setscl ( basher, 1 );
97 setsda ( basher, 0 );
98 setscl ( basher, 0 );
99 setsda ( basher, 1 );
100}
static void setsda(struct bit_basher *basher, int state)
Set state of I2C SDA line.
Definition i2c_bit.c:71
static void setscl(struct bit_basher *basher, int state)
Set state of I2C SCL line.
Definition i2c_bit.c:59

References setscl(), and setsda().

Referenced by i2c_reset(), and i2c_select().

◆ i2c_send_bit()

void i2c_send_bit ( struct bit_basher * basher,
int bit )
static

Send an I2C data bit.

Parameters
basherBit-bashing interface
bitBit to send

Definition at line 108 of file i2c_bit.c.

108 {
109 setsda ( basher, bit );
110 setscl ( basher, 1 );
111 setscl ( basher, 0 );
112 setsda ( basher, 1 );
113}
static unsigned int unsigned int bit
Definition bigint.h:392

References bit, setscl(), and setsda().

Referenced by i2c_recv_byte(), and i2c_send_byte().

◆ i2c_recv_bit()

int i2c_recv_bit ( struct bit_basher * basher)
static

Receive an I2C data bit.

Parameters
basherBit-bashing interface
Return values
bitReceived bit

Definition at line 121 of file i2c_bit.c.

121 {
122 int bit;
123
124 setscl ( basher, 1 );
125 bit = getsda ( basher );
126 setscl ( basher, 0 );
127 return bit;
128}
static int getsda(struct bit_basher *basher)
Get state of I2C SDA line.
Definition i2c_bit.c:83

References bit, getsda(), and setscl().

Referenced by i2c_recv_byte(), and i2c_send_byte().

◆ i2c_stop()

void i2c_stop ( struct bit_basher * basher)
static

Send an I2C stop condition.

Parameters
basherBit-bashing interface

Definition at line 135 of file i2c_bit.c.

135 {
136 setsda ( basher, 0 );
137 setscl ( basher, 1 );
138 setsda ( basher, 1 );
139}

References setscl(), and setsda().

Referenced by i2c_bit_read(), i2c_bit_write(), and i2c_reset().

◆ i2c_send_byte()

int i2c_send_byte ( struct bit_basher * basher,
uint8_t byte )
static

Send byte via I2C bus and check for acknowledgement.

Parameters
basherBit-bashing interface
byteByte to send
Return values
rcReturn status code

Sends a byte via the I2C bus and checks for an acknowledgement from the slave device.

Definition at line 151 of file i2c_bit.c.

151 {
152 int i;
153 int ack;
154
155 /* Send byte */
156 DBG2 ( "[send %02x]", byte );
157 for ( i = 8 ; i ; i-- ) {
158 i2c_send_bit ( basher, byte & 0x80 );
159 byte <<= 1;
160 }
161
162 /* Check for acknowledgement from slave */
163 ack = ( i2c_recv_bit ( basher ) == 0 );
164 DBG2 ( "%s", ( ack ? "[acked]" : "[not acked]" ) );
165
166 return ( ack ? 0 : -EIO );
167}
#define EIO
Input/output error.
Definition errno.h:434
static void i2c_send_bit(struct bit_basher *basher, int bit)
Send an I2C data bit.
Definition i2c_bit.c:108
static int i2c_recv_bit(struct bit_basher *basher)
Receive an I2C data bit.
Definition i2c_bit.c:121

References DBG2, EIO, i2c_recv_bit(), and i2c_send_bit().

Referenced by i2c_bit_read(), i2c_bit_write(), and i2c_select().

◆ i2c_recv_byte()

uint8_t i2c_recv_byte ( struct bit_basher * basher)
static

Receive byte via I2C bus.

Parameters
basherBit-bashing interface
Return values
byteReceived byte

Receives a byte via the I2C bus and sends NACK to the slave device.

Definition at line 177 of file i2c_bit.c.

177 {
178 uint8_t byte = 0;
179 int i;
180
181 /* Receive byte */
182 for ( i = 8 ; i ; i-- ) {
183 byte <<= 1;
184 byte |= ( i2c_recv_bit ( basher ) & 0x1 );
185 }
186
187 /* Send NACK */
188 i2c_send_bit ( basher, 1 );
189
190 DBG2 ( "[rcvd %02x]", byte );
191 return byte;
192}
unsigned char uint8_t
Definition stdint.h:10
unsigned char byte
Definition smc9000.h:38

References DBG2, i2c_recv_bit(), and i2c_send_bit().

Referenced by i2c_bit_read().

◆ i2c_select()

int i2c_select ( struct bit_basher * basher,
struct i2c_device * i2cdev,
unsigned int offset,
unsigned int direction )
static

Select I2C device for reading or writing.

Parameters
basherBit-bashing interface
i2cdevI2C device
offsetStarting offset within the device
directionI2C_READ or I2C_WRITE
Return values
rcReturn status code

Definition at line 203 of file i2c_bit.c.

204 {
205 unsigned int address;
206 int shift;
207 unsigned int byte;
208 int rc;
209
210 i2c_start ( basher );
211
212 /* Calculate address to appear on bus */
213 address = ( ( ( i2cdev->dev_addr |
214 ( offset >> ( 8 * i2cdev->word_addr_len ) ) ) << 1 )
215 | direction );
216
217 /* Send address a byte at a time */
218 for ( shift = ( 8 * ( i2cdev->dev_addr_len - 1 ) ) ;
219 shift >= 0 ; shift -= 8 ) {
220 byte = ( ( address >> shift ) & 0xff );
221 if ( ( rc = i2c_send_byte ( basher, byte ) ) != 0 )
222 return rc;
223 }
224
225 return 0;
226}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint8_t direction
Direction.
Definition ena.h:3
uint64_t address
Base address.
Definition ena.h:13
static int i2c_send_byte(struct bit_basher *basher, uint8_t byte)
Send byte via I2C bus and check for acknowledgement.
Definition i2c_bit.c:151
static void i2c_start(struct bit_basher *basher)
Send an I2C start condition.
Definition i2c_bit.c:95
unsigned int dev_addr
Address of this device.
Definition i2c.h:31
unsigned int word_addr_len
Word adddress length, in bytes.
Definition i2c.h:49
unsigned int dev_addr_len
Device address length, in bytes.
Definition i2c.h:38

References address, i2c_device::dev_addr, i2c_device::dev_addr_len, direction, i2c_send_byte(), i2c_start(), offset, rc, and i2c_device::word_addr_len.

Referenced by i2c_bit_read(), and i2c_bit_write().

◆ i2c_reset()

int i2c_reset ( struct bit_basher * basher)
static

Reset I2C bus.

Parameters
basherBit-bashing interface
Return values
rcReturn status code

i2c devices often don't have a reset line, so even a reboot or system power cycle is sometimes not enough to bring them back to a known state.

Definition at line 238 of file i2c_bit.c.

238 {
239 unsigned int i;
240 int sda;
241
242 /* Clock through several cycles, waiting for an opportunity to
243 * pull SDA low while SCL is high (which creates a start
244 * condition).
245 */
246 open_bit ( basher );
247 setscl ( basher, 0 );
248 setsda ( basher, 1 );
249 for ( i = 0 ; i < I2C_RESET_MAX_CYCLES ; i++ ) {
250 setscl ( basher, 1 );
251 sda = getsda ( basher );
252 if ( sda ) {
253 /* Now that the device will see a start, issue it */
254 i2c_start ( basher );
255 /* Stop the bus to leave it in a known good state */
256 i2c_stop ( basher );
257 DBGC ( basher, "I2CBIT %p reset after %d attempts\n",
258 basher, ( i + 1 ) );
259 close_bit ( basher );
260 return 0;
261 }
262 setscl ( basher, 0 );
263 }
264
265 DBGC ( basher, "I2CBIT %p could not reset after %d attempts\n",
266 basher, i );
267 close_bit ( basher );
268 return -ETIMEDOUT;
269}
static void open_bit(struct bit_basher *basher)
Open bit-bashing interface.
Definition bitbash.h:66
static void close_bit(struct bit_basher *basher)
Close bit-bashing interface.
Definition bitbash.h:76
#define DBGC(...)
Definition compiler.h:505
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define I2C_RESET_MAX_CYCLES
Maximum number of cycles to use when attempting a bus reset.
Definition i2c.h:123
static void i2c_stop(struct bit_basher *basher)
Send an I2C stop condition.
Definition i2c_bit.c:135

References close_bit(), DBGC, ETIMEDOUT, getsda(), I2C_RESET_MAX_CYCLES, i2c_start(), i2c_stop(), open_bit(), setscl(), and setsda().

Referenced by init_i2c_bit_basher().

◆ i2c_bit_read()

int i2c_bit_read ( struct i2c_interface * i2c,
struct i2c_device * i2cdev,
unsigned int offset,
uint8_t * data,
unsigned int len )
static

Read data from I2C device via bit-bashing interface.

Parameters
i2cI2C interface
i2cdevI2C device
offsetStarting offset within the device
dataData buffer
lenLength of data buffer
Return values
rcReturn status code

Note that attempting to read zero bytes of data is a valid way to check for I2C device presence.

Definition at line 284 of file i2c_bit.c.

286 {
287 struct i2c_bit_basher *i2cbit
288 = container_of ( i2c, struct i2c_bit_basher, i2c );
289 struct bit_basher *basher = &i2cbit->basher;
290 int rc = 0;
291
292 DBGC ( basher, "I2CBIT %p reading from device %x: ",
293 basher, i2cdev->dev_addr );
294
295 open_bit ( basher );
296
297 for ( ; ; data++, offset++ ) {
298
299 /* Select device for writing */
300 if ( ( rc = i2c_select ( basher, i2cdev, offset,
301 I2C_WRITE ) ) != 0 )
302 break;
303
304 /* Abort at end of data */
305 if ( ! ( len-- ) )
306 break;
307
308 /* Select offset */
309 if ( ( rc = i2c_send_byte ( basher, offset ) ) != 0 )
310 break;
311
312 /* Select device for reading */
313 if ( ( rc = i2c_select ( basher, i2cdev, offset,
314 I2C_READ ) ) != 0 )
315 break;
316
317 /* Read byte */
318 *data = i2c_recv_byte ( basher );
319 DBGC ( basher, "%02x ", *data );
320 }
321
322 DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) );
323 i2c_stop ( basher );
324 close_bit ( basher );
325 return rc;
326}
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define I2C_WRITE
An I2C write command.
Definition i2c.h:106
#define I2C_READ
An I2C read command.
Definition i2c.h:109
static uint8_t i2c_recv_byte(struct bit_basher *basher)
Receive byte via I2C bus.
Definition i2c_bit.c:177
static int i2c_select(struct bit_basher *basher, struct i2c_device *i2cdev, unsigned int offset, unsigned int direction)
Select I2C device for reading or writing.
Definition i2c_bit.c:203
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A bit-bashing interface.
Definition bitbash.h:56
A bit-bashing I2C interface.
Definition i2c.h:91
struct i2c_interface i2c
I2C interface.
Definition i2c.h:93
struct bit_basher basher
Bit-bashing interface.
Definition i2c.h:95

References i2c_bit_basher::basher, close_bit(), container_of, data, DBGC, i2c_device::dev_addr, i2c_bit_basher::i2c, I2C_READ, i2c_recv_byte(), i2c_select(), i2c_send_byte(), i2c_stop(), I2C_WRITE, len, offset, open_bit(), and rc.

Referenced by init_i2c_bit_basher().

◆ i2c_bit_write()

int i2c_bit_write ( struct i2c_interface * i2c,
struct i2c_device * i2cdev,
unsigned int offset,
const uint8_t * data,
unsigned int len )
static

Write data to I2C device via bit-bashing interface.

Parameters
i2cI2C interface
i2cdevI2C device
offsetStarting offset within the device
dataData buffer
lenLength of data buffer
Return values
rcReturn status code

Note that attempting to write zero bytes of data is a valid way to check for I2C device presence.

Definition at line 341 of file i2c_bit.c.

343 {
344 struct i2c_bit_basher *i2cbit
345 = container_of ( i2c, struct i2c_bit_basher, i2c );
346 struct bit_basher *basher = &i2cbit->basher;
347 int rc = 0;
348
349 DBGC ( basher, "I2CBIT %p writing to device %x: ",
350 basher, i2cdev->dev_addr );
351
352 open_bit ( basher );
353
354 for ( ; ; data++, offset++ ) {
355
356 /* Select device for writing */
357 if ( ( rc = i2c_select ( basher, i2cdev, offset,
358 I2C_WRITE ) ) != 0 )
359 break;
360
361 /* Abort at end of data */
362 if ( ! ( len-- ) )
363 break;
364
365 /* Select offset */
366 if ( ( rc = i2c_send_byte ( basher, offset ) ) != 0 )
367 break;
368
369 /* Write data to device */
370 DBGC ( basher, "%02x ", *data );
371 if ( ( rc = i2c_send_byte ( basher, *data ) ) != 0 )
372 break;
373 }
374
375 DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) );
376 i2c_stop ( basher );
377 close_bit ( basher );
378 return rc;
379}

References i2c_bit_basher::basher, close_bit(), container_of, data, DBGC, i2c_device::dev_addr, i2c_bit_basher::i2c, i2c_select(), i2c_send_byte(), i2c_stop(), I2C_WRITE, len, offset, open_bit(), and rc.

Referenced by init_i2c_bit_basher().

◆ init_i2c_bit_basher()

int init_i2c_bit_basher ( struct i2c_bit_basher * i2cbit,
struct bit_basher_operations * bash_op )

Initialise I2C bit-bashing interface.

Parameters
i2cbitI2C bit-bashing interface
bash_opBit-basher operations

Definition at line 387 of file i2c_bit.c.

388 {
389 struct bit_basher *basher = &i2cbit->basher;
390 int rc;
391
392 /* Initialise data structures */
393 basher->op = bash_op;
394 assert ( basher->op->read != NULL );
395 assert ( basher->op->write != NULL );
396 i2cbit->i2c.read = i2c_bit_read;
397 i2cbit->i2c.write = i2c_bit_write;
398
399 /* Reset I2C bus */
400 if ( ( rc = i2c_reset ( basher ) ) != 0 ) {
401 DBGC ( basher, "I2CBIT %p could not reset I2C bus: %s\n",
402 basher, strerror ( rc ) );
403 return rc;
404 }
405
406 return 0;
407}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static int i2c_bit_read(struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, uint8_t *data, unsigned int len)
Read data from I2C device via bit-bashing interface.
Definition i2c_bit.c:284
static int i2c_reset(struct bit_basher *basher)
Reset I2C bus.
Definition i2c_bit.c:238
static int i2c_bit_write(struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, const uint8_t *data, unsigned int len)
Write data to I2C device via bit-bashing interface.
Definition i2c_bit.c:341
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
void(* write)(struct bit_basher *basher, unsigned int bit_id, unsigned long data)
Set/clear output bit.
Definition bitbash.h:42
int(* read)(struct bit_basher *basher, unsigned int bit_id)
Read input bit.
Definition bitbash.h:52
struct bit_basher_operations * op
Bit-bashing operations.
Definition bitbash.h:58
int(* write)(struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, const uint8_t *data, unsigned int len)
Write data to I2C device.
Definition i2c.h:81
int(* read)(struct i2c_interface *i2c, struct i2c_device *i2cdev, unsigned int offset, uint8_t *data, unsigned int len)
Read data from I2C device.
Definition i2c.h:68

References assert, i2c_bit_basher::basher, DBGC, i2c_bit_basher::i2c, i2c_bit_read(), i2c_bit_write(), i2c_reset(), NULL, bit_basher::op, rc, bit_basher_operations::read, i2c_interface::read, strerror(), bit_basher_operations::write, and i2c_interface::write.

Referenced by exanic_try_init_eeprom(), falcon_probe_spi(), linda_init_i2c(), and qib7322_init_i2c().