Commit 0ff596d02fd9d876a31d038255a6d4f89da9dfed

Authored by pbrook
1 parent c6fdf5fc

I2C/SMBus framework.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2845 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -402,6 +402,8 @@ SOUND_HW += fmopl.o adlib.o
402 402 endif
403 403 AUDIODRV+= wavcapture.o
404 404  
  405 +VL_OBJS += i2c.o smbus.o
  406 +
405 407 # SCSI layer
406 408 VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
407 409  
... ...
hw/acpi.c
... ... @@ -35,7 +35,7 @@ typedef struct PIIX4PMState {
35 35 uint8_t apms;
36 36 QEMUTimer *tmr_timer;
37 37 int64_t tmr_overflow_time;
38   - SMBusDevice *smb_dev[128];
  38 + i2c_bus *smbus;
39 39 uint8_t smb_stat;
40 40 uint8_t smb_ctl;
41 41 uint8_t smb_cmd;
... ... @@ -63,9 +63,6 @@ typedef struct PIIX4PMState {
63 63 #define SMBHSTDAT1 0x06
64 64 #define SMBBLKDAT 0x07
65 65  
66   -/* Note: only used for piix4_smbus_register_device */
67   -static PIIX4PMState *piix4_pm_state;
68   -
69 66 static uint32_t get_pmtmr(PIIX4PMState *s)
70 67 {
71 68 uint32_t d;
... ... @@ -258,59 +255,44 @@ static void smb_transaction(PIIX4PMState *s)
258 255 uint8_t read = s->smb_addr & 0x01;
259 256 uint8_t cmd = s->smb_cmd;
260 257 uint8_t addr = s->smb_addr >> 1;
261   - SMBusDevice *dev = s->smb_dev[addr];
  258 + i2c_bus *bus = s->smbus;
262 259  
263 260 #ifdef DEBUG
264 261 printf("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
265 262 #endif
266   - if (!dev) goto error;
267   -
268 263 switch(prot) {
269 264 case 0x0:
270   - if (!dev->quick_cmd) goto error;
271   - (*dev->quick_cmd)(dev, read);
  265 + smbus_quick_command(bus, addr, read);
272 266 break;
273 267 case 0x1:
274 268 if (read) {
275   - if (!dev->receive_byte) goto error;
276   - s->smb_data0 = (*dev->receive_byte)(dev);
277   - }
278   - else {
279   - if (!dev->send_byte) goto error;
280   - (*dev->send_byte)(dev, cmd);
  269 + s->smb_data0 = smbus_receive_byte(bus, addr);
  270 + } else {
  271 + smbus_send_byte(bus, addr, cmd);
281 272 }
282 273 break;
283 274 case 0x2:
284 275 if (read) {
285   - if (!dev->read_byte) goto error;
286   - s->smb_data0 = (*dev->read_byte)(dev, cmd);
287   - }
288   - else {
289   - if (!dev->write_byte) goto error;
290   - (*dev->write_byte)(dev, cmd, s->smb_data0);
  276 + s->smb_data0 = smbus_read_byte(bus, addr, cmd);
  277 + } else {
  278 + smbus_write_byte(bus, addr, cmd, s->smb_data0);
291 279 }
292 280 break;
293 281 case 0x3:
294 282 if (read) {
295 283 uint16_t val;
296   - if (!dev->read_word) goto error;
297   - val = (*dev->read_word)(dev, cmd);
  284 + val = smbus_read_word(bus, addr, cmd);
298 285 s->smb_data0 = val;
299 286 s->smb_data1 = val >> 8;
300   - }
301   - else {
302   - if (!dev->write_word) goto error;
303   - (*dev->write_word)(dev, cmd, (s->smb_data1 << 8) | s->smb_data0);
  287 + } else {
  288 + smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
304 289 }
305 290 break;
306 291 case 0x5:
307 292 if (read) {
308   - if (!dev->read_block) goto error;
309   - s->smb_data0 = (*dev->read_block)(dev, cmd, s->smb_data);
310   - }
311   - else {
312   - if (!dev->write_block) goto error;
313   - (*dev->write_block)(dev, cmd, s->smb_data0, s->smb_data);
  293 + s->smb_data0 = smbus_read_block(bus, addr, cmd, s->smb_data);
  294 + } else {
  295 + smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
314 296 }
315 297 break;
316 298 default:
... ... @@ -469,7 +451,7 @@ static int pm_load(QEMUFile* f,void* opaque,int version_id)
469 451 return 0;
470 452 }
471 453  
472   -void piix4_pm_init(PCIBus *bus, int devfn)
  454 +i2c_bus *piix4_pm_init(PCIBus *bus, int devfn)
473 455 {
474 456 PIIX4PMState *s;
475 457 uint8_t *pci_conf;
... ... @@ -514,10 +496,7 @@ void piix4_pm_init(PCIBus *bus, int devfn)
514 496 s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
515 497  
516 498 register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s);
517   - piix4_pm_state = s;
518   -}
519 499  
520   -void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr)
521   -{
522   - piix4_pm_state->smb_dev[addr] = dev;
  500 + s->smbus = i2c_init_bus();
  501 + return s->smbus;
523 502 }
... ...
hw/i2c.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU I2C bus interface.
  3 + *
  4 + * Copyright (c) 2007 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the LGPL.
  8 + */
  9 +
  10 +#include "vl.h"
  11 +
  12 +struct i2c_bus
  13 +{
  14 + i2c_slave *current_dev;
  15 + i2c_slave *dev;
  16 +};
  17 +
  18 +/* Create a new I2C bus. */
  19 +i2c_bus *i2c_init_bus(void)
  20 +{
  21 + i2c_bus *bus;
  22 +
  23 + bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus));
  24 + return bus;
  25 +}
  26 +
  27 +/* Create a new slave device. */
  28 +i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size)
  29 +{
  30 + i2c_slave *dev;
  31 +
  32 + if (size < sizeof(i2c_slave))
  33 + cpu_abort(cpu_single_env, "I2C struct too small");
  34 +
  35 + dev = (i2c_slave *)qemu_mallocz(size);
  36 + dev->address = address;
  37 + dev->next = bus->dev;
  38 + bus->dev = dev;
  39 +
  40 + return dev;
  41 +}
  42 +
  43 +void i2c_set_slave_address(i2c_slave *dev, int address)
  44 +{
  45 + dev->address = address;
  46 +}
  47 +
  48 +/* Return nonzero if bus is busy. */
  49 +int i2c_bus_busy(i2c_bus *bus)
  50 +{
  51 + return bus->current_dev != NULL;
  52 +}
  53 +
  54 +/* Returns nonzero if the bus is already busy, or is the address is not
  55 + valid. */
  56 +/* TODO: Make this handle multiple masters. */
  57 +int i2c_start_transfer(i2c_bus *bus, int address, int recv)
  58 +{
  59 + i2c_slave *dev;
  60 +
  61 + for (dev = bus->dev; dev; dev = dev->next) {
  62 + if (dev->address == address)
  63 + break;
  64 + }
  65 +
  66 + if (!dev)
  67 + return 1;
  68 +
  69 + /* If the bus is already busy, assume this is a repeated
  70 + start condition. */
  71 + bus->current_dev = dev;
  72 + dev->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
  73 + return 0;
  74 +}
  75 +
  76 +void i2c_end_transfer(i2c_bus *bus)
  77 +{
  78 + i2c_slave *dev = bus->current_dev;
  79 +
  80 + if (!dev)
  81 + return;
  82 +
  83 + dev->event(dev, I2C_FINISH);
  84 +
  85 + bus->current_dev = NULL;
  86 +}
  87 +
  88 +int i2c_send(i2c_bus *bus, uint8_t data)
  89 +{
  90 + i2c_slave *dev = bus->current_dev;
  91 +
  92 + if (!dev)
  93 + return -1;
  94 +
  95 + return dev->send(dev, data);
  96 +}
  97 +
  98 +int i2c_recv(i2c_bus *bus)
  99 +{
  100 + i2c_slave *dev = bus->current_dev;
  101 +
  102 + if (!dev)
  103 + return -1;
  104 +
  105 + return dev->recv(dev);
  106 +}
  107 +
  108 +void i2c_nack(i2c_bus *bus)
  109 +{
  110 + i2c_slave *dev = bus->current_dev;
  111 +
  112 + if (!dev)
  113 + return;
  114 +
  115 + dev->event(dev, I2C_NACK);
  116 +}
  117 +
