diff options
author | Paul Brook <paul@codesourcery.com> | 2009-05-14 22:35:09 +0100 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2009-05-14 22:35:09 +0100 |
commit | 90d37239d4051281d2882117efc73020046c32ca (patch) | |
tree | e9861ffff211a45026d66271e4889b7d410e1a49 /hw | |
parent | 1de9610c8ff80aa2a47b6cbe8c198b935916feda (diff) |
SSP bus framework
Signed-off-by: Paul Brook <paul@codesourcery.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ssi.c | 52 | ||||
-rw-r--r-- | hw/ssi.h | 41 |
2 files changed, 93 insertions, 0 deletions
diff --git a/hw/ssi.c b/hw/ssi.c new file mode 100644 index 0000000000..9dfdbe94f8 --- /dev/null +++ b/hw/ssi.c @@ -0,0 +1,52 @@ +/* + * QEMU Synchronous Serial Interface support + * + * Copyright (c) 2009 CodeSourcery. + * Written by Paul Brook + * + * This code is licenced under the GNU GPL v2. + */ + +#include "ssi.h" + +struct SSIBus { + SSISlave *slave; +}; + +static void ssi_slave_init(DeviceState *dev, void *opaque) +{ + SSISlaveInfo *info = opaque; + SSISlave *s = SSI_SLAVE_FROM_QDEV(dev); + SSIBus *bus = qdev_get_bus(dev); + + bus->slave = s; + s->info = info; + info->init(s); +} + +void ssi_register_slave(const char *name, int size, SSISlaveInfo *info) +{ + assert(size >= sizeof(SSISlave)); + qdev_register(name, size, ssi_slave_init, info); +} + +DeviceState *ssi_create_slave(SSIBus *bus, const char *name) +{ + DeviceState *dev; + dev = qdev_create(bus, name); + qdev_init(dev); + return dev; +} + +SSIBus *ssi_create_bus(void) +{ + return qemu_mallocz(sizeof(SSIBus)); +} + +uint32_t ssi_transfer(SSIBus *bus, uint32_t val) +{ + if (!bus->slave) { + return 0; + } + return bus->slave->info->transfer(bus->slave, val); +} diff --git a/hw/ssi.h b/hw/ssi.h new file mode 100644 index 0000000000..d9865e64de --- /dev/null +++ b/hw/ssi.h @@ -0,0 +1,41 @@ +/* QEMU Synchronous Serial Interface support. */ + +/* In principle SSI is a point-point interface. As such the qemu + implementation has a single slave device on a "bus". + However it is fairly common for boards to have multiple slaves + connected to a single master, and select devices with an external + chip select. This is implemented in qemu by having an explicit mux device. + It is assumed that master and slave are both using the same transfer width. + */ + +#ifndef QEMU_SSI_H +#define QEMU_SSI_H + +#include "qdev.h" + +typedef struct SSISlave SSISlave; + +/* Slave devices. */ +typedef struct { + void (*init)(SSISlave *dev); + uint32_t (*transfer)(SSISlave *dev, uint32_t val); +} SSISlaveInfo; + +struct SSISlave { + DeviceState qdev; + SSISlaveInfo *info; +}; + +#define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev) +#define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev) + +void ssi_register_slave(const char *name, int size, SSISlaveInfo *info); + +DeviceState *ssi_create_slave(SSIBus *bus, const char *name); + +/* Master interface. */ +SSIBus *ssi_create_bus(void); + +uint32_t ssi_transfer(SSIBus *bus, uint32_t val); + +#endif |