qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v1 1/6] i2c: support address ranges


From: Peter Crosthwaite
Subject: [Qemu-devel] [PATCH v1 1/6] i2c: support address ranges
Date: Wed, 20 Feb 2013 15:29:54 +1000

Some I2C devices (eg m24c08) can decode a linear range of addresses
(e.g. 0b10100xx). Add the address_range field to I2C slave that specifies the
number of consecutive addresses the device decodes.

Signed-off-by: Peter Crosthwaite <address@hidden>
---

 hw/i2c.c |   14 ++++++++++----
 hw/i2c.h |    6 ++++++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index ec314a4..a9004e6 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -19,6 +19,7 @@ struct i2c_bus
 
 static Property i2c_props[] = {
     DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
+    DEFINE_PROP_UINT8("address-range", struct I2CSlave, address_range, 1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -93,7 +94,8 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int 
recv)
     QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
         DeviceState *qdev = kid->child;
         I2CSlave *candidate = I2C_SLAVE(qdev);
-        if (candidate->address == address) {
+        if (address >= candidate->address &&
+                address < candidate->address + candidate->address_range) {
             slave = candidate;
             break;
         }
@@ -110,6 +112,9 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int 
recv)
     if (sc->event) {
         sc->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
     }
+    if (sc->decode_address) {
+        sc->decode_address(slave, address);
+    }
     return 0;
 }
 
@@ -192,12 +197,13 @@ static int i2c_slave_post_load(void *opaque, int 
version_id)
 
 const VMStateDescription vmstate_i2c_slave = {
     .name = "I2CSlave",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
     .post_load = i2c_slave_post_load,
     .fields      = (VMStateField []) {
         VMSTATE_UINT8(address, I2CSlave),
+        VMSTATE_UINT8(address_range, I2CSlave),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/i2c.h b/hw/i2c.h
index 0e80d5a..0021125 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -40,6 +40,11 @@ typedef struct I2CSlaveClass
 
     /* Notify the slave of a bus state change.  */
     void (*event)(I2CSlave *s, enum i2c_event event);
+
+    /* Notify the slave what address was decoded. Only needed for slaves that
+     * decode multiple addresses. Called after event() for I2C_START_RECV/SEND
+     */
+    void (*decode_address)(I2CSlave *s, uint8_t address);
 } I2CSlaveClass;
 
 struct I2CSlave
@@ -48,6 +53,7 @@ struct I2CSlave
 
     /* Remaining fields for internal use by the I2C code.  */
     uint8_t address;
+    uint8_t address_range;
 };
 
 i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
-- 
1.7.0.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]