... ...
hw/i2c.h 0 โ†’ 100644
  1 +#ifndef QEMU_I2C_H
  2 +#define QEMU_I2C_H
  3 +
  4 +/* The QEMU I2C implementation only supports simple transfers that complete
  5 + immediately. It does not support slave devices that need to be able to
  6 + defer their response (eg. CPU slave interfaces where the data is supplied
  7 + by the device driver in response to an interrupt). */
  8 +
  9 +enum i2c_event {
  10 + I2C_START_RECV,
  11 + I2C_START_SEND,
  12 + I2C_FINISH,
  13 + I2C_NACK /* Masker NACKed a recieve byte. */
  14 +};
  15 +
  16 +typedef struct i2c_slave i2c_slave;
  17 +
  18 +/* Master to slave. */
  19 +typedef int (*i2c_send_cb)(i2c_slave *s, uint8_t data);
  20 +/* Slave to master. */
  21 +typedef int (*i2c_recv_cb)(i2c_slave *s);
  22 +/* Notify the slave of a bus state change. */
  23 +typedef void (*i2c_event_cb)(i2c_slave *s, enum i2c_event event);
  24 +
  25 +struct i2c_slave
  26 +{
  27 + /* Callbacks to be set by the device. */
  28 + i2c_event_cb event;
  29 + i2c_recv_cb recv;
  30 + i2c_send_cb send;
  31 +
  32 + /* Remaining fields for internal use by the I2C code. */
  33 + int address;
  34 + void *next;
  35 +};
  36 +
  37 +typedef struct i2c_bus i2c_bus;
  38 +
  39 +i2c_bus *i2c_init_bus(void);
  40 +i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size);
  41 +void i2c_set_slave_address(i2c_slave *dev, int address);
  42 +int i2c_bus_busy(i2c_bus *bus);
  43 +int i2c_start_transfer(i2c_bus *bus, int address, int recv);
  44 +void i2c_end_transfer(i2c_bus *bus);
  45 +void i2c_nack(i2c_bus *bus);
  46 +int i2c_send(i2c_bus *bus, uint8_t data);
  47 +int i2c_recv(i2c_bus *bus);
  48 +
  49 +#endif
