diff mbox series

[1/2] hw/i2c/core: add reachable state boolean

Message ID 20210403222810.3481372-2-venture@google.com (mailing list archive)
State New, archived
Headers show
Series hw/i2c: Adds pca954x i2c mux switch device | expand

Commit Message

Patrick Leis April 3, 2021, 10:28 p.m. UTC
An i2c device can be reachable or not, controlled by some external
factor.  This field is leveraged by an i2c mux which presents the
devices on the parent bus when the associated channel is enabled and
otherwise not.

Signed-off-by: Patrick Venture <venture@google.com>
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
Reviewed-by: Hao Wu <wuhaotsh@google.com>
---
 hw/i2c/core.c        | 6 ++++++
 include/hw/i2c/i2c.h | 3 +++
 2 files changed, 9 insertions(+)
diff mbox series

Patch

diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 21ec52ac5a..fa7db4549d 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -18,6 +18,7 @@ 
 #define I2C_BROADCAST 0x00
 
 static Property i2c_props[] = {
+    DEFINE_PROP_BOOL("reachable", struct I2CSlave, reachable, true),
     DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -118,6 +119,9 @@  int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
         QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
             DeviceState *qdev = kid->child;
             I2CSlave *candidate = I2C_SLAVE(qdev);
+            if (!candidate->reachable) {
+                continue;
+            }
             if ((candidate->address == address) || (bus->broadcast)) {
                 node = g_malloc(sizeof(struct I2CNode));
                 node->elt = candidate;
@@ -262,6 +266,7 @@  const VMStateDescription vmstate_i2c_slave = {
     .minimum_version_id = 1,
     .post_load = i2c_slave_post_load,
     .fields = (VMStateField[]) {
+        VMSTATE_BOOL(reachable, I2CSlave),
         VMSTATE_UINT8(address, I2CSlave),
         VMSTATE_END_OF_LIST()
     }
@@ -272,6 +277,7 @@  I2CSlave *i2c_slave_new(const char *name, uint8_t addr)
     DeviceState *dev;
 
     dev = qdev_new(name);
+    qdev_prop_set_bit(dev, "reachable", true);
     qdev_prop_set_uint8(dev, "address", addr);
     return I2C_SLAVE(dev);
 }
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 277dd9f2d6..e5ca15e486 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -44,6 +44,9 @@  struct I2CSlaveClass {
 struct I2CSlave {
     DeviceState qdev;
 
+    /* Whether the i2c child device is reachable from this bus. */
+    bool reachable;
+
     /* Remaining fields for internal use by the I2C code.  */
     uint8_t address;
 };