mirror of https://github.com/proxmox/mirror_qemu
i2c: smbus: convert to QEMU Object Model
This converts two types because smbus is implemented as a subclass of i2c. It's extremely difficult to convert these two independently. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>master
parent
9e07bdf816
commit
b5ea932781
21
hw/ds1338.c
21
hw/ds1338.c
|
@ -118,13 +118,20 @@ static int ds1338_init(I2CSlave *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static I2CSlaveInfo ds1338_info = {
|
||||
.qdev.name = "ds1338",
|
||||
.qdev.size = sizeof(DS1338State),
|
||||
.init = ds1338_init,
|
||||
.event = ds1338_event,
|
||||
.recv = ds1338_recv,
|
||||
.send = ds1338_send,
|
||||
static void ds1338_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = ds1338_init;
|
||||
k->event = ds1338_event;
|
||||
k->recv = ds1338_recv;
|
||||
k->send = ds1338_send;
|
||||
}
|
||||
|
||||
static DeviceInfo ds1338_info = {
|
||||
.name = "ds1338",
|
||||
.size = sizeof(DS1338State),
|
||||
.class_init = ds1338_class_init,
|
||||
};
|
||||
|
||||
static void ds1338_register_devices(void)
|
||||
|
|
85
hw/i2c.c
85
hw/i2c.c
|
@ -83,6 +83,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
|
|||
{
|
||||
DeviceState *qdev;
|
||||
I2CSlave *slave = NULL;
|
||||
I2CSlaveClass *sc;
|
||||
|
||||
QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
|
||||
I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
|
||||
|
@ -92,24 +93,33 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
|
|||
}
|
||||
}
|
||||
|
||||
if (!slave)
|
||||
if (!slave) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
sc = I2C_SLAVE_GET_CLASS(slave);
|
||||
/* If the bus is already busy, assume this is a repeated
|
||||
start condition. */
|
||||
bus->current_dev = slave;
|
||||
slave->info->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
|
||||
if (sc->event) {
|
||||
sc->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_end_transfer(i2c_bus *bus)
|
||||
{
|
||||
I2CSlave *dev = bus->current_dev;
|
||||
I2CSlaveClass *sc;
|
||||
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
dev->info->event(dev, I2C_FINISH);
|
||||
sc = I2C_SLAVE_GET_CLASS(dev);
|
||||
if (sc->event) {
|
||||
sc->event(dev, I2C_FINISH);
|
||||
}
|
||||
|
||||
bus->current_dev = NULL;
|
||||
}
|
||||
|
@ -117,31 +127,50 @@ void i2c_end_transfer(i2c_bus *bus)
|
|||
int i2c_send(i2c_bus *bus, uint8_t data)
|
||||
{
|
||||
I2CSlave *dev = bus->current_dev;
|
||||
I2CSlaveClass *sc;
|
||||
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dev->info->send(dev, data);
|
||||
sc = I2C_SLAVE_GET_CLASS(dev);
|
||||
if (sc->send) {
|
||||
return sc->send(dev, data);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i2c_recv(i2c_bus *bus)
|
||||
{
|
||||
I2CSlave *dev = bus->current_dev;
|
||||
I2CSlaveClass *sc;
|
||||
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dev->info->recv(dev);
|
||||
sc = I2C_SLAVE_GET_CLASS(dev);
|
||||
if (sc->recv) {
|
||||
return sc->recv(dev);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void i2c_nack(i2c_bus *bus)
|
||||
{
|
||||
I2CSlave *dev = bus->current_dev;
|
||||
I2CSlaveClass *sc;
|
||||
|
||||
if (!dev)
|
||||
if (!dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
dev->info->event(dev, I2C_NACK);
|
||||
sc = I2C_SLAVE_GET_CLASS(dev);
|
||||
if (sc->event) {
|
||||
sc->event(dev, I2C_NACK);
|
||||
}
|
||||
}
|
||||
|
||||
static int i2c_slave_post_load(void *opaque, int version_id)
|
||||
|
@ -169,20 +198,23 @@ const VMStateDescription vmstate_i2c_slave = {
|
|||
|
||||
static int i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
|
||||
{
|
||||
I2CSlaveInfo *info = container_of(base, I2CSlaveInfo, qdev);
|
||||
I2CSlave *s = I2C_SLAVE_FROM_QDEV(dev);
|
||||
I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s);
|
||||
|
||||
s->info = info;
|
||||
|
||||
return info->init(s);
|
||||
return sc->init(s);
|
||||
}
|
||||
|
||||
void i2c_register_slave(I2CSlaveInfo *info)
|
||||
void i2c_register_slave_subclass(DeviceInfo *info, const char *parent)
|
||||
{
|
||||
assert(info->qdev.size >= sizeof(I2CSlave));
|
||||
info->qdev.init = i2c_slave_qdev_init;
|
||||
info->qdev.bus_info = &i2c_bus_info;
|
||||
qdev_register(&info->qdev);
|
||||
assert(info->size >= sizeof(I2CSlave));
|
||||
info->init = i2c_slave_qdev_init;
|
||||
info->bus_info = &i2c_bus_info;
|
||||
qdev_register_subclass(info, parent);
|
||||
}
|
||||
|
||||
void i2c_register_slave(DeviceInfo *info)
|
||||
{
|
||||
i2c_register_slave_subclass(info, TYPE_I2C_SLAVE);
|
||||
}
|
||||
|
||||
DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
|
||||
|
@ -194,3 +226,18 @@ DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
|
|||
qdev_init_nofail(dev);
|
||||
return dev;
|
||||
}
|
||||
|
||||
static TypeInfo i2c_slave_type_info = {
|
||||
.name = TYPE_I2C_SLAVE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_size = sizeof(I2CSlave),
|
||||
.abstract = true,
|
||||
.class_size = sizeof(I2CSlaveClass),
|
||||
};
|
||||
|
||||
static void i2c_slave_register_devices(void)
|
||||
{
|
||||
type_register_static(&i2c_slave_type_info);
|
||||
}
|
||||
|
||||
device_init(i2c_slave_register_devices);
|
||||
|
|
40
hw/i2c.h
40
hw/i2c.h
|
@ -17,29 +17,34 @@ enum i2c_event {
|
|||
|
||||
typedef struct I2CSlave I2CSlave;
|
||||
|
||||
/* Master to slave. */
|
||||
typedef int (*i2c_send_cb)(I2CSlave *s, uint8_t data);
|
||||
/* Slave to master. */
|
||||
typedef int (*i2c_recv_cb)(I2CSlave *s);
|
||||
/* Notify the slave of a bus state change. */
|
||||
typedef void (*i2c_event_cb)(I2CSlave *s, enum i2c_event event);
|
||||
#define TYPE_I2C_SLAVE "i2c-slave"
|
||||
#define I2C_SLAVE(obj) \
|
||||
OBJECT_CHECK(I2CSlave, (obj), TYPE_I2C_SLAVE)
|
||||
#define I2C_SLAVE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(I2CSlaveClass, (klass), TYPE_I2C_SLAVE)
|
||||
#define I2C_SLAVE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
|
||||
|
||||
typedef int (*i2c_slave_initfn)(I2CSlave *dev);
|
||||
|
||||
typedef struct {
|
||||
DeviceInfo qdev;
|
||||
typedef struct I2CSlaveClass
|
||||
{
|
||||
DeviceClass parent_class;
|
||||
|
||||
/* Callbacks provided by the device. */
|
||||
i2c_slave_initfn init;
|
||||
i2c_event_cb event;
|
||||
i2c_recv_cb recv;
|
||||
i2c_send_cb send;
|
||||
} I2CSlaveInfo;
|
||||
int (*init)(I2CSlave *dev);
|
||||
|
||||
/* Master to slave. */
|
||||
int (*send)(I2CSlave *s, uint8_t data);
|
||||
|
||||
/* Slave to master. */
|
||||
int (*recv)(I2CSlave *s);
|
||||
|
||||
/* Notify the slave of a bus state change. */
|
||||
void (*event)(I2CSlave *s, enum i2c_event event);
|
||||
} I2CSlaveClass;
|
||||
|
||||
struct I2CSlave
|
||||
{
|
||||
DeviceState qdev;
|
||||
I2CSlaveInfo *info;
|
||||
|
||||
/* Remaining fields for internal use by the I2C code. */
|
||||
uint8_t address;
|
||||
|
@ -57,7 +62,8 @@ int i2c_recv(i2c_bus *bus);
|
|||
#define I2C_SLAVE_FROM_QDEV(dev) DO_UPCAST(I2CSlave, qdev, dev)
|
||||
#define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
|
||||
|
||||
void i2c_register_slave(I2CSlaveInfo *type);
|
||||
void i2c_register_slave(DeviceInfo *type);
|
||||
void i2c_register_slave_subclass(DeviceInfo *info, const char *parent);
|
||||
|
||||
DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr);
|
||||
|
||||
|
|
23
hw/lm832x.c
23
hw/lm832x.c
|
@ -494,14 +494,21 @@ void lm832x_key_event(DeviceState *dev, int key, int state)
|
|||
lm_kbd_irq_update(s);
|
||||
}
|
||||
|
||||
static I2CSlaveInfo lm8323_info = {
|
||||
.qdev.name = "lm8323",
|
||||
.qdev.size = sizeof(LM823KbdState),
|
||||
.qdev.vmsd = &vmstate_lm_kbd,
|
||||
.init = lm8323_init,
|
||||
.event = lm_i2c_event,
|
||||
.recv = lm_i2c_rx,
|
||||
.send = lm_i2c_tx
|
||||
static void lm8323_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = lm8323_init;
|
||||
k->event = lm_i2c_event;
|
||||
k->recv = lm_i2c_rx;
|
||||
k->send = lm_i2c_tx;
|
||||
}
|
||||
|
||||
static DeviceInfo lm8323_info = {
|
||||
.name = "lm8323",
|
||||
.size = sizeof(LM823KbdState),
|
||||
.vmsd = &vmstate_lm_kbd,
|
||||
.class_init = lm8323_class_init,
|
||||
};
|
||||
|
||||
static void lm832x_register_devices(void)
|
||||
|
|
25
hw/max7310.c
25
hw/max7310.c
|
@ -185,15 +185,22 @@ static int max7310_init(I2CSlave *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static I2CSlaveInfo max7310_info = {
|
||||
.qdev.name = "max7310",
|
||||
.qdev.size = sizeof(MAX7310State),
|
||||
.qdev.vmsd = &vmstate_max7310,
|
||||
.qdev.reset = max7310_reset,
|
||||
.init = max7310_init,
|
||||
.event = max7310_event,
|
||||
.recv = max7310_rx,
|
||||
.send = max7310_tx
|
||||
static void max7310_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = max7310_init;
|
||||
k->event = max7310_event;
|
||||
k->recv = max7310_rx;
|
||||
k->send = max7310_tx;
|
||||
}
|
||||
|
||||
static DeviceInfo max7310_info = {
|
||||
.name = "max7310",
|
||||
.size = sizeof(MAX7310State),
|
||||
.vmsd = &vmstate_max7310,
|
||||
.reset = max7310_reset,
|
||||
.class_init = max7310_class_init,
|
||||
};
|
||||
|
||||
static void max7310_register_devices(void)
|
||||
|
|
21
hw/pxa2xx.c
21
hw/pxa2xx.c
|
@ -1472,13 +1472,20 @@ static int pxa2xx_i2c_slave_init(I2CSlave *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static I2CSlaveInfo pxa2xx_i2c_slave_info = {
|
||||
.qdev.name = "pxa2xx-i2c-slave",
|
||||
.qdev.size = sizeof(PXA2xxI2CSlaveState),
|
||||
.init = pxa2xx_i2c_slave_init,
|
||||
.event = pxa2xx_i2c_event,
|
||||
.recv = pxa2xx_i2c_rx,
|
||||
.send = pxa2xx_i2c_tx
|
||||
static void pxapxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = pxa2xx_i2c_slave_init;
|
||||
k->event = pxa2xx_i2c_event;
|
||||
k->recv = pxa2xx_i2c_rx;
|
||||
k->send = pxa2xx_i2c_tx;
|
||||
}
|
||||
|
||||
static DeviceInfo pxa2xx_i2c_slave_info = {
|
||||
.name = "pxa2xx-i2c-slave",
|
||||
.size = sizeof(PXA2xxI2CSlaveState),
|
||||
.class_init = pxapxa2xx_i2c_slave_class_init,
|
||||
};
|
||||
|
||||
PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
|
||||
|
|
75
hw/smbus.c
75
hw/smbus.c
|
@ -37,29 +37,30 @@ enum {
|
|||
|
||||
static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
|
||||
{
|
||||
SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
|
||||
|
||||
DPRINTF("Quick Command %d\n", recv);
|
||||
if (t->quick_cmd)
|
||||
t->quick_cmd(dev, recv);
|
||||
if (sc->quick_cmd) {
|
||||
sc->quick_cmd(dev, recv);
|
||||
}
|
||||
}
|
||||
|
||||
static void smbus_do_write(SMBusDevice *dev)
|
||||
{
|
||||
SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
|
||||
|
||||
if (dev->data_len == 0) {
|
||||
smbus_do_quick_cmd(dev, 0);
|
||||
} else if (dev->data_len == 1) {
|
||||
DPRINTF("Send Byte\n");
|
||||
if (t->send_byte) {
|
||||
t->send_byte(dev, dev->data_buf[0]);
|
||||
if (sc->send_byte) {
|
||||
sc->send_byte(dev, dev->data_buf[0]);
|
||||
}
|
||||
} else {
|
||||
dev->command = dev->data_buf[0];
|
||||
DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
|
||||
if (t->write_data) {
|
||||
t->write_data(dev, dev->command, dev->data_buf + 1,
|
||||
if (sc->write_data) {
|
||||
sc->write_data(dev, dev->command, dev->data_buf + 1,
|
||||
dev->data_len - 1);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ static void smbus_do_write(SMBusDevice *dev)
|
|||
|
||||
static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
|
||||
{
|
||||
SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
|
||||
SMBusDevice *dev = SMBUS_DEVICE(s);
|
||||
|
||||
switch (event) {
|
||||
case I2C_START_SEND:
|
||||
|
@ -150,14 +151,14 @@ static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
|
|||
|
||||
static int smbus_i2c_recv(I2CSlave *s)
|
||||
{
|
||||
SMBusDeviceInfo *t = container_of(s->info, SMBusDeviceInfo, i2c);
|
||||
SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
|
||||
SMBusDevice *dev = SMBUS_DEVICE(s);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
|
||||
int ret;
|
||||
|
||||
switch (dev->mode) {
|
||||
case SMBUS_RECV_BYTE:
|
||||
if (t->receive_byte) {
|
||||
ret = t->receive_byte(dev);
|
||||
if (sc->receive_byte) {
|
||||
ret = sc->receive_byte(dev);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -165,8 +166,8 @@ static int smbus_i2c_recv(I2CSlave *s)
|
|||
dev->mode = SMBUS_DONE;
|
||||
break;
|
||||
case SMBUS_READ_DATA:
|
||||
if (t->read_data) {
|
||||
ret = t->read_data(dev, dev->command, dev->data_len);
|
||||
if (sc->read_data) {
|
||||
ret = sc->read_data(dev, dev->command, dev->data_len);
|
||||
dev->data_len++;
|
||||
} else {
|
||||
ret = 0;
|
||||
|
@ -184,7 +185,7 @@ static int smbus_i2c_recv(I2CSlave *s)
|
|||
|
||||
static int smbus_i2c_send(I2CSlave *s, uint8_t data)
|
||||
{
|
||||
SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
|
||||
SMBusDevice *dev = SMBUS_DEVICE(s);
|
||||
|
||||
switch (dev->mode) {
|
||||
case SMBUS_WRITE_DATA:
|
||||
|
@ -200,20 +201,16 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
|
|||
|
||||
static int smbus_device_init(I2CSlave *i2c)
|
||||
{
|
||||
SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
|
||||
SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
|
||||
SMBusDevice *dev = SMBUS_DEVICE(i2c);
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
|
||||
|
||||
return t->init(dev);
|
||||
return sc->init(dev);
|
||||
}
|
||||
|
||||
void smbus_register_device(SMBusDeviceInfo *info)
|
||||
void smbus_register_device(DeviceInfo *info)
|
||||
{
|
||||
assert(info->i2c.qdev.size >= sizeof(SMBusDevice));
|
||||
info->i2c.init = smbus_device_init;
|
||||
info->i2c.event = smbus_i2c_event;
|
||||
info->i2c.recv = smbus_i2c_recv;
|
||||
info->i2c.send = smbus_i2c_send;
|
||||
i2c_register_slave(&info->i2c);
|
||||
assert(info->size >= sizeof(SMBusDevice));
|
||||
i2c_register_slave_subclass(info, TYPE_SMBUS_DEVICE);
|
||||
}
|
||||
|
||||
/* Master device commands. */
|
||||
|
@ -316,3 +313,29 @@ void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *dat
|
|||
i2c_send(bus, data[i]);
|
||||
i2c_end_transfer(bus);
|
||||
}
|
||||
|
||||
static void smbus_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
sc->init = smbus_device_init;
|
||||
sc->event = smbus_i2c_event;
|
||||
sc->recv = smbus_i2c_recv;
|
||||
sc->send = smbus_i2c_send;
|
||||
}
|
||||
|
||||
static TypeInfo smbus_device_type_info = {
|
||||
.name = TYPE_SMBUS_DEVICE,
|
||||
.parent = TYPE_I2C_SLAVE,
|
||||
.instance_size = sizeof(SMBusDevice),
|
||||
.abstract = true,
|
||||
.class_size = sizeof(SMBusDeviceClass),
|
||||
.class_init = smbus_device_class_init,
|
||||
};
|
||||
|
||||
static void smbus_device_register_devices(void)
|
||||
{
|
||||
type_register_static(&smbus_device_type_info);
|
||||
}
|
||||
|
||||
device_init(smbus_device_register_devices);
|
||||
|
|
42
hw/smbus.h
42
hw/smbus.h
|
@ -1,3 +1,6 @@
|
|||
#ifndef QEMU_SMBUS_H
|
||||
#define QEMU_SMBUS_H
|
||||
|
||||
/*
|
||||
* QEMU SMBus API
|
||||
*
|
||||
|
@ -24,19 +27,17 @@
|
|||
|
||||
#include "i2c.h"
|
||||
|
||||
struct SMBusDevice {
|
||||
/* The SMBus protocol is implemented on top of I2C. */
|
||||
I2CSlave i2c;
|
||||
#define TYPE_SMBUS_DEVICE "smbus-device"
|
||||
#define SMBUS_DEVICE(obj) \
|
||||
OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE)
|
||||
#define SMBUS_DEVICE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE)
|
||||
#define SMBUS_DEVICE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE)
|
||||
|
||||
/* Remaining fields for internal use only. */
|
||||
int mode;
|
||||
int data_len;
|
||||
uint8_t data_buf[34]; /* command + len + 32 bytes of data. */
|
||||
uint8_t command;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
I2CSlaveInfo i2c;
|
||||
typedef struct SMBusDeviceClass
|
||||
{
|
||||
I2CSlaveClass parent_class;
|
||||
int (*init)(SMBusDevice *dev);
|
||||
void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
|
||||
void (*send_byte)(SMBusDevice *dev, uint8_t val);
|
||||
|
@ -51,9 +52,20 @@ typedef struct {
|
|||
byte at a time. The device is responsible for adding the length
|
||||
byte on block reads. */
|
||||
uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
|
||||
} SMBusDeviceInfo;
|
||||
} SMBusDeviceClass;
|
||||
|
||||
void smbus_register_device(SMBusDeviceInfo *info);
|
||||
struct SMBusDevice {
|
||||
/* The SMBus protocol is implemented on top of I2C. */
|
||||
I2CSlave i2c;
|
||||
|
||||
/* Remaining fields for internal use only. */
|
||||
int mode;
|
||||
int data_len;
|
||||
uint8_t data_buf[34]; /* command + len + 32 bytes of data. */
|
||||
uint8_t command;
|
||||
};
|
||||
|
||||
void smbus_register_device(DeviceInfo *info);
|
||||
|
||||
/* Master device commands. */
|
||||
void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read);
|
||||
|
@ -69,3 +81,5 @@ void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *dat
|
|||
|
||||
void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
|
||||
const uint8_t *eeprom_spd, int size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -104,19 +104,26 @@ static int smbus_eeprom_initfn(SMBusDevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SMBusDeviceInfo smbus_eeprom_info = {
|
||||
.i2c.qdev.name = "smbus-eeprom",
|
||||
.i2c.qdev.size = sizeof(SMBusEEPROMDevice),
|
||||
.i2c.qdev.props = (Property[]) {
|
||||
static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
|
||||
{
|
||||
SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
|
||||
|
||||
sc->init = smbus_eeprom_initfn;
|
||||
sc->quick_cmd = eeprom_quick_cmd;
|
||||
sc->send_byte = eeprom_send_byte;
|
||||
sc->receive_byte = eeprom_receive_byte;
|
||||
sc->write_data = eeprom_write_data;
|
||||
sc->read_data = eeprom_read_data;
|
||||
}
|
||||
|
||||
static DeviceInfo smbus_eeprom_info = {
|
||||
.name = "smbus-eeprom",
|
||||
.size = sizeof(SMBusEEPROMDevice),
|
||||
.class_init = smbus_eeprom_class_initfn,
|
||||
.props = (Property[]) {
|
||||
DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
},
|
||||
.init = smbus_eeprom_initfn,
|
||||
.quick_cmd = eeprom_quick_cmd,
|
||||
.send_byte = eeprom_send_byte,
|
||||
.receive_byte = eeprom_receive_byte,
|
||||
.write_data = eeprom_write_data,
|
||||
.read_data = eeprom_read_data
|
||||
};
|
||||
|
||||
static void smbus_eeprom_register_devices(void)
|
||||
|
|
23
hw/ssd0303.c
23
hw/ssd0303.c
|
@ -294,14 +294,21 @@ static int ssd0303_init(I2CSlave *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static I2CSlaveInfo ssd0303_info = {
|
||||
.qdev.name = "ssd0303",
|
||||
.qdev.size = sizeof(ssd0303_state),
|
||||
.qdev.vmsd = &vmstate_ssd0303,
|
||||
.init = ssd0303_init,
|
||||
.event = ssd0303_event,
|
||||
.recv = ssd0303_recv,
|
||||
.send = ssd0303_send
|
||||
static void ssd0303_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = ssd0303_init;
|
||||
k->event = ssd0303_event;
|
||||
k->recv = ssd0303_recv;
|
||||
k->send = ssd0303_send;
|
||||
}
|
||||
|
||||
static DeviceInfo ssd0303_info = {
|
||||
.name = "ssd0303",
|
||||
.size = sizeof(ssd0303_state),
|
||||
.vmsd = &vmstate_ssd0303,
|
||||
.class_init = ssd0303_class_init,
|
||||
};
|
||||
|
||||
static void ssd0303_register_devices(void)
|
||||
|
|
23
hw/tmp105.c
23
hw/tmp105.c
|
@ -226,14 +226,21 @@ static int tmp105_init(I2CSlave *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static I2CSlaveInfo tmp105_info = {
|
||||
.qdev.name = "tmp105",
|
||||
.qdev.size = sizeof(TMP105State),
|
||||
.qdev.vmsd = &vmstate_tmp105,
|
||||
.init = tmp105_init,
|
||||
.event = tmp105_event,
|
||||
.recv = tmp105_rx,
|
||||
.send = tmp105_tx
|
||||
static void tmp105_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = tmp105_init;
|
||||
k->event = tmp105_event;
|
||||
k->recv = tmp105_rx;
|
||||
k->send = tmp105_tx;
|
||||
}
|
||||
|
||||
static DeviceInfo tmp105_info = {
|
||||
.name = "tmp105",
|
||||
.size = sizeof(TMP105State),
|
||||
.vmsd = &vmstate_tmp105,
|
||||
.class_init = tmp105_class_init,
|
||||
};
|
||||
|
||||
static void tmp105_register_devices(void)
|
||||
|
|
21
hw/tosa.c
21
hw/tosa.c
|
@ -259,13 +259,20 @@ static void tosapda_machine_init(void)
|
|||
|
||||
machine_init(tosapda_machine_init);
|
||||
|
||||
static I2CSlaveInfo tosa_dac_info = {
|
||||
.qdev.name = "tosa_dac",
|
||||
.qdev.size = sizeof(TosaDACState),
|
||||
.init = tosa_dac_init,
|
||||
.event = tosa_dac_event,
|
||||
.recv = tosa_dac_recv,
|
||||
.send = tosa_dac_send
|
||||
static void tosa_dac_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = tosa_dac_init;
|
||||
k->event = tosa_dac_event;
|
||||
k->recv = tosa_dac_recv;
|
||||
k->send = tosa_dac_send;
|
||||
}
|
||||
|
||||
static DeviceInfo tosa_dac_info = {
|
||||
.name = "tosa_dac",
|
||||
.size = sizeof(TosaDACState),
|
||||
.class_init = tosa_dac_class_init,
|
||||
};
|
||||
|
||||
static void tosa_ssp_class_init(ObjectClass *klass, void *data)
|
||||
|
|
|
@ -857,14 +857,21 @@ static int twl92230_init(I2CSlave *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static I2CSlaveInfo twl92230_info = {
|
||||
.qdev.name ="twl92230",
|
||||
.qdev.size = sizeof(MenelausState),
|
||||
.qdev.vmsd = &vmstate_menelaus,
|
||||
.init = twl92230_init,
|
||||
.event = menelaus_event,
|
||||
.recv = menelaus_rx,
|
||||
.send = menelaus_tx
|
||||
static void twl92230_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
sc->init = twl92230_init;
|
||||
sc->event = menelaus_event;
|
||||
sc->recv = menelaus_rx;
|
||||
sc->send = menelaus_tx;
|
||||
}
|
||||
|
||||
static DeviceInfo twl92230_info = {
|
||||
.name ="twl92230",
|
||||
.size = sizeof(MenelausState),
|
||||
.vmsd = &vmstate_menelaus,
|
||||
.class_init = twl92230_class_init,
|
||||
};
|
||||
|
||||
static void twl92230_register_devices(void)
|
||||
|
|
23
hw/wm8750.c
23
hw/wm8750.c
|
@ -689,14 +689,21 @@ void wm8750_set_bclk_in(void *opaque, int new_hz)
|
|||
wm8750_clk_update(s, 1);
|
||||
}
|
||||
|
||||
static I2CSlaveInfo wm8750_info = {
|
||||
.qdev.name = "wm8750",
|
||||
.qdev.size = sizeof(WM8750State),
|
||||
.qdev.vmsd = &vmstate_wm8750,
|
||||
.init = wm8750_init,
|
||||
.event = wm8750_event,
|
||||
.recv = wm8750_rx,
|
||||
.send = wm8750_tx
|
||||
static void wm8750_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
sc->init = wm8750_init;
|
||||
sc->event = wm8750_event;
|
||||
sc->recv = wm8750_rx;
|
||||
sc->send = wm8750_tx;
|
||||
}
|
||||
|
||||
static DeviceInfo wm8750_info = {
|
||||
.name = "wm8750",
|
||||
.size = sizeof(WM8750State),
|
||||
.vmsd = &vmstate_wm8750,
|
||||
.class_init = wm8750_class_init,
|
||||
};
|
||||
|
||||
static void wm8750_register_devices(void)
|
||||
|
|
23
hw/z2.c
23
hw/z2.c
|
@ -273,14 +273,21 @@ static VMStateDescription vmstate_aer915_state = {
|
|||
}
|
||||
};
|
||||
|
||||
static I2CSlaveInfo aer915_info = {
|
||||
.qdev.name = "aer915",
|
||||
.qdev.size = sizeof(AER915State),
|
||||
.qdev.vmsd = &vmstate_aer915_state,
|
||||
.init = aer915_init,
|
||||
.event = aer915_event,
|
||||
.recv = aer915_recv,
|
||||
.send = aer915_send
|
||||
static void aer915_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = aer915_init;
|
||||
k->event = aer915_event;
|
||||
k->recv = aer915_recv;
|
||||
k->send = aer915_send;
|
||||
}
|
||||
|
||||
static DeviceInfo aer915_info = {
|
||||
.name = "aer915",
|
||||
.size = sizeof(AER915State),
|
||||
.vmsd = &vmstate_aer915_state,
|
||||
.class_init = aer915_class_init,
|
||||
};
|
||||
|
||||
static void z2_init(ram_addr_t ram_size,
|
||||
|
|
Loading…
Reference in New Issue