Revision 02e2da45 hw/i2c.c

b/hw/i2c.c
11 11

  
12 12
struct i2c_bus
13 13
{
14
    BusState qbus;
14 15
    i2c_slave *current_dev;
15 16
    i2c_slave *dev;
16 17
    int saved_address;
......
39 40
}
40 41

  
41 42
/* Create a new I2C bus.  */
42
i2c_bus *i2c_init_bus(void)
43
i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
43 44
{
44 45
    i2c_bus *bus;
45 46

  
46
    bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus));
47
    bus = FROM_QBUS(i2c_bus, qbus_create(BUS_TYPE_I2C, sizeof(i2c_bus),
48
                                         parent, name));
47 49
    register_savevm("i2c_bus", -1, 1, i2c_bus_save, i2c_bus_load, bus);
48 50
    return bus;
49 51
}
......
63 65
/* TODO: Make this handle multiple masters.  */
64 66
int i2c_start_transfer(i2c_bus *bus, int address, int recv)
65 67
{
66
    i2c_slave *dev;
68
    DeviceState *qdev;
69
    i2c_slave *slave = NULL;
67 70

  
68
    for (dev = bus->dev; dev; dev = dev->next) {
69
        if (dev->address == address)
71
    LIST_FOREACH(qdev, &bus->qbus.children, sibling) {
72
        slave = I2C_SLAVE_FROM_QDEV(qdev);
73
        if (slave->address == address)
70 74
            break;
71 75
    }
72 76

  
73
    if (!dev)
77
    if (!slave)
74 78
        return 1;
75 79

  
76 80
    /* If the bus is already busy, assume this is a repeated
77 81
       start condition.  */
78
    bus->current_dev = dev;
79
    dev->info->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
82
    bus->current_dev = slave;
83
    slave->info->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
80 84
    return 0;
81 85
}
82 86

  
......
130 134
void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
131 135
{
132 136
    i2c_bus *bus;
133
    bus = qdev_get_bus(&dev->qdev);
137
    bus = FROM_QBUS(i2c_bus, qdev_get_parent_bus(&dev->qdev));
134 138
    dev->address = qemu_get_byte(f);
135 139
    if (bus->saved_address == dev->address) {
136 140
        bus->current_dev = dev;
137 141
    }
138 142
}
139 143

  
140
static void i2c_slave_qdev_init(DeviceState *dev, void *opaque)
144
static void i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
141 145
{
142
    I2CSlaveInfo *info = opaque;
146
    I2CSlaveInfo *info = container_of(base, I2CSlaveInfo, qdev);
143 147
    i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev);
144 148

  
145 149
    s->info = info;
146
    s->bus = qdev_get_bus(dev);
147 150
    s->address = qdev_get_prop_int(dev, "address", 0);
148
    s->next = s->bus->dev;
149
    s->bus->dev = s;
150 151

  
151 152
    info->init(s);
152 153
}
......
154 155
void i2c_register_slave(const char *name, int size, I2CSlaveInfo *info)
155 156
{
156 157
    assert(size >= sizeof(i2c_slave));
157
    qdev_register(name, size, i2c_slave_qdev_init, info);
158
    info->qdev.init = i2c_slave_qdev_init;
159
    info->qdev.bus_type = BUS_TYPE_I2C;
160
    qdev_register(name, size, &info->qdev);
158 161
}
159 162

  
160 163
DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr)
161 164
{
162 165
    DeviceState *dev;
163 166

  
164
    dev = qdev_create(bus, name);
167
    dev = qdev_create(&bus->qbus, name);
165 168
    qdev_set_prop_int(dev, "address", addr);
166 169
    qdev_init(dev);
167 170
    return dev;

Also available in: Unified diff