... ...
... ... @@ -897,11 +897,12 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
897 897  
898 898 if (pci_enabled && acpi_enabled) {
899 899 uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
900   - piix4_pm_init(pci_bus, piix3_devfn + 3);
  900 + i2c_bus *smbus;
  901 +
  902 + /* TODO: Populate SPD eeprom data. */
  903 + smbus = piix4_pm_init(pci_bus, piix3_devfn + 3);
901 904 for (i = 0; i < 8; i++) {
902   - SMBusDevice *eeprom = smbus_eeprom_device_init(0x50 + i,
903   - eeprom_buf + (i * 256));
904   - piix4_smbus_register_device(eeprom, 0x50 + i);
  905 + smbus_eeprom_device_init(smbus, 0x50 + i, eeprom_buf + (i * 256));
905 906 }
906 907 }
907 908  
... ...
hw/smbus.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU SMBus device emulation.
  3 + *
  4 + * Copyright (c) 2007 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the LGPL.
  8 + */
  9 +
  10 +/* TODO: Implement PEC. */
  11 +
  12 +#include "vl.h"
  13 +
  14 +//#define DEBUG_SMBUS 1
  15 +
  16 +#ifdef DEBUG_SMBUS
  17 +#define DPRINTF(fmt, args...) \
  18 +do { printf("smbus(%02x): " fmt , dev->i2c.address, ##args); } while (0)
  19 +#define BADF(fmt, args...) \
  20 +do { fprintf(stderr, "smbus: error: " fmt , ##args); exit(1);} while (0)
  21 +#else
  22 +#define DPRINTF(fmt, args...) do {} while(0)
  23 +#define BADF(fmt, args...) \
  24 +do { fprintf(stderr, "smbus: error: " fmt , ##args);} while (0)
  25 +#endif
  26 +
  27 +enum {
  28 + SMBUS_IDLE,
  29 + SMBUS_WRITE_DATA,
  30 + SMBUS_RECV_BYTE,
  31 + SMBUS_READ_DATA,
  32 + SMBUS_DONE,
  33 + SMBUS_CONFUSED = -1
  34 +};
  35 +
  36 +static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
  37 +{
  38 + DPRINTF("Quick Command %d\n", recv);
  39 + if (dev->quick_cmd)
  40 + dev->quick_cmd(dev, recv);
  41 +}
  42 +
  43 +static void smbus_do_write(SMBusDevice *dev)
  44 +{
  45 + if (dev->data_len == 0) {
  46 + smbus_do_quick_cmd(dev, 0);
  47 + } else if (dev->data_len == 1) {
  48 + DPRINTF("Send Byte\n");
  49 + if (dev->send_byte) {
  50 + dev->send_byte(dev, dev->data_buf[0]);
  51 + }
  52 + } else {
  53 + dev->command = dev->data_buf[0];
  54 + DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
  55 + if (dev->write_data) {
  56 + dev->write_data(dev, dev->command, dev->data_buf + 1,
  57 + dev->data_len - 1);
  58 + }
  59 + }
  60 +}
  61 +
  62 +void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
  63 +{
  64 + SMBusDevice *dev = (SMBusDevice *)s;
  65 + switch (event) {
  66 + case I2C_START_SEND:
  67 + switch (dev->mode) {
  68 + case SMBUS_IDLE:
  69 + DPRINTF("Incoming data\n");
  70 + dev->mode = SMBUS_WRITE_DATA;
  71 + break;
  72 + default:
  73 + BADF("Unexpected send start condition in state %d\n", dev->mode);
  74 + dev->mode = SMBUS_CONFUSED;
  75 + break;
  76 + }
  77 + break;
  78 +
  79 + case I2C_START_RECV:
  80 + switch (dev->mode) {
  81 + case SMBUS_IDLE:
  82 + DPRINTF("Read mode\n");
  83 + dev->mode = SMBUS_RECV_BYTE;
  84 + break;
  85 + case SMBUS_WRITE_DATA:
  86 + if (dev->data_len == 0) {
  87 + BADF("Read after write with no data\n");
  88 + dev->mode = SMBUS_CONFUSED;
  89 + } else {
  90 + if (dev->data_len > 1) {
  91 + smbus_do_write(dev);
  92 + } else {
  93 + dev->command = dev->data_buf[0];
  94 + DPRINTF("%02x: Command %d\n", dev->i2c.address,
  95 + dev->command);
  96 + }
  97 + DPRINTF("Read mode\n");
  98 + dev->data_len = 0;
  99 + dev->mode = SMBUS_READ_DATA;
  100 + }
  101 + break;
  102 + default:
  103 + BADF("Unexpected recv start condition in state %d\n", dev->mode);
  104 + dev->mode = SMBUS_CONFUSED;
  105 + break;
  106 + }
  107 + break;
  108 +
  109 + case I2C_FINISH:
  110 + switch (dev->mode) {
  111 + case SMBUS_WRITE_DATA:
  112 + smbus_do_write(dev);
  113 + break;
  114 + case SMBUS_RECV_BYTE:
  115 + smbus_do_quick_cmd(dev, 1);
  116 + break;
  117 + case SMBUS_READ_DATA:
  118 + BADF("Unexpected stop during receive\n");
  119 + break;
  120 + default:
  121 + /* Nothing to do. */
  122 + break;
  123 + }
  124 + dev->mode = SMBUS_IDLE;
  125 + dev->data_len = 0;
  126 + break;
  127 +
  128 + case I2C_NACK:
  129 + switch (dev->mode) {
  130 + case SMBUS_DONE:
  131 + /* Nothing to do. */
  132 + break;
  133 + case SMBUS_READ_DATA:
  134 + dev->mode = SMBUS_DONE;
  135 + break;
  136 + default:
  137 + BADF("Unexpected NACK in state %d\n", dev->mode);
  138 + dev->mode = SMBUS_CONFUSED;
  139 + break;
  140 + }
  141 + }
  142 +}
  143 +
  144 +static int smbus_i2c_recv(i2c_slave *s)
  145 +{
  146 + SMBusDevice *dev = (SMBusDevice *)s;
  147 + int ret;
  148 +
  149 + switch (dev->mode) {
  150 + case SMBUS_RECV_BYTE:
  151 + if (dev->receive_byte) {
  152 + ret = dev->receive_byte(dev);
  153 + } else {
  154 + ret = 0;
  155 + }
  156 + DPRINTF("Receive Byte %02x\n", ret);
  157 + dev->mode = SMBUS_DONE;
  158 + break;
  159 + case SMBUS_READ_DATA:
  160 + if (dev->read_data) {
  161 + ret = dev->read_data(dev, dev->command, dev->data_len);
  162 + dev->data_len++;
  163 + } else {
  164 + ret = 0;
  165 + }
  166 + DPRINTF("Read data %02x\n", ret);
  167 + break;
  168 + default:
  169 + BADF("Unexpected read in state %d\n", dev->mode);
  170 + dev->mode = SMBUS_CONFUSED;
  171 + ret = 0;
  172 + break;
  173 + }
  174 + return ret;
  175 +}
  176 +
  177 +static int smbus_i2c_send(i2c_slave *s, uint8_t data)
  178 +{
  179 + SMBusDevice *dev = (SMBusDevice *)s;
  180 + switch (dev->mode) {
  181 + case SMBUS_WRITE_DATA:
  182 + DPRINTF("Write data %02x\n", data);
  183 + dev->data_buf[dev->data_len++] = data;
  184 + break;
  185 + default:
  186 + BADF("Unexpected write in state %d\n", dev->mode);
  187 + break;
  188 + }
  189 + return 0;
  190 +}
  191 +
  192 +SMBusDevice *smbus_device_init(i2c_bus *bus, int address, int size)
  193 +{
  194 + SMBusDevice *dev;
  195 +
  196 + dev = (SMBusDevice *)i2c_slave_init(bus, address, size);
  197 + dev->i2c.event = smbus_i2c_event;
  198 + dev->i2c.recv = smbus_i2c_recv;
  199 + dev->i2c.send = smbus_i2c_send;
  200 +
  201 + return dev;
  202 +}
  203 +
  204 +/* Master device commands. */
  205 +void smbus_quick_command(i2c_bus *bus, int addr, int read)
  206 +{
  207 + i2c_start_transfer(bus, addr, read);
  208 + i2c_end_transfer(bus);
  209 +}
  210 +
  211 +uint8_t smbus_receive_byte(i2c_bus *bus, int addr)
  212 +{
  213 + uint8_t data;
  214 +
  215 + i2c_start_transfer(bus, addr, 1);
  216 + data = i2c_recv(bus);
  217 + i2c_nack(bus);
  218 + i2c_end_transfer(bus);
  219 + return data;
  220 +}
  221 +
  222 +void smbus_send_byte(i2c_bus *bus, int addr, uint8_t data)
  223 +{
  224 + i2c_start_transfer(bus, addr, 0);
  225 + i2c_send(bus, data);
  226 + i2c_end_transfer(bus);
  227 +}
  228 +
  229 +uint8_t smbus_read_byte(i2c_bus *bus, int addr, uint8_t command)
  230 +{
  231 + uint8_t data;
  232 + i2c_start_transfer(bus, addr, 0);
  233 + i2c_send(bus, command);
  234 + i2c_start_transfer(bus, addr, 1);
  235 + data = i2c_recv(bus);
  236 + i2c_nack(bus);
  237 + i2c_end_transfer(bus);
  238 + return data;
  239 +}
  240 +
  241 +void smbus_write_byte(i2c_bus *bus, int addr, uint8_t command, uint8_t data)
  242 +{
  243 + i2c_start_transfer(bus, addr, 0);
  244 + i2c_send(bus, command);
  245 + i2c_send(bus, data);
  246 + i2c_end_transfer(bus);
  247 +}
  248 +
  249 +uint16_t smbus_read_word(i2c_bus *bus, int addr, uint8_t command)
  250 +{
  251 + uint16_t data;
  252 + i2c_start_transfer(bus, addr, 0);
  253 + i2c_send(bus, command);
  254 + i2c_start_transfer(bus, addr, 1);
  255 + data = i2c_recv(bus);
  256 + data |= i2c_recv(bus) << 8;
  257 + i2c_nack(bus);
  258 + i2c_end_transfer(bus);
  259 + return data;
  260 +}
  261 +
  262 +void smbus_write_word(i2c_bus *bus, int addr, uint8_t command, uint16_t data)
  263 +{
  264 + i2c_start_transfer(bus, addr, 0);
  265 + i2c_send(bus, command);
  266 + i2c_send(bus, data & 0xff);
  267 + i2c_send(bus, data >> 8);
  268 + i2c_end_transfer(bus);
  269 +}
  270 +
  271 +int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data)
  272 +{
  273 + int len;
  274 + int i;
  275 +
  276 + i2c_start_transfer(bus, addr, 0);
  277 + i2c_send(bus, command);
  278 + i2c_start_transfer(bus, addr, 1);
  279 + len = i2c_recv(bus);
  280 + if (len > 32)
  281 + len = 0;
  282 + for (i = 0; i < len; i++)
  283 + data[i] = i2c_recv(bus);
  284 + i2c_nack(bus);
  285 + i2c_end_transfer(bus);
  286 + return len;
  287 +}
  288 +
  289 +void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data,
  290 + int len)
  291 +{
  292 + int i;
  293 +
  294 + if (len > 32)
  295 + len = 32;
  296 +
  297 + i2c_start_transfer(bus, addr, 0);
  298 + i2c_send(bus, command);
  299 + i2c_send(bus, len);
  300 + for (i = 0; i < len; i++)
  301 + i2c_send(bus, data[i]);
  302 + i2c_end_transfer(bus);
  303 +}
... ...
hw/smbus.h
... ... @@ -25,14 +25,46 @@
25 25 typedef struct SMBusDevice SMBusDevice;
26 26  
27 27 struct SMBusDevice {
28   - uint8_t addr;
  28 + /* The SMBus protocol is implemented on top of I2C. */
  29 + i2c_slave i2c;
  30 +
  31 + /* Callbacks set by the device. */
29 32 void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
30 33 void (*send_byte)(SMBusDevice *dev, uint8_t val);
31 34 uint8_t (*receive_byte)(SMBusDevice *dev);
32   - void (*write_byte)(SMBusDevice *dev, uint8_t cmd, uint8_t val);
33   - uint8_t (*read_byte)(SMBusDevice *dev, uint8_t cmd);
34   - void (*write_word)(SMBusDevice *dev, uint8_t cmd, uint16_t val);
35   - uint16_t (*read_word)(SMBusDevice *dev, uint8_t cmd);
36   - void (*write_block)(SMBusDevice *dev, uint8_t cmd, uint8_t len, uint8_t *buf);
37   - uint8_t (*read_block)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf);
  35 + /* We can't distinguish between a word write and a block write with
  36 + length 1, so pass the whole data block including the length byte
  37 + (if present). The device is responsible figuring out what type of
  38 + command this is. */
  39 + void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len);
  40 + /* Likewise we can't distinguish between defferent reads, or even know
  41 + the length of the read until the read is complete, so read data a
  42 + byte at a time. The device is responsible for adding the length
  43 + byte on block reads. */
  44 + uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
  45 +
  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;
38 51 };
  52 +
  53 +/* Create a slave device. */
  54 +SMBusDevice *smbus_device_init(i2c_bus *bus, int address, int size);
  55 +
  56 +/* Master device commands. */
  57 +void smbus_quick_command(i2c_bus *bus, int addr, int read);
  58 +uint8_t smbus_receive_byte(i2c_bus *bus, int addr);
  59 +void smbus_send_byte(i2c_bus *bus, int addr, uint8_t data);
  60 +uint8_t smbus_read_byte(i2c_bus *bus, int addr, uint8_t command);
  61 +void smbus_write_byte(i2c_bus *bus, int addr, uint8_t command, uint8_t data);
  62 +uint16_t smbus_read_word(i2c_bus *bus, int addr, uint8_t command);
  63 +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);
  65 +void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data,
  66 + int len);
  67 +
  68 +/* smbus_eeprom.c */
  69 +void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf);
  70 +
... ...
hw/smbus_eeprom.c
... ... @@ -58,37 +58,51 @@ static uint8_t eeprom_receive_byte(SMBusDevice *dev)
58 58 return val;
59 59 }
60 60  
61   -static void eeprom_write_byte(SMBusDevice *dev, uint8_t cmd, uint8_t val)
  61 +static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
62 62 {
63 63 SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
  64 + int n;
64 65 #ifdef DEBUG
65 66 printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", dev->addr,
66   - cmd, val);
  67 + cmd, buf[0]);
67 68 #endif
68   - eeprom->data[cmd] = val;
  69 + /* An page write operation is not a valid SMBus command.
  70 + It is a block write without a length byte. Fortunately we
  71 + get the full block anyway. */
  72 + /* TODO: Should this set the current location? */
  73 + if (cmd + len > 256)
  74 + n = 256 - cmd;
  75 + else
  76 + n = len;
  77 + memcpy(eeprom->data + cmd, buf, n);
  78 + len -= n;
  79 + if (len)
  80 + memcpy(eeprom->data, buf + n, len);
69 81 }
70 82  
71   -static uint8_t eeprom_read_byte(SMBusDevice *dev, uint8_t cmd)
  83 +static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
72 84 {
73 85 SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
74   - uint8_t val = eeprom->data[cmd];
75   -#ifdef DEBUG
76   - printf("eeprom_read_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", dev->addr,
77   - cmd, val);
78   -#endif
79   - return val;
  86 + /* If this is the first byte then set the current position. */
  87 + if (n == 0)
  88 + eeprom->offset = cmd;
  89 + /* As with writes, we implement block reads without the
  90 + SMBus length byte. */
  91 + return eeprom_receive_byte(dev);
80 92 }
81 93  
82   -SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf)
  94 +void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf)
83 95 {
84   - SMBusEEPROMDevice *eeprom = qemu_mallocz(sizeof(SMBusEEPROMDevice));
85   - eeprom->dev.addr = addr;
  96 + SMBusEEPROMDevice *eeprom;
  97 +
  98 + eeprom = (SMBusEEPROMDevice *)smbus_device_init(bus, addr,
  99 + sizeof(SMBusEEPROMDevice));
  100 +
86 101 eeprom->dev.quick_cmd = eeprom_quick_cmd;
87 102 eeprom->dev.send_byte = eeprom_send_byte;
88 103 eeprom->dev.receive_byte = eeprom_receive_byte;
89   - eeprom->dev.write_byte = eeprom_write_byte;
90   - eeprom->dev.read_byte = eeprom_read_byte;
  104 + eeprom->dev.write_data = eeprom_write_data;
  105 + eeprom->dev.read_data = eeprom_read_data;
91 106 eeprom->data = buf;
92 107 eeprom->offset = 0;
93   - return (SMBusDevice *) eeprom;
94 108 }
... ...
... ... @@ -1126,17 +1126,16 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time);
1126 1126 void pcspk_init(PITState *);
1127 1127 int pcspk_audio_init(AudioState *, qemu_irq *pic);
1128 1128  
  1129 +#include "hw/i2c.h"
  1130 +
1129 1131 #include "hw/smbus.h"
1130 1132  
1131 1133 /* acpi.c */
1132 1134 extern int acpi_enabled;
1133   -void piix4_pm_init(PCIBus *bus, int devfn);
  1135 +i2c_bus *piix4_pm_init(PCIBus *bus, int devfn);
1134 1136 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
1135 1137 void acpi_bios_init(void);
1136 1138  
1137   -/* smbus_eeprom.c */
1138   -SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
1139   -
1140 1139 /* pc.c */
1141 1140 extern QEMUMachine pc_machine;
1142 1141 extern QEMUMachine isapc_machine;
... ...