1 /* 2 * Bit-Bang i2c emulation extracted from 3 * Marvell MV88W8618 / Freecom MusicPal emulation. 4 * 5 * Copyright (c) 2008 Jan Kiszka 6 * 7 * This code is licensed under the GNU GPL v2. 8 * 9 * Contributions after 2012-01-13 are licensed under the terms of the 10 * GNU GPL, version 2 or (at your option) any later version. 11 */ 12 #include "hw/hw.h" 13 #include "bitbang_i2c.h" 14 #include "hw/sysbus.h" 15 16 //#define DEBUG_BITBANG_I2C 17 18 #ifdef DEBUG_BITBANG_I2C 19 #define DPRINTF(fmt, ...) \ 20 do { printf("bitbang_i2c: " fmt , ## __VA_ARGS__); } while (0) 21 #else 22 #define DPRINTF(fmt, ...) do {} while(0) 23 #endif 24 25 typedef enum bitbang_i2c_state { 26 STOPPED = 0, 27 SENDING_BIT7, 28 SENDING_BIT6, 29 SENDING_BIT5, 30 SENDING_BIT4, 31 SENDING_BIT3, 32 SENDING_BIT2, 33 SENDING_BIT1, 34 SENDING_BIT0, 35 WAITING_FOR_ACK, 36 RECEIVING_BIT7, 37 RECEIVING_BIT6, 38 RECEIVING_BIT5, 39 RECEIVING_BIT4, 40 RECEIVING_BIT3, 41 RECEIVING_BIT2, 42 RECEIVING_BIT1, 43 RECEIVING_BIT0, 44 SENDING_ACK, 45 SENT_NACK 46 } bitbang_i2c_state; 47 48 struct bitbang_i2c_interface { 49 I2CBus *bus; 50 bitbang_i2c_state state; 51 int last_data; 52 int last_clock; 53 int device_out; 54 uint8_t buffer; 55 int current_addr; 56 }; 57 58 static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c) 59 { 60 DPRINTF("STOP\n"); 61 if (i2c->current_addr >= 0) 62 i2c_end_transfer(i2c->bus); 63 i2c->current_addr = -1; 64 i2c->state = STOPPED; 65 } 66 67 /* Set device data pin. */ 68 static int bitbang_i2c_ret(bitbang_i2c_interface *i2c, int level) 69 { 70 i2c->device_out = level; 71 //DPRINTF("%d %d %d\n", i2c->last_clock, i2c->last_data, i2c->device_out); 72 return level & i2c->last_data; 73 } 74 75 /* Leave device data pin unodified. */ 76 static int bitbang_i2c_nop(bitbang_i2c_interface *i2c) 77 { 78 return bitbang_i2c_ret(i2c, i2c->device_out); 79 } 80 81 /* Returns data line level. */ 82 int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level) 83 { 84 int data; 85 86 if (level != 0 && level != 1) { 87 abort(); 88 } 89 90 if (line == BITBANG_I2C_SDA) { 91 if (level == i2c->last_data) { 92 return bitbang_i2c_nop(i2c); 93 } 94 i2c->last_data = level; 95 if (i2c->last_clock == 0) { 96 return bitbang_i2c_nop(i2c); 97 } 98 if (level == 0) { 99 DPRINTF("START\n"); 100 /* START condition. */ 101 i2c->state = SENDING_BIT7; 102 i2c->current_addr = -1; 103 } else { 104 /* STOP condition. */ 105 bitbang_i2c_enter_stop(i2c); 106 } 107 return bitbang_i2c_ret(i2c, 1); 108 } 109 110 data = i2c->last_data; 111 if (i2c->last_clock == level) { 112 return bitbang_i2c_nop(i2c); 113 } 114 i2c->last_clock = level; 115 if (level == 0) { 116 /* State is set/read at the start of the clock pulse. 117 release the data line at the end. */ 118 return bitbang_i2c_ret(i2c, 1); 119 } 120 switch (i2c->state) { 121 case STOPPED: 122 case SENT_NACK: 123 return bitbang_i2c_ret(i2c, 1); 124 125 case SENDING_BIT7 ... SENDING_BIT0: 126 i2c->buffer = (i2c->buffer << 1) | data; 127 /* will end up in WAITING_FOR_ACK */ 128 i2c->state++; 129 return bitbang_i2c_ret(i2c, 1); 130 131 case WAITING_FOR_ACK: 132 if (i2c->current_addr < 0) { 133 i2c->current_addr = i2c->buffer; 134 DPRINTF("Address 0x%02x\n", i2c->current_addr); 135 i2c_start_transfer(i2c->bus, i2c->current_addr >> 1, 136 i2c->current_addr & 1); 137 } else { 138 DPRINTF("Sent 0x%02x\n", i2c->buffer); 139 i2c_send(i2c->bus, i2c->buffer); 140 } 141 if (i2c->current_addr & 1) { 142 i2c->state = RECEIVING_BIT7; 143 } else { 144 i2c->state = SENDING_BIT7; 145 } 146 return bitbang_i2c_ret(i2c, 0); 147 148 case RECEIVING_BIT7: 149 i2c->buffer = i2c_recv(i2c->bus); 150 DPRINTF("RX byte 0x%02x\n", i2c->buffer); 151 /* Fall through... */ 152 case RECEIVING_BIT6 ... RECEIVING_BIT0: 153 data = i2c->buffer >> 7; 154 /* will end up in SENDING_ACK */ 155 i2c->state++; 156 i2c->buffer <<= 1; 157 return bitbang_i2c_ret(i2c, data); 158 159 case SENDING_ACK: 160 i2c->state = RECEIVING_BIT7; 161 if (data != 0) { 162 DPRINTF("NACKED\n"); 163 i2c->state = SENT_NACK; 164 i2c_nack(i2c->bus); 165 } else { 166 DPRINTF("ACKED\n"); 167 } 168 return bitbang_i2c_ret(i2c, 1); 169 } 170 abort(); 171 } 172 173 bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus) 174 { 175 bitbang_i2c_interface *s; 176 177 s = g_malloc0(sizeof(bitbang_i2c_interface)); 178 179 s->bus = bus; 180 s->last_data = 1; 181 s->last_clock = 1; 182 s->device_out = 1; 183 184 return s; 185 } 186 187 /* GPIO interface. */ 188 189 #define TYPE_GPIO_I2C "gpio_i2c" 190 #define GPIO_I2C(obj) OBJECT_CHECK(GPIOI2CState, (obj), TYPE_GPIO_I2C) 191 192 typedef struct GPIOI2CState { 193 SysBusDevice parent_obj; 194 195 MemoryRegion dummy_iomem; 196 bitbang_i2c_interface *bitbang; 197 int last_level; 198 qemu_irq out; 199 } GPIOI2CState; 200 201 static void bitbang_i2c_gpio_set(void *opaque, int irq, int level) 202 { 203 GPIOI2CState *s = opaque; 204 205 level = bitbang_i2c_set(s->bitbang, irq, level); 206 if (level != s->last_level) { 207 s->last_level = level; 208 qemu_set_irq(s->out, level); 209 } 210 } 211 212 static int gpio_i2c_init(SysBusDevice *sbd) 213 { 214 DeviceState *dev = DEVICE(sbd); 215 GPIOI2CState *s = GPIO_I2C(dev); 216 I2CBus *bus; 217 218 memory_region_init(&s->dummy_iomem, OBJECT(s), "gpio_i2c", 0); 219 sysbus_init_mmio(sbd, &s->dummy_iomem); 220 221 bus = i2c_init_bus(dev, "i2c"); 222 s->bitbang = bitbang_i2c_init(bus); 223 224 qdev_init_gpio_in(dev, bitbang_i2c_gpio_set, 2); 225 qdev_init_gpio_out(dev, &s->out, 1); 226 227 return 0; 228 } 229 230 static void gpio_i2c_class_init(ObjectClass *klass, void *data) 231 { 232 DeviceClass *dc = DEVICE_CLASS(klass); 233 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 234 235 k->init = gpio_i2c_init; 236 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 237 dc->desc = "Virtual GPIO to I2C bridge"; 238 } 239 240 static const TypeInfo gpio_i2c_info = { 241 .name = TYPE_GPIO_I2C, 242 .parent = TYPE_SYS_BUS_DEVICE, 243 .instance_size = sizeof(GPIOI2CState), 244 .class_init = gpio_i2c_class_init, 245 }; 246 247 static void bitbang_i2c_register_types(void) 248 { 249 type_register_static(&gpio_i2c_info); 250 } 251 252 type_init(bitbang_i2c_register_types) 253