1 #include "qemu/osdep.h" 2 #include "qemu/timer.h" 3 #include "qemu/main-loop.h" 4 #include "block/aio.h" 5 #include "hw/i2c/i2c.h" 6 7 #define TYPE_I2C_ECHO "i2c-echo" 8 OBJECT_DECLARE_SIMPLE_TYPE(I2CEchoState, I2C_ECHO) 9 10 enum i2c_echo_state { 11 I2C_ECHO_STATE_IDLE, 12 I2C_ECHO_STATE_START_SEND, 13 I2C_ECHO_STATE_ACK, 14 }; 15 16 typedef struct I2CEchoState { 17 I2CSlave parent_obj; 18 19 I2CBus *bus; 20 21 enum i2c_echo_state state; 22 QEMUBH *bh; 23 24 unsigned int pos; 25 uint8_t data[3]; 26 } I2CEchoState; 27 28 static void i2c_echo_bh(void *opaque) 29 { 30 I2CEchoState *state = opaque; 31 32 switch (state->state) { 33 case I2C_ECHO_STATE_IDLE: 34 return; 35 36 case I2C_ECHO_STATE_START_SEND: 37 if (i2c_start_send_async(state->bus, state->data[0])) { 38 goto release_bus; 39 } 40 41 state->pos++; 42 state->state = I2C_ECHO_STATE_ACK; 43 return; 44 45 case I2C_ECHO_STATE_ACK: 46 if (state->pos > 2) { 47 break; 48 } 49 50 if (i2c_send_async(state->bus, state->data[state->pos++])) { 51 break; 52 } 53 54 return; 55 } 56 57 58 i2c_end_transfer(state->bus); 59 release_bus: 60 i2c_bus_release(state->bus); 61 62 state->state = I2C_ECHO_STATE_IDLE; 63 } 64 65 static int i2c_echo_event(I2CSlave *s, enum i2c_event event) 66 { 67 I2CEchoState *state = I2C_ECHO(s); 68 69 switch (event) { 70 case I2C_START_RECV: 71 state->pos = 0; 72 73 break; 74 75 case I2C_START_SEND: 76 state->pos = 0; 77 78 break; 79 80 case I2C_FINISH: 81 state->pos = 0; 82 state->state = I2C_ECHO_STATE_START_SEND; 83 i2c_bus_master(state->bus, state->bh); 84 85 break; 86 87 case I2C_NACK: 88 break; 89 90 default: 91 return -1; 92 } 93 94 return 0; 95 } 96 97 static uint8_t i2c_echo_recv(I2CSlave *s) 98 { 99 I2CEchoState *state = I2C_ECHO(s); 100 101 if (state->pos > 2) { 102 return 0xff; 103 } 104 105 return state->data[state->pos++]; 106 } 107 108 static int i2c_echo_send(I2CSlave *s, uint8_t data) 109 { 110 I2CEchoState *state = I2C_ECHO(s); 111 112 if (state->pos > 2) { 113 return -1; 114 } 115 116 state->data[state->pos++] = data; 117 118 return 0; 119 } 120 121 static void i2c_echo_realize(DeviceState *dev, Error **errp) 122 { 123 I2CEchoState *state = I2C_ECHO(dev); 124 BusState *bus = qdev_get_parent_bus(dev); 125 126 state->bus = I2C_BUS(bus); 127 state->bh = qemu_bh_new(i2c_echo_bh, state); 128 129 return; 130 } 131 132 static void i2c_echo_class_init(ObjectClass *oc, void *data) 133 { 134 I2CSlaveClass *sc = I2C_SLAVE_CLASS(oc); 135 DeviceClass *dc = DEVICE_CLASS(oc); 136 137 dc->realize = i2c_echo_realize; 138 139 sc->event = i2c_echo_event; 140 sc->recv = i2c_echo_recv; 141 sc->send = i2c_echo_send; 142 } 143 144 static const TypeInfo i2c_echo = { 145 .name = TYPE_I2C_ECHO, 146 .parent = TYPE_I2C_SLAVE, 147 .instance_size = sizeof(I2CEchoState), 148 .class_init = i2c_echo_class_init, 149 }; 150 151 static void register_types(void) 152 { 153 type_register_static(&i2c_echo); 154 } 155 156 type_init(register_types); 157