Commit 1ea96673c611cdc05ea32ac81f40d9f864e18507

Authored by Paul Brook
1 parent fd1eb2ea

SMBus qdev conversion

Signed-off-by: Paul Brook <paul@codesourcery.com>
hw/mips_malta.c
... ... @@ -911,7 +911,11 @@ void mips_malta_init (ram_addr_t ram_size,
911 911 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
912 912 for (i = 0; i < 8; i++) {
913 913 /* TODO: Populate SPD eeprom data. */
914   - smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
  914 + DeviceState *eeprom;
  915 + eeprom = qdev_create(smbus, "smbus-eeprom");
  916 + qdev_set_prop_int(eeprom, "address", 0x50 + i);
  917 + qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256));
  918 + qdev_init(eeprom);
915 919 }
916 920 pit = pit_init(0x40, i8259[0]);
917 921 DMA_init(0);
... ...
... ... @@ -1109,7 +1109,11 @@ static void pc_init1(ram_addr_t ram_size,
1109 1109 /* TODO: Populate SPD eeprom data. */
1110 1110 smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
1111 1111 for (i = 0; i < 8; i++) {
1112   - smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
  1112 + DeviceState *eeprom;
  1113 + eeprom = qdev_create(smbus, "smbus-eeprom");
  1114 + qdev_set_prop_int(eeprom, "address", 0x50 + i);
  1115 + qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256));
  1116 + qdev_init(eeprom);
1113 1117 }
1114 1118 }
1115 1119  
... ...
hw/smbus.c
... ... @@ -37,33 +37,38 @@ enum {
37 37  
38 38 static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
39 39 {
  40 + SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
  41 +
40 42 DPRINTF("Quick Command %d\n", recv);
41   - if (dev->quick_cmd)
42   - dev->quick_cmd(dev, recv);
  43 + if (t->quick_cmd)
  44 + t->quick_cmd(dev, recv);
43 45 }
44 46  
45 47 static void smbus_do_write(SMBusDevice *dev)
46 48 {
  49 + SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
  50 +
47 51 if (dev->data_len == 0) {
48 52 smbus_do_quick_cmd(dev, 0);
49 53 } else if (dev->data_len == 1) {
50 54 DPRINTF("Send Byte\n");
51   - if (dev->send_byte) {
52   - dev->send_byte(dev, dev->data_buf[0]);
  55 + if (t->send_byte) {
  56 + t->send_byte(dev, dev->data_buf[0]);
53 57 }
54 58 } else {
55 59 dev->command = dev->data_buf[0];
56 60 DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
57   - if (dev->write_data) {
58   - dev->write_data(dev, dev->command, dev->data_buf + 1,
59   - dev->data_len - 1);
  61 + if (t->write_data) {
  62 + t->write_data(dev, dev->command, dev->data_buf + 1,
  63 + dev->data_len - 1);
60 64 }
61 65 }
62 66 }
63 67  
64 68 static void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
65 69 {
66   - SMBusDevice *dev = (SMBusDevice *)s;
  70 + SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
  71 +
67 72 switch (event) {
68 73 case I2C_START_SEND:
69 74 switch (dev->mode) {
... ... @@ -145,13 +150,14 @@ static void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
145 150  
146 151 static int smbus_i2c_recv(i2c_slave *s)
147 152 {
148   - SMBusDevice *dev = (SMBusDevice *)s;
  153 + SMBusDeviceInfo *t = container_of(s->info, SMBusDeviceInfo, i2c);
  154 + SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
149 155 int ret;
150 156  
151 157 switch (dev->mode) {
152 158 case SMBUS_RECV_BYTE:
153   - if (dev->receive_byte) {
154   - ret = dev->receive_byte(dev);
  159 + if (t->receive_byte) {
  160 + ret = t->receive_byte(dev);
155 161 } else {
156 162 ret = 0;
157 163 }
... ... @@ -159,8 +165,8 @@ static int smbus_i2c_recv(i2c_slave *s)
159 165 dev->mode = SMBUS_DONE;
160 166 break;
161 167 case SMBUS_READ_DATA:
162   - if (dev->read_data) {
163   - ret = dev->read_data(dev, dev->command, dev->data_len);
  168 + if (t->read_data) {
  169 + ret = t->read_data(dev, dev->command, dev->data_len);
164 170 dev->data_len++;
165 171 } else {
166 172 ret = 0;
... ... @@ -178,7 +184,8 @@ static int smbus_i2c_recv(i2c_slave *s)
178 184  
179 185 static int smbus_i2c_send(i2c_slave *s, uint8_t data)
180 186 {
181   - SMBusDevice *dev = (SMBusDevice *)s;
  187 + SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
  188 +
182 189 switch (dev->mode) {
183 190 case SMBUS_WRITE_DATA:
184 191 DPRINTF("Write data %02x\n", data);
... ... @@ -191,19 +198,22 @@ static int smbus_i2c_send(i2c_slave *s, uint8_t data)
191 198 return 0;
192 199 }
193 200  
194   -SMBusDevice *smbus_device_init(i2c_bus *bus, int address, int size)
  201 +static void smbus_device_init(i2c_slave *i2c)
195 202 {
196   - SMBusDevice *dev;
  203 + SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
  204 + SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
197 205  
198   - if (size < sizeof(SMBusDevice))
199   - hw_error("SMBus struct too small");
200   -
201   - dev = (SMBusDevice *)i2c_slave_init(bus, address, size);
202   - dev->i2c.event = smbus_i2c_event;
203   - dev->i2c.recv = smbus_i2c_recv;
204   - dev->i2c.send = smbus_i2c_send;
  206 + t->init(dev);
  207 +}
205 208  
206   - return dev;
  209 +void smbus_register_device(const char *name, int size, SMBusDeviceInfo *info)
  210 +{
  211 + assert(size >= sizeof(SMBusDevice));
  212 + info->i2c.init = smbus_device_init;
  213 + info->i2c.event = smbus_i2c_event;
  214 + info->i2c.recv = smbus_i2c_recv;
  215 + info->i2c.send = smbus_i2c_send;
  216 + i2c_register_slave(name, size, &info->i2c);
207 217 }
208 218  
209 219 /* Master device commands. */
... ...
hw/smbus.h
... ... @@ -28,7 +28,16 @@ struct SMBusDevice {
28 28 /* The SMBus protocol is implemented on top of I2C. */
29 29 i2c_slave i2c;
30 30  
31   - /* Callbacks set by the device. */
  31 + /* Remaining fields for internal use only. */
  32 + int mode;
  33 + int data_len;
  34 + uint8_t data_buf[34]; /* command + len + 32 bytes of data. */
  35 + uint8_t command;
  36 +};
  37 +
  38 +typedef struct {
  39 + I2CSlaveInfo i2c;
  40 + void (*init)(SMBusDevice *dev);
32 41 void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
33 42 void (*send_byte)(SMBusDevice *dev, uint8_t val);
34 43 uint8_t (*receive_byte)(SMBusDevice *dev);
... ... @@ -42,16 +51,9 @@ struct SMBusDevice {
42 51 byte at a time. The device is responsible for adding the length
43 52 byte on block reads. */
44 53 uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
  54 +} SMBusDeviceInfo;
45 55  
46   - /* Remaining fields for internal use only. */
47   - int mode;
48   - int data_len;
49   - uint8_t data_buf[34]; /* command + len + 32 bytes of data. */
50   - uint8_t command;
51   -};
52   -
53   -/* Create a slave device. */
54   -SMBusDevice *smbus_device_init(i2c_bus *bus, int address, int size);
  56 +void smbus_register_device(const char *name, int size, SMBusDeviceInfo *info);
55 57  
56 58 /* Master device commands. */
57 59 void smbus_quick_command(i2c_bus *bus, int addr, int read);
... ... @@ -64,6 +66,3 @@ void smbus_write_word(i2c_bus *bus, int addr, uint8_t command, uint16_t data);
64 66 int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data);
65 67 void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data,
66 68 int len);
67   -
68   -/* smbus_eeprom.c */
69   -void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf);
... ...
hw/smbus_eeprom.c
... ... @@ -29,7 +29,7 @@
29 29 //#define DEBUG
30 30  
31 31 typedef struct SMBusEEPROMDevice {
32   - SMBusDevice dev;
  32 + SMBusDevice smbusdev;
33 33 uint8_t *data;
34 34 uint8_t offset;
35 35 } SMBusEEPROMDevice;
... ... @@ -95,18 +95,28 @@ static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
95 95 return eeprom_receive_byte(dev);
96 96 }
97 97  
98   -void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf)
  98 +static void smbus_eeprom_init(SMBusDevice *dev)
99 99 {
100   - SMBusEEPROMDevice *eeprom;
  100 + SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
101 101  
102   - eeprom = (SMBusEEPROMDevice *)smbus_device_init(bus, addr,
103   - sizeof(SMBusEEPROMDevice));
104   -
105   - eeprom->dev.quick_cmd = eeprom_quick_cmd;
106   - eeprom->dev.send_byte = eeprom_send_byte;
107   - eeprom->dev.receive_byte = eeprom_receive_byte;
108   - eeprom->dev.write_data = eeprom_write_data;
109   - eeprom->dev.read_data = eeprom_read_data;
110   - eeprom->data = buf;
  102 + /* FIXME: Should be a blob rather than a ptr. */
  103 + eeprom->data = qdev_get_prop_ptr(&dev->i2c.qdev, "data");
111 104 eeprom->offset = 0;
112 105 }
  106 +
  107 +static SMBusDeviceInfo smbus_eeprom_info = {
  108 + .init = smbus_eeprom_init,
  109 + .quick_cmd = eeprom_quick_cmd,
  110 + .send_byte = eeprom_send_byte,
  111 + .receive_byte = eeprom_receive_byte,
  112 + .write_data = eeprom_write_data,
  113 + .read_data = eeprom_read_data
  114 +};
  115 +
  116 +static void smbus_eeprom_register_devices(void)
  117 +{
  118 + smbus_register_device("smbus-eeprom", sizeof(SMBusEEPROMDevice),
  119 + &smbus_eeprom_info);
  120 +}
  121 +
  122 +device_init(smbus_eeprom_register_devices)
... ...