/*
 * GPIO key
 *
 * Copyright (c) 2016 Linaro Limited
 *
 * Author: Shannon Zhao <shannon.zhao@linaro.org>
 *
 * Emulate a (human) keypress -- when the key is triggered by
 * setting the incoming gpio line, the outbound irq line is
 * raised for 100ms before being dropped again.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qom/object.h"

#define TYPE_GPIOKEY "gpio-key"
OBJECT_DECLARE_SIMPLE_TYPE(GPIOKEYState, GPIOKEY)
#define GPIO_KEY_LATENCY 100 /* 100ms */

struct GPIOKEYState {
    SysBusDevice parent_obj;

    QEMUTimer *timer;
    qemu_irq irq;
};

static const VMStateDescription vmstate_gpio_key = {
    .name = "gpio-key",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_TIMER_PTR(timer, GPIOKEYState),
        VMSTATE_END_OF_LIST()
    }
};

static void gpio_key_reset(DeviceState *dev)
{
    GPIOKEYState *s = GPIOKEY(dev);

    timer_del(s->timer);
}

static void gpio_key_timer_expired(void *opaque)
{
    GPIOKEYState *s = (GPIOKEYState *)opaque;

    qemu_set_irq(s->irq, 0);
    timer_del(s->timer);
}

static void gpio_key_set_irq(void *opaque, int irq, int level)
{
    GPIOKEYState *s = (GPIOKEYState *)opaque;

    qemu_set_irq(s->irq, 1);
    timer_mod(s->timer,
              qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + GPIO_KEY_LATENCY);
}

static void gpio_key_realize(DeviceState *dev, Error **errp)
{
    GPIOKEYState *s = GPIOKEY(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    sysbus_init_irq(sbd, &s->irq);
    qdev_init_gpio_in(dev, gpio_key_set_irq, 1);
    s->timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, gpio_key_timer_expired, s);
}

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

    dc->realize = gpio_key_realize;
    dc->vmsd = &vmstate_gpio_key;
    device_class_set_legacy_reset(dc, gpio_key_reset);
}

static const TypeInfo gpio_key_info = {
    .name          = TYPE_GPIOKEY,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(GPIOKEYState),
    .class_init    = gpio_key_class_init,
};

static void gpio_key_register_types(void)
{
    type_register_static(&gpio_key_info);
}

type_init(gpio_key_register_types)
