bitbang_i2c.c (5960B)
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 13#include "qemu/osdep.h" 14#include "hw/irq.h" 15#include "hw/i2c/bitbang_i2c.h" 16#include "hw/sysbus.h" 17#include "qemu/module.h" 18#include "qom/object.h" 19 20//#define DEBUG_BITBANG_I2C 21 22#ifdef DEBUG_BITBANG_I2C 23#define DPRINTF(fmt, ...) \ 24do { printf("bitbang_i2c: " fmt , ## __VA_ARGS__); } while (0) 25#else 26#define DPRINTF(fmt, ...) do {} while(0) 27#endif 28 29static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c) 30{ 31 DPRINTF("STOP\n"); 32 if (i2c->current_addr >= 0) 33 i2c_end_transfer(i2c->bus); 34 i2c->current_addr = -1; 35 i2c->state = STOPPED; 36} 37 38/* Set device data pin. */ 39static int bitbang_i2c_ret(bitbang_i2c_interface *i2c, int level) 40{ 41 i2c->device_out = level; 42 //DPRINTF("%d %d %d\n", i2c->last_clock, i2c->last_data, i2c->device_out); 43 return level & i2c->last_data; 44} 45 46/* Leave device data pin unodified. */ 47static int bitbang_i2c_nop(bitbang_i2c_interface *i2c) 48{ 49 return bitbang_i2c_ret(i2c, i2c->device_out); 50} 51 52/* Returns data line level. */ 53int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level) 54{ 55 int data; 56 57 if (level != 0 && level != 1) { 58 abort(); 59 } 60 61 if (line == BITBANG_I2C_SDA) { 62 if (level == i2c->last_data) { 63 return bitbang_i2c_nop(i2c); 64 } 65 i2c->last_data = level; 66 if (i2c->last_clock == 0) { 67 return bitbang_i2c_nop(i2c); 68 } 69 if (level == 0) { 70 DPRINTF("START\n"); 71 /* START condition. */ 72 i2c->state = SENDING_BIT7; 73 i2c->current_addr = -1; 74 } else { 75 /* STOP condition. */ 76 bitbang_i2c_enter_stop(i2c); 77 } 78 return bitbang_i2c_ret(i2c, 1); 79 } 80 81 data = i2c->last_data; 82 if (i2c->last_clock == level) { 83 return bitbang_i2c_nop(i2c); 84 } 85 i2c->last_clock = level; 86 if (level == 0) { 87 /* State is set/read at the start of the clock pulse. 88 release the data line at the end. */ 89 return bitbang_i2c_ret(i2c, 1); 90 } 91 switch (i2c->state) { 92 case STOPPED: 93 case SENT_NACK: 94 return bitbang_i2c_ret(i2c, 1); 95 96 case SENDING_BIT7 ... SENDING_BIT0: 97 i2c->buffer = (i2c->buffer << 1) | data; 98 /* will end up in WAITING_FOR_ACK */ 99 i2c->state++; 100 return bitbang_i2c_ret(i2c, 1); 101 102 case WAITING_FOR_ACK: 103 { 104 int ret; 105 106 if (i2c->current_addr < 0) { 107 i2c->current_addr = i2c->buffer; 108 DPRINTF("Address 0x%02x\n", i2c->current_addr); 109 ret = i2c_start_transfer(i2c->bus, i2c->current_addr >> 1, 110 i2c->current_addr & 1); 111 } else { 112 DPRINTF("Sent 0x%02x\n", i2c->buffer); 113 ret = i2c_send(i2c->bus, i2c->buffer); 114 } 115 if (ret) { 116 /* NACK (either addressing a nonexistent device, or the 117 * device we were sending to decided to NACK us). 118 */ 119 DPRINTF("Got NACK\n"); 120 bitbang_i2c_enter_stop(i2c); 121 return bitbang_i2c_ret(i2c, 1); 122 } 123 if (i2c->current_addr & 1) { 124 i2c->state = RECEIVING_BIT7; 125 } else { 126 i2c->state = SENDING_BIT7; 127 } 128 return bitbang_i2c_ret(i2c, 0); 129 } 130 case RECEIVING_BIT7: 131 i2c->buffer = i2c_recv(i2c->bus); 132 DPRINTF("RX byte 0x%02x\n", i2c->buffer); 133 /* Fall through... */ 134 case RECEIVING_BIT6 ... RECEIVING_BIT0: 135 data = i2c->buffer >> 7; 136 /* will end up in SENDING_ACK */ 137 i2c->state++; 138 i2c->buffer <<= 1; 139 return bitbang_i2c_ret(i2c, data); 140 141 case SENDING_ACK: 142 i2c->state = RECEIVING_BIT7; 143 if (data != 0) { 144 DPRINTF("NACKED\n"); 145 i2c->state = SENT_NACK; 146 i2c_nack(i2c->bus); 147 } else { 148 DPRINTF("ACKED\n"); 149 } 150 return bitbang_i2c_ret(i2c, 1); 151 } 152 abort(); 153} 154 155void bitbang_i2c_init(bitbang_i2c_interface *s, I2CBus *bus) 156{ 157 s->bus = bus; 158 s->last_data = 1; 159 s->last_clock = 1; 160 s->device_out = 1; 161} 162 163/* GPIO interface. */ 164 165#define TYPE_GPIO_I2C "gpio_i2c" 166OBJECT_DECLARE_SIMPLE_TYPE(GPIOI2CState, GPIO_I2C) 167 168struct GPIOI2CState { 169 SysBusDevice parent_obj; 170 171 MemoryRegion dummy_iomem; 172 bitbang_i2c_interface bitbang; 173 int last_level; 174 qemu_irq out; 175}; 176 177static void bitbang_i2c_gpio_set(void *opaque, int irq, int level) 178{ 179 GPIOI2CState *s = opaque; 180 181 level = bitbang_i2c_set(&s->bitbang, irq, level); 182 if (level != s->last_level) { 183 s->last_level = level; 184 qemu_set_irq(s->out, level); 185 } 186} 187 188static void gpio_i2c_init(Object *obj) 189{ 190 DeviceState *dev = DEVICE(obj); 191 GPIOI2CState *s = GPIO_I2C(obj); 192 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 193 I2CBus *bus; 194 195 memory_region_init(&s->dummy_iomem, obj, "gpio_i2c", 0); 196 sysbus_init_mmio(sbd, &s->dummy_iomem); 197 198 bus = i2c_init_bus(dev, "i2c"); 199 bitbang_i2c_init(&s->bitbang, bus); 200 201 qdev_init_gpio_in(dev, bitbang_i2c_gpio_set, 2); 202 qdev_init_gpio_out(dev, &s->out, 1); 203} 204 205static void gpio_i2c_class_init(ObjectClass *klass, void *data) 206{ 207 DeviceClass *dc = DEVICE_CLASS(klass); 208 209 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); 210 dc->desc = "Virtual GPIO to I2C bridge"; 211} 212 213static const TypeInfo gpio_i2c_info = { 214 .name = TYPE_GPIO_I2C, 215 .parent = TYPE_SYS_BUS_DEVICE, 216 .instance_size = sizeof(GPIOI2CState), 217 .instance_init = gpio_i2c_init, 218 .class_init = gpio_i2c_class_init, 219}; 220 221static void bitbang_i2c_register_types(void) 222{ 223 type_register_static(&gpio_i2c_info); 224} 225 226type_init(bitbang_i2c_register_types)