/*
 * 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 = (const 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_finalize(Object *obj)
{
    StellarisGamepad *s = STELLARIS_GAMEPAD(obj);

    g_free(s->keycodes);
}

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),
        .instance_finalize = stellaris_gamepad_finalize,
        .class_init = stellaris_gamepad_class_init,
    },
};

DEFINE_TYPES(stellaris_gamepad_info);
