diff --git a/src/drivers/bitbash/i2c_bit.c b/src/drivers/bitbash/i2c_bit.c index a72d1459..decc8d80 100644 --- a/src/drivers/bitbash/i2c_bit.c +++ b/src/drivers/bitbash/i2c_bit.c @@ -239,6 +239,7 @@ static int i2c_reset ( struct bit_basher *basher ) { * pull SDA low while SCL is high (which creates a start * condition). */ + open_bit ( basher ); setscl ( basher, 0 ); setsda ( basher, 1 ); for ( i = 0 ; i < I2C_RESET_MAX_CYCLES ; i++ ) { @@ -251,6 +252,7 @@ static int i2c_reset ( struct bit_basher *basher ) { i2c_stop ( basher ); DBGC ( basher, "I2CBIT %p reset after %d attempts\n", basher, ( i + 1 ) ); + close_bit ( basher ); return 0; } setscl ( basher, 0 ); @@ -258,6 +260,7 @@ static int i2c_reset ( struct bit_basher *basher ) { DBGC ( basher, "I2CBIT %p could not reset after %d attempts\n", basher, i ); + close_bit ( basher ); return -ETIMEDOUT; } @@ -285,6 +288,8 @@ static int i2c_bit_read ( struct i2c_interface *i2c, DBGC ( basher, "I2CBIT %p reading from device %x: ", basher, i2cdev->dev_addr ); + open_bit ( basher ); + for ( ; ; data++, offset++ ) { /* Select device for writing */ @@ -312,6 +317,7 @@ static int i2c_bit_read ( struct i2c_interface *i2c, DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) ); i2c_stop ( basher ); + close_bit ( basher ); return rc; } @@ -339,6 +345,8 @@ static int i2c_bit_write ( struct i2c_interface *i2c, DBGC ( basher, "I2CBIT %p writing to device %x: ", basher, i2cdev->dev_addr ); + open_bit ( basher ); + for ( ; ; data++, offset++ ) { /* Select device for writing */ @@ -359,9 +367,10 @@ static int i2c_bit_write ( struct i2c_interface *i2c, if ( ( rc = i2c_send_byte ( basher, *data ) ) != 0 ) break; } - + DBGC ( basher, "%s\n", ( rc ? "failed" : "" ) ); i2c_stop ( basher ); + close_bit ( basher ); return rc; } diff --git a/src/drivers/bitbash/spi_bit.c b/src/drivers/bitbash/spi_bit.c index 4a9af0a3..1b39d72f 100644 --- a/src/drivers/bitbash/spi_bit.c +++ b/src/drivers/bitbash/spi_bit.c @@ -163,6 +163,9 @@ static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device, uint32_t tmp_address; uint32_t tmp_address_detect; + /* Open bit-bashing interface */ + open_bit ( &spibit->basher ); + /* Deassert chip select to reset specified slave */ spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE ); @@ -214,6 +217,9 @@ static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device, /* Deassert chip select on specified slave */ spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE ); + /* Close bit-bashing interface */ + close_bit ( &spibit->basher ); + return 0; } diff --git a/src/include/ipxe/bitbash.h b/src/include/ipxe/bitbash.h index 62b54b10..69d5d9e3 100644 --- a/src/include/ipxe/bitbash.h +++ b/src/include/ipxe/bitbash.h @@ -13,6 +13,18 @@ struct bit_basher; /** Bit-bashing operations */ struct bit_basher_operations { + /** + * Open bit-bashing interface (optional) + * + * @v basher Bit-bashing interface + */ + void ( * open ) ( struct bit_basher *basher ); + /** + * Close bit-bashing interface (optional) + * + * @v basher Bit-bashing interface + */ + void ( * close ) ( struct bit_basher *basher ); /** * Set/clear output bit * @@ -45,6 +57,26 @@ struct bit_basher { struct bit_basher_operations *op; }; +/** + * Open bit-bashing interface + * + * @v basher Bit-bashing interface + */ +static inline void open_bit ( struct bit_basher *basher ) { + if ( basher->op->open ) + basher->op->open ( basher ); +} + +/** + * Close bit-bashing interface + * + * @v basher Bit-bashing interface + */ +static inline void close_bit ( struct bit_basher *basher ) { + if ( basher->op->close ) + basher->op->close ( basher ); +} + extern void write_bit ( struct bit_basher *basher, unsigned int bit_id, unsigned long data ); extern int read_bit ( struct bit_basher *basher, unsigned int bit_id );