summary refs log tree commit diff stats
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)
downloadfocaccia-qemu-0ff596d02fd9d876a31d038255a6d4f89da9dfed.tar.gz
focaccia-qemu-0ff596d02fd9d876a31d038255a6d4f89da9dfed.zip
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;
 }