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 i2c_bus *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(i2c_bus *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 typedef struct { 189 SysBusDevice busdev; 190 MemoryRegion dummy_iomem; 191 bitbang_i2c_interface *bitbang; 192 int last_level; 193 qemu_irq out; 194 } GPIOI2CState; 195 196 static void bitbang_i2c_gpio_set(void *opaque, int irq, int level) 197 { 198 GPIOI2CState *s = opaque; 199 200 level = bitbang_i2c_set(s->bitbang, irq, level); 201 if (level != s->last_level) { 202 s->last_level = level; 203 qemu_set_irq(s->out, level); 204 } 205 } 206 207 static int gpio_i2c_init(SysBusDevice *dev) 208 { 209 GPIOI2CState *s = FROM_SYSBUS(GPIOI2CState, dev); 210 i2c_bus *bus; 211 212 memory_region_init(&s->dummy_iomem, OBJECT(s), "gpio_i2c", 0); 213 sysbus_init_mmio(dev, &s->dummy_iomem); 214 215 bus = i2c_init_bus(&dev->qdev, "i2c"); 216 s->bitbang = bitbang_i2c_init(bus); 217 218 qdev_init_gpio_in(&dev->qdev, bitbang_i2c_gpio_set, 2); 219 qdev_init_gpio_out(&dev->qdev, &s->out, 1); 220 221 return 0; 222 } 223 224 static void gpio_i2c_class_init(ObjectClass *klass, void *data) 225 { 226 DeviceClass *dc = DEVICE_CLASS(klass); 227 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 228 229 k->init = gpio_i2c_init; 230 dc->desc = "Virtual GPIO to I2C bridge"; 231 } 232 233 static const TypeInfo gpio_i2c_info = { 234 .name = "gpio_i2c", 235 .parent = TYPE_SYS_BUS_DEVICE, 236 .instance_size = sizeof(GPIOI2CState), 237 .class_init = gpio_i2c_class_init, 238 }; 239 240 static void bitbang_i2c_register_types(void) 241 { 242 type_register_static(&gpio_i2c_info); 243 } 244 245 type_init(bitbang_i2c_register_types) 246