xref: /openbmc/qemu/hw/input/stellaris_gamepad.c (revision 7c76f397fde313bcdfd3781d64fc28dae0e42df8)
1c45460deSPeter Maydell /*
2c45460deSPeter Maydell  * Gamepad style buttons connected to IRQ/GPIO lines
3c45460deSPeter Maydell  *
4c45460deSPeter Maydell  * Copyright (c) 2007 CodeSourcery.
5c45460deSPeter Maydell  * Written by Paul Brook
6c45460deSPeter Maydell  *
7c45460deSPeter Maydell  * This code is licensed under the GPL.
8c45460deSPeter Maydell  */
9c45460deSPeter Maydell 
10c45460deSPeter Maydell #include "qemu/osdep.h"
11a75f336bSPeter Maydell #include "qapi/error.h"
12c45460deSPeter Maydell #include "hw/input/stellaris_gamepad.h"
13c45460deSPeter Maydell #include "hw/irq.h"
14a75f336bSPeter Maydell #include "hw/qdev-properties.h"
15c45460deSPeter Maydell #include "migration/vmstate.h"
16c45460deSPeter Maydell #include "ui/console.h"
17c45460deSPeter Maydell 
18*7c76f397SPeter Maydell static void stellaris_gamepad_event(DeviceState *dev, QemuConsole *src,
19*7c76f397SPeter Maydell                                     InputEvent *evt)
20c45460deSPeter Maydell {
21*7c76f397SPeter Maydell     StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
22*7c76f397SPeter Maydell     InputKeyEvent *key = evt->u.key.data;
23*7c76f397SPeter Maydell     int qcode = qemu_input_key_value_to_qcode(key->key);
24c45460deSPeter Maydell     int i;
25c45460deSPeter Maydell 
26c45460deSPeter Maydell     for (i = 0; i < s->num_buttons; i++) {
27*7c76f397SPeter Maydell         if (s->keycodes[i] == qcode && s->pressed[i] != key->down) {
28*7c76f397SPeter Maydell             s->pressed[i] = key->down;
29*7c76f397SPeter Maydell             qemu_set_irq(s->irqs[i], key->down);
30c45460deSPeter Maydell         }
31c45460deSPeter Maydell     }
32c45460deSPeter Maydell }
33c45460deSPeter Maydell 
34c45460deSPeter Maydell static const VMStateDescription vmstate_stellaris_gamepad = {
35c45460deSPeter Maydell     .name = "stellaris_gamepad",
36*7c76f397SPeter Maydell     .version_id = 4,
37*7c76f397SPeter Maydell     .minimum_version_id = 4,
38c45460deSPeter Maydell     .fields = (VMStateField[]) {
395f8d505eSPeter Maydell         VMSTATE_VARRAY_UINT32(pressed, StellarisGamepad, num_buttons,
405f8d505eSPeter Maydell                               0, vmstate_info_uint8, uint8_t),
41c45460deSPeter Maydell         VMSTATE_END_OF_LIST()
42c45460deSPeter Maydell     }
43c45460deSPeter Maydell };
44c45460deSPeter Maydell 
45*7c76f397SPeter Maydell static const QemuInputHandler stellaris_gamepad_handler = {
46*7c76f397SPeter Maydell     .name = "Stellaris Gamepad",
47*7c76f397SPeter Maydell     .mask = INPUT_EVENT_MASK_KEY,
48*7c76f397SPeter Maydell     .event = stellaris_gamepad_event,
49*7c76f397SPeter Maydell };
50*7c76f397SPeter Maydell 
51a75f336bSPeter Maydell static void stellaris_gamepad_realize(DeviceState *dev, Error **errp)
52c45460deSPeter Maydell {
53a75f336bSPeter Maydell     StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
54c45460deSPeter Maydell 
55a75f336bSPeter Maydell     if (s->num_buttons == 0) {
56a75f336bSPeter Maydell         error_setg(errp, "keycodes property array must be set");
57a75f336bSPeter Maydell         return;
58c45460deSPeter Maydell     }
59a75f336bSPeter Maydell 
60a75f336bSPeter Maydell     s->irqs = g_new0(qemu_irq, s->num_buttons);
61a75f336bSPeter Maydell     s->pressed = g_new0(uint8_t, s->num_buttons);
62a75f336bSPeter Maydell     qdev_init_gpio_out(dev, s->irqs, s->num_buttons);
63*7c76f397SPeter Maydell     qemu_input_handler_register(dev, &stellaris_gamepad_handler);
64c45460deSPeter Maydell }
65a75f336bSPeter Maydell 
66a75f336bSPeter Maydell static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
67a75f336bSPeter Maydell {
68a75f336bSPeter Maydell     StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
69a75f336bSPeter Maydell 
70a75f336bSPeter Maydell     memset(s->pressed, 0, s->num_buttons * sizeof(uint8_t));
71a75f336bSPeter Maydell }
72a75f336bSPeter Maydell 
73a75f336bSPeter Maydell static Property stellaris_gamepad_properties[] = {
74a75f336bSPeter Maydell     DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons,
75a75f336bSPeter Maydell                       keycodes, qdev_prop_uint32, uint32_t),
76a75f336bSPeter Maydell     DEFINE_PROP_END_OF_LIST(),
77a75f336bSPeter Maydell };
78a75f336bSPeter Maydell 
79a75f336bSPeter Maydell static void stellaris_gamepad_class_init(ObjectClass *klass, void *data)
80a75f336bSPeter Maydell {
81a75f336bSPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
82a75f336bSPeter Maydell     ResettableClass *rc = RESETTABLE_CLASS(klass);
83a75f336bSPeter Maydell 
84a75f336bSPeter Maydell     rc->phases.enter = stellaris_gamepad_reset_enter;
85a75f336bSPeter Maydell     dc->realize = stellaris_gamepad_realize;
86a75f336bSPeter Maydell     dc->vmsd = &vmstate_stellaris_gamepad;
87a75f336bSPeter Maydell     device_class_set_props(dc, stellaris_gamepad_properties);
88a75f336bSPeter Maydell }
89a75f336bSPeter Maydell 
90a75f336bSPeter Maydell static const TypeInfo stellaris_gamepad_info[] = {
91a75f336bSPeter Maydell     {
92a75f336bSPeter Maydell         .name = TYPE_STELLARIS_GAMEPAD,
93a75f336bSPeter Maydell         .parent = TYPE_SYS_BUS_DEVICE,
94a75f336bSPeter Maydell         .instance_size = sizeof(StellarisGamepad),
95a75f336bSPeter Maydell         .class_init = stellaris_gamepad_class_init,
96a75f336bSPeter Maydell     },
97a75f336bSPeter Maydell };
98a75f336bSPeter Maydell 
99a75f336bSPeter Maydell DEFINE_TYPES(stellaris_gamepad_info);
100