/*
 * Gamepad style buttons connected to IRQ/GPIO lines
 *
 * Copyright (c) 2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licensed under the GPL.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/input/stellaris_gamepad.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "ui/console.h"

static void stellaris_gamepad_event(DeviceState *dev, QemuConsole *src,
                                    InputEvent *evt)
{
    StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
    InputKeyEvent *key = evt->u.key.data;
    int qcode = qemu_input_key_value_to_qcode(key->key);
    int i;

    for (i = 0; i < s->num_buttons; i++) {
        if (s->keycodes[i] == qcode && s->pressed[i] != key->down) {
            s->pressed[i] = key->down;
            qemu_set_irq(s->irqs[i], key->down);
        }
    }
}

static const VMStateDescription vmstate_stellaris_gamepad = {
    .name = "stellaris_gamepad",
    .version_id = 4,
    .minimum_version_id = 4,
    .fields = (VMStateField[]) {
        VMSTATE_VARRAY_UINT32(pressed, StellarisGamepad, num_buttons,
                              0, vmstate_info_uint8, uint8_t),
        VMSTATE_END_OF_LIST()
    }
};

static const QemuInputHandler stellaris_gamepad_handler = {
    .name = "Stellaris Gamepad",
    .mask = INPUT_EVENT_MASK_KEY,
    .event = stellaris_gamepad_event,
};

static void stellaris_gamepad_realize(DeviceState *dev, Error **errp)
{
    StellarisGamepad *s = STELLARIS_GAMEPAD(dev);

    if (s->num_buttons == 0) {
        error_setg(errp, "keycodes property array must be set");
        return;
    }

    s->irqs = g_new0(qemu_irq, s->num_buttons);
    s->pressed = g_new0(uint8_t, s->num_buttons);
    qdev_init_gpio_out(dev, s->irqs, s->num_buttons);
    qemu_input_handler_register(dev, &stellaris_gamepad_handler);
}

static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
{
    StellarisGamepad *s = STELLARIS_GAMEPAD(obj);

    memset(s->pressed, 0, s->num_buttons * sizeof(uint8_t));
}

static Property stellaris_gamepad_properties[] = {
    DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons,
                      keycodes, qdev_prop_uint32, uint32_t),
    DEFINE_PROP_END_OF_LIST(),
};

static void stellaris_gamepad_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);

    rc->phases.enter = stellaris_gamepad_reset_enter;
    dc->realize = stellaris_gamepad_realize;
    dc->vmsd = &vmstate_stellaris_gamepad;
    device_class_set_props(dc, stellaris_gamepad_properties);
}

static const TypeInfo stellaris_gamepad_info[] = {
    {
        .name = TYPE_STELLARIS_GAMEPAD,
        .parent = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(StellarisGamepad),
        .class_init = stellaris_gamepad_class_init,
    },
};

DEFINE_TYPES(stellaris_gamepad_info);
