qemu-commits
[Top][All Lists]
Advanced

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

[Qemu-commits] [COMMIT fe8de49] I2C qdev support


From: Anthony Liguori
Subject: [Qemu-commits] [COMMIT fe8de49] I2C qdev support
Date: Thu, 14 May 2009 21:41:32 -0000

From: Paul Brook <address@hidden>

Signed-off-by: Paul Brook <address@hidden>

diff --git a/hw/i2c.c b/hw/i2c.c
index 2d0dd71..e694025 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -7,7 +7,6 @@
  * This code is licenced under the LGPL.
  */
 
-#include "hw.h"
 #include "i2c.h"
 
 struct i2c_bus
@@ -61,7 +60,7 @@ i2c_slave *i2c_slave_init(i2c_bus *bus, int address, int size)
     dev->address = address;
     dev->next = bus->dev;
     bus->dev = dev;
-    dev->bus = bus;
+    dev->qdev.bus = bus;
 
     return dev;
 }
@@ -94,7 +93,7 @@ int i2c_start_transfer(i2c_bus *bus, int address, int recv)
     /* If the bus is already busy, assume this is a repeated
        start condition.  */
     bus->current_dev = dev;
-    dev->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
+    dev->info->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
     return 0;
 }
 
@@ -105,7 +104,7 @@ void i2c_end_transfer(i2c_bus *bus)
     if (!dev)
         return;
 
-    dev->event(dev, I2C_FINISH);
+    dev->info->event(dev, I2C_FINISH);
 
     bus->current_dev = NULL;
 }
@@ -117,7 +116,7 @@ int i2c_send(i2c_bus *bus, uint8_t data)
     if (!dev)
         return -1;
 
-    return dev->send(dev, data);
+    return dev->info->send(dev, data);
 }
 
 int i2c_recv(i2c_bus *bus)
@@ -127,7 +126,7 @@ int i2c_recv(i2c_bus *bus)
     if (!dev)
         return -1;
 
-    return dev->recv(dev);
+    return dev->info->recv(dev);
 }
 
 void i2c_nack(i2c_bus *bus)
@@ -137,7 +136,7 @@ void i2c_nack(i2c_bus *bus)
     if (!dev)
         return;
 
-    dev->event(dev, I2C_NACK);
+    dev->info->event(dev, I2C_NACK);
 }
 
 void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
@@ -147,7 +146,44 @@ void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
 
 void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
 {
+    i2c_bus *bus;
+    bus = qdev_get_bus(&dev->qdev);
     dev->address = qemu_get_byte(f);
-    if (dev->bus->saved_address == dev->address)
-        dev->bus->current_dev = dev;
+    if (bus->saved_address == dev->address) {
+        bus->current_dev = dev;
+    }
+}
+
+static void i2c_slave_qdev_init(DeviceState *dev, void *opaque)
+{
+    I2CSlaveInfo *info = opaque;
+    i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev);
+
+    s->info = info;
+    s->bus = qdev_get_bus(dev);
+    s->address = qdev_get_prop_int(dev, "address", 0);
+    s->next = s->bus->dev;
+    s->bus->dev = s;
+
+    s->event = info->event;
+    s->recv = info->recv;
+    s->send = info->send;
+
+    info->init(s);
+}
+
+void i2c_register_slave(const char *name, int size, I2CSlaveInfo *info)
+{
+    assert(size >= sizeof(i2c_slave));
+    qdev_register(name, size, i2c_slave_qdev_init, info);
+}
+
+DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(bus, name);
+    qdev_set_prop_int(dev, "address", addr);
+    qdev_init(dev);
+    return dev;
 }
diff --git a/hw/i2c.h b/hw/i2c.h
index 870a084..ce092e8 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -1,6 +1,8 @@
 #ifndef QEMU_I2C_H
 #define QEMU_I2C_H
 
+#include "qdev.h"
+
 /* The QEMU I2C implementation only supports simple transfers that complete
    immediately.  It does not support slave devices that need to be able to
    defer their response (eg. CPU slave interfaces where the data is supplied
@@ -20,9 +22,21 @@ typedef int (*i2c_recv_cb)(i2c_slave *s);
 /* Notify the slave of a bus state change.  */
 typedef void (*i2c_event_cb)(i2c_slave *s, enum i2c_event event);
 
+typedef void (*i2c_slave_initfn)(i2c_slave *dev);
+
+typedef struct {
+    /* Callbacks provided by the device.  */
+    i2c_slave_initfn init;
+    i2c_event_cb event;
+    i2c_recv_cb recv;
+    i2c_send_cb send;
+} I2CSlaveInfo;
+
 struct i2c_slave
 {
-    /* Callbacks to be set by the device.  */
+    DeviceState qdev;
+    I2CSlaveInfo *info;
+    /* FIXME: These 3 should go away once all devices have been converted.  */
     i2c_event_cb event;
     i2c_recv_cb recv;
     i2c_send_cb send;
@@ -45,6 +59,13 @@ int i2c_recv(i2c_bus *bus);
 void i2c_slave_save(QEMUFile *f, i2c_slave *dev);
 void i2c_slave_load(QEMUFile *f, i2c_slave *dev);
 
+#define I2C_SLAVE_FROM_QDEV(dev) DO_UPCAST(i2c_slave, qdev, dev)
+#define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
+
+void i2c_register_slave(const char *name, int size, I2CSlaveInfo *type);
+
+DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr);
+
 /* max111x.c */
 typedef struct MAX111xState MAX111xState;
 uint32_t max111x_read(void *opaque);




reply via email to

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