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,7 +911,11 @@ void mips_malta_init (ram_addr_t ram_size,
911 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */ 911 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
912 for (i = 0; i < 8; i++) { 912 for (i = 0; i < 8; i++) {
913 /* TODO: Populate SPD eeprom data. */ 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 pit = pit_init(0x40, i8259[0]); 920 pit = pit_init(0x40, i8259[0]);
917 DMA_init(0); 921 DMA_init(0);
@@ -1109,7 +1109,11 @@ static void pc_init1(ram_addr_t ram_size, @@ -1109,7 +1109,11 @@ static void pc_init1(ram_addr_t ram_size,
1109 /* TODO: Populate SPD eeprom data. */ 1109 /* TODO: Populate SPD eeprom data. */
1110 smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]); 1110 smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
1111 for (i = 0; i < 8; i++) { 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,33 +37,38 @@ enum {
37 37
38 static void smbus_do_quick_cmd(SMBusDevice *dev, int recv) 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 DPRINTF("Quick Command %d\n", recv); 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 static void smbus_do_write(SMBusDevice *dev) 47 static void smbus_do_write(SMBusDevice *dev)
46 { 48 {
  49 + SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
  50 +
47 if (dev->data_len == 0) { 51 if (dev->data_len == 0) {
48 smbus_do_quick_cmd(dev, 0); 52 smbus_do_quick_cmd(dev, 0);
49 } else if (dev->data_len == 1) { 53 } else if (dev->data_len == 1) {
50 DPRINTF("Send Byte\n"); 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 } else { 58 } else {
55 dev->command = dev->data_buf[0]; 59 dev->command = dev->data_buf[0];
56 DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1); 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 static void smbus_i2c_event(i2c_slave *s, enum i2c_event event) 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 switch (event) { 72 switch (event) {
68 case I2C_START_SEND: 73 case I2C_START_SEND:
69 switch (dev->mode) { 74 switch (dev->mode) {
@@ -145,13 +150,14 @@ static void smbus_i2c_event(i2c_slave *s, enum i2c_event event) @@ -145,13 +150,14 @@ static void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
145 150
146 static int smbus_i2c_recv(i2c_slave *s) 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 int ret; 155 int ret;
150 156
151 switch (dev->mode) { 157 switch (dev->mode) {
152 case SMBUS_RECV_BYTE: 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 } else { 161 } else {
156 ret = 0; 162 ret = 0;
157 } 163 }
@@ -159,8 +165,8 @@ static int smbus_i2c_recv(i2c_slave *s) @@ -159,8 +165,8 @@ static int smbus_i2c_recv(i2c_slave *s)
159 dev->mode = SMBUS_DONE; 165 dev->mode = SMBUS_DONE;
160 break; 166 break;
161 case SMBUS_READ_DATA: 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 dev->data_len++; 170 dev->data_len++;
165 } else { 171 } else {
166 ret = 0; 172 ret = 0;
@@ -178,7 +184,8 @@ static int smbus_i2c_recv(i2c_slave *s) @@ -178,7 +184,8 @@ static int smbus_i2c_recv(i2c_slave *s)
178 184
179 static int smbus_i2c_send(i2c_slave *s, uint8_t data) 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 switch (dev->mode) { 189 switch (dev->mode) {
183 case SMBUS_WRITE_DATA: 190 case SMBUS_WRITE_DATA:
184 DPRINTF("Write data %02x\n", data); 191 DPRINTF("Write data %02x\n", data);
@@ -191,19 +198,22 @@ static int smbus_i2c_send(i2c_slave *s, uint8_t data) @@ -191,19 +198,22 @@ static int smbus_i2c_send(i2c_slave *s, uint8_t data)
191 return 0; 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 /* Master device commands. */ 219 /* Master device commands. */
hw/smbus.h
@@ -28,7 +28,16 @@ struct SMBusDevice { @@ -28,7 +28,16 @@ struct SMBusDevice {
28 /* The SMBus protocol is implemented on top of I2C. */ 28 /* The SMBus protocol is implemented on top of I2C. */
29 i2c_slave i2c; 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 void (*quick_cmd)(SMBusDevice *dev, uint8_t read); 41 void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
33 void (*send_byte)(SMBusDevice *dev, uint8_t val); 42 void (*send_byte)(SMBusDevice *dev, uint8_t val);
34 uint8_t (*receive_byte)(SMBusDevice *dev); 43 uint8_t (*receive_byte)(SMBusDevice *dev);
@@ -42,16 +51,9 @@ struct SMBusDevice { @@ -42,16 +51,9 @@ struct SMBusDevice {
42 byte at a time. The device is responsible for adding the length 51 byte at a time. The device is responsible for adding the length
43 byte on block reads. */ 52 byte on block reads. */
44 uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n); 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 /* Master device commands. */ 58 /* Master device commands. */
57 void smbus_quick_command(i2c_bus *bus, int addr, int read); 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,6 +66,3 @@ void smbus_write_word(i2c_bus *bus, int addr, uint8_t command, uint16_t data);
64 int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data); 66 int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data);
65 void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data, 67 void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data,
66 int len); 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,7 +29,7 @@
29 //#define DEBUG 29 //#define DEBUG
30 30
31 typedef struct SMBusEEPROMDevice { 31 typedef struct SMBusEEPROMDevice {
32 - SMBusDevice dev; 32 + SMBusDevice smbusdev;
33 uint8_t *data; 33 uint8_t *data;
34 uint8_t offset; 34 uint8_t offset;
35 } SMBusEEPROMDevice; 35 } SMBusEEPROMDevice;
@@ -95,18 +95,28 @@ static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n) @@ -95,18 +95,28 @@ static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
95 return eeprom_receive_byte(dev); 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 eeprom->offset = 0; 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)