Signed-off-by: Benoit Canet <benoit.ca...@gmail.com> --- hw/bitbang_i2c.c | 92 +++++++++++++++++++++++++++++++++++------------------ 1 files changed, 61 insertions(+), 31 deletions(-)
diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c index 431359d..b711144 100644 --- a/hw/bitbang_i2c.c +++ b/hw/bitbang_i2c.c @@ -19,37 +19,53 @@ do { printf("bitbang_i2c: " fmt , ## __VA_ARGS__); } while (0) #define DPRINTF(fmt, ...) do {} while(0) #endif -typedef enum bitbang_i2c_state { +enum { STOPPED = 0, - SENDING_BIT7, - SENDING_BIT6, - SENDING_BIT5, - SENDING_BIT4, - SENDING_BIT3, - SENDING_BIT2, - SENDING_BIT1, - SENDING_BIT0, - WAITING_FOR_ACK, - RECEIVING_BIT7, - RECEIVING_BIT6, - RECEIVING_BIT5, - RECEIVING_BIT4, - RECEIVING_BIT3, - RECEIVING_BIT2, - RECEIVING_BIT1, - RECEIVING_BIT0, - SENDING_ACK, - SENT_NACK -} bitbang_i2c_state; + SENDING_BIT7 = 1, + SENDING_BIT6 = 2, + SENDING_BIT5 = 3, + SENDING_BIT4 = 4, + SENDING_BIT3 = 5, + SENDING_BIT2 = 6, + SENDING_BIT1 = 7, + SENDING_BIT0 = 8, + WAITING_FOR_ACK = 9, + RECEIVING_BIT7 = 10, + RECEIVING_BIT6 = 11, + RECEIVING_BIT5 = 12, + RECEIVING_BIT4 = 13, + RECEIVING_BIT3 = 14, + RECEIVING_BIT2 = 15, + RECEIVING_BIT1 = 16, + RECEIVING_BIT0 = 17, + SENDING_ACK = 18, + SENT_NACK = 19 +}; struct bitbang_i2c_interface { i2c_bus *bus; - bitbang_i2c_state state; - int last_data; - int last_clock; - int device_out; + uint8_t state; + int32_t last_data; + int32_t last_clock; + int32_t device_out; uint8_t buffer; - int current_addr; + int32_t current_addr; +}; + +const VMStateDescription vmstate_bitbang_i2c = { + .name = "bitbang_i2c", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(state, bitbang_i2c_interface), + VMSTATE_INT32(last_data, bitbang_i2c_interface), + VMSTATE_INT32(last_clock, bitbang_i2c_interface), + VMSTATE_INT32(device_out, bitbang_i2c_interface), + VMSTATE_UINT8(buffer, bitbang_i2c_interface), + VMSTATE_INT32(current_addr, bitbang_i2c_interface), + VMSTATE_END_OF_LIST() + } }; static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c) @@ -62,7 +78,7 @@ static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c) } /* Set device data pin. */ -static int bitbang_i2c_ret(bitbang_i2c_interface *i2c, int level) +static int32_t bitbang_i2c_ret(bitbang_i2c_interface *i2c, int32_t level) { i2c->device_out = level; //DPRINTF("%d %d %d\n", i2c->last_clock, i2c->last_data, i2c->device_out); @@ -70,13 +86,13 @@ static int bitbang_i2c_ret(bitbang_i2c_interface *i2c, int level) } /* Leave device data pin unodified. */ -static int bitbang_i2c_nop(bitbang_i2c_interface *i2c) +static int32_t bitbang_i2c_nop(bitbang_i2c_interface *i2c) { return bitbang_i2c_ret(i2c, i2c->device_out); } /* Returns data line level. */ -int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level) +int32_t bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int32_t level) { int data; @@ -185,11 +201,24 @@ bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus) typedef struct { SysBusDevice busdev; bitbang_i2c_interface *bitbang; - int last_level; + int32_t last_level; qemu_irq out; } GPIOI2CState; -static void bitbang_i2c_gpio_set(void *opaque, int irq, int level) +const VMStateDescription vmstate_gpio_i2c = { + .name = "gpio_i2c", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_POINTER(bitbang, GPIOI2CState, vmstate_bitbang_i2c, + bitbang_i2c_interface *), + VMSTATE_INT32(last_level, GPIOI2CState), + VMSTATE_END_OF_LIST() + } +}; + +static void bitbang_i2c_gpio_set(void *opaque, int irq, int32_t level) { GPIOI2CState *s = opaque; @@ -221,6 +250,7 @@ static SysBusDeviceInfo gpio_i2c_info = { .qdev.name = "gpio_i2c", .qdev.desc = "Virtual GPIO to I2C bridge", .qdev.size = sizeof(GPIOI2CState), + .qdev.vmsd = &vmstate_gpio_i2c, }; static void bitbang_i2c_register(void) -- 1.7.4.1