summaryrefslogtreecommitdiff
path: root/hw/smbus_eeprom.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-23 00:03:59 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-23 00:03:59 +0000
commit0ff596d02fd9d876a31d038255a6d4f89da9dfed (patch)
tree754c9dfaee7006ab91d80333141835d9213a6d06 /hw/smbus_eeprom.c
parentc6fdf5fca0149fbc2d05d8d5ad43e3686c37514e (diff)
I2C/SMBus framework.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2845 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/smbus_eeprom.c')
-rw-r--r--hw/smbus_eeprom.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index d401b17565..699bd54175 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -58,37 +58,51 @@ static uint8_t eeprom_receive_byte(SMBusDevice *dev)
return val;
}
-static void eeprom_write_byte(SMBusDevice *dev, uint8_t cmd, uint8_t val)
+static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
{
SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
+ int n;
#ifdef DEBUG
printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", dev->addr,
- cmd, val);
+ cmd, buf[0]);
#endif
- eeprom->data[cmd] = val;
+ /* An page write operation is not a valid SMBus command.
+ It is a block write without a length byte. Fortunately we
+ get the full block anyway. */
+ /* TODO: Should this set the current location? */
+ if (cmd + len > 256)
+ n = 256 - cmd;
+ else
+ n = len;
+ memcpy(eeprom->data + cmd, buf, n);
+ len -= n;
+ if (len)
+ memcpy(eeprom->data, buf + n, len);
}
-static uint8_t eeprom_read_byte(SMBusDevice *dev, uint8_t cmd)
+static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
{
SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
- uint8_t val = eeprom->data[cmd];
-#ifdef DEBUG
- printf("eeprom_read_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n", dev->addr,
- cmd, val);
-#endif
- return val;
+ /* If this is the first byte then set the current position. */
+ if (n == 0)
+ eeprom->offset = cmd;
+ /* As with writes, we implement block reads without the
+ SMBus length byte. */
+ return eeprom_receive_byte(dev);
}
-SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf)
+void smbus_eeprom_device_init(i2c_bus *bus, uint8_t addr, uint8_t *buf)
{
- SMBusEEPROMDevice *eeprom = qemu_mallocz(sizeof(SMBusEEPROMDevice));
- eeprom->dev.addr = addr;
+ SMBusEEPROMDevice *eeprom;
+
+ eeprom = (SMBusEEPROMDevice *)smbus_device_init(bus, addr,
+ sizeof(SMBusEEPROMDevice));
+
eeprom->dev.quick_cmd = eeprom_quick_cmd;
eeprom->dev.send_byte = eeprom_send_byte;
eeprom->dev.receive_byte = eeprom_receive_byte;
- eeprom->dev.write_byte = eeprom_write_byte;
- eeprom->dev.read_byte = eeprom_read_byte;
+ eeprom->dev.write_data = eeprom_write_data;
+ eeprom->dev.read_data = eeprom_read_data;
eeprom->data = buf;
eeprom->offset = 0;
- return (SMBusDevice *) eeprom;
}