/*
 * GPIO device simulation in PKUnity SoC
 *
 * Copyright (C) 2010-2012 Guan Xuetao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation, or any later version.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "qom/object.h"

#undef DEBUG_PUV3
#include "hw/unicore32/puv3.h"
#include "qemu/module.h"
#include "qemu/log.h"

#define TYPE_PUV3_GPIO "puv3_gpio"
OBJECT_DECLARE_SIMPLE_TYPE(PUV3GPIOState, PUV3_GPIO)

struct PUV3GPIOState {
    SysBusDevice parent_obj;

    MemoryRegion iomem;
    qemu_irq irq[9];

    uint32_t reg_GPLR;
    uint32_t reg_GPDR;
    uint32_t reg_GPIR;
};

static uint64_t puv3_gpio_read(void *opaque, hwaddr offset,
        unsigned size)
{
    PUV3GPIOState *s = opaque;
    uint32_t ret = 0;

    switch (offset) {
    case 0x00:
        ret = s->reg_GPLR;
        break;
    case 0x04:
        ret = s->reg_GPDR;
        break;
    case 0x20:
        ret = s->reg_GPIR;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
                      __func__, offset);
    }
    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);

    return ret;
}

static void puv3_gpio_write(void *opaque, hwaddr offset,
        uint64_t value, unsigned size)
{
    PUV3GPIOState *s = opaque;

    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
    switch (offset) {
    case 0x04:
        s->reg_GPDR = value;
        break;
    case 0x08:
        if (s->reg_GPDR & value) {
            s->reg_GPLR |= value;
        } else {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: Write gpio input port\n",
                          __func__);
        }
        break;
    case 0x0c:
        if (s->reg_GPDR & value) {
            s->reg_GPLR &= ~value;
        } else {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: Write gpio input port\n",
                          __func__);
        }
        break;
    case 0x10: /* GRER */
    case 0x14: /* GFER */
    case 0x18: /* GEDR */
        break;
    case 0x20: /* GPIR */
        s->reg_GPIR = value;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
                      __func__, offset);
    }
}

static const MemoryRegionOps puv3_gpio_ops = {
    .read = puv3_gpio_read,
    .write = puv3_gpio_write,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void puv3_gpio_realize(DeviceState *dev, Error **errp)
{
    PUV3GPIOState *s = PUV3_GPIO(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    s->reg_GPLR = 0;
    s->reg_GPDR = 0;

    /* FIXME: these irqs not handled yet */
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]);
    sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]);

    memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio",
            PUV3_REGS_OFFSET);
    sysbus_init_mmio(sbd, &s->iomem);
}

static void puv3_gpio_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = puv3_gpio_realize;
}

static const TypeInfo puv3_gpio_info = {
    .name = TYPE_PUV3_GPIO,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PUV3GPIOState),
    .class_init = puv3_gpio_class_init,
};

static void puv3_gpio_register_type(void)
{
    type_register_static(&puv3_gpio_info);
}

type_init(puv3_gpio_register_type)
