/*
 * 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 {
    BusState qbus;
};

static struct BusInfo ssi_bus_info = {
    .name = "SSI",
    .size = sizeof(SSIBus),
};

static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
{
    SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev);
    SSISlave *s = SSI_SLAVE_FROM_QDEV(dev);
    SSIBus *bus;

    bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
    if (LIST_FIRST(&bus->qbus.children) != dev
        || LIST_NEXT(dev, sibling) != NULL) {
        hw_error("Too many devices on SSI bus");
    }

    s->info = info;
    info->init(s);
}

void ssi_register_slave(SSISlaveInfo *info)
{
    assert(info->qdev.size >= sizeof(SSISlave));
    info->qdev.init = ssi_slave_init;
    info->qdev.bus_info = &ssi_bus_info;
    qdev_register(&info->qdev);
}

DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
{
    DeviceState *dev;
    dev = qdev_create(&bus->qbus, name);
    qdev_init(dev);
    return dev;
}

SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
{
    BusState *bus;
    bus = qbus_create(&ssi_bus_info, parent, name);
    return FROM_QBUS(SSIBus, bus);
}

uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
{
    DeviceState *dev;
    SSISlave *slave;
    dev = LIST_FIRST(&bus->qbus.children);
    if (!dev) {
        return 0;
    }
    slave = SSI_SLAVE_FROM_QDEV(dev);
    return slave->info->transfer(slave, val);
}
