1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "hw/sysbus.h"
27
28#define TYPE_GPIOKEY "gpio-key"
29#define GPIOKEY(obj) OBJECT_CHECK(GPIOKEYState, (obj), TYPE_GPIOKEY)
30#define GPIO_KEY_LATENCY 100
31
32typedef struct GPIOKEYState {
33 SysBusDevice parent_obj;
34
35 QEMUTimer *timer;
36 qemu_irq irq;
37} GPIOKEYState;
38
39static const VMStateDescription vmstate_gpio_key = {
40 .name = "gpio-key",
41 .version_id = 1,
42 .minimum_version_id = 1,
43 .fields = (VMStateField[]) {
44 VMSTATE_TIMER_PTR(timer, GPIOKEYState),
45 VMSTATE_END_OF_LIST()
46 }
47};
48
49static void gpio_key_reset(DeviceState *dev)
50{
51 GPIOKEYState *s = GPIOKEY(dev);
52
53 timer_del(s->timer);
54}
55
56static void gpio_key_timer_expired(void *opaque)
57{
58 GPIOKEYState *s = (GPIOKEYState *)opaque;
59
60 qemu_set_irq(s->irq, 0);
61 timer_del(s->timer);
62}
63
64static void gpio_key_set_irq(void *opaque, int irq, int level)
65{
66 GPIOKEYState *s = (GPIOKEYState *)opaque;
67
68 qemu_set_irq(s->irq, 1);
69 timer_mod(s->timer,
70 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + GPIO_KEY_LATENCY);
71}
72
73static void gpio_key_realize(DeviceState *dev, Error **errp)
74{
75 GPIOKEYState *s = GPIOKEY(dev);
76 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
77
78 sysbus_init_irq(sbd, &s->irq);
79 qdev_init_gpio_in(dev, gpio_key_set_irq, 1);
80 s->timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, gpio_key_timer_expired, s);
81}
82
83static void gpio_key_class_init(ObjectClass *klass, void *data)
84{
85 DeviceClass *dc = DEVICE_CLASS(klass);
86
87 dc->realize = gpio_key_realize;
88 dc->vmsd = &vmstate_gpio_key;
89 dc->reset = &gpio_key_reset;
90}
91
92static const TypeInfo gpio_key_info = {
93 .name = TYPE_GPIOKEY,
94 .parent = TYPE_SYS_BUS_DEVICE,
95 .instance_size = sizeof(GPIOKEYState),
96 .class_init = gpio_key_class_init,
97};
98
99static void gpio_key_register_types(void)
100{
101 type_register_static(&gpio_key_info);
102}
103
104type_init(gpio_key_register_types)
105