xref: /openbmc/qemu/hw/input/stellaris_gamepad.c (revision d328fef93ae757a0dd65ed786a4086e27952eef3)
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 
stellaris_gamepad_event(DeviceState * dev,QemuConsole * src,InputEvent * evt)187c76f397SPeter Maydell static void stellaris_gamepad_event(DeviceState *dev, QemuConsole *src,
197c76f397SPeter Maydell                                     InputEvent *evt)
20c45460deSPeter Maydell {
217c76f397SPeter Maydell     StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
227c76f397SPeter Maydell     InputKeyEvent *key = evt->u.key.data;
237c76f397SPeter 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++) {
277c76f397SPeter Maydell         if (s->keycodes[i] == qcode && s->pressed[i] != key->down) {
287c76f397SPeter Maydell             s->pressed[i] = key->down;
297c76f397SPeter 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",
367c76f397SPeter Maydell     .version_id = 4,
377c76f397SPeter Maydell     .minimum_version_id = 4,
38*af0f07dfSRichard Henderson     .fields = (const 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 
457c76f397SPeter Maydell static const QemuInputHandler stellaris_gamepad_handler = {
467c76f397SPeter Maydell     .name = "Stellaris Gamepad",
477c76f397SPeter Maydell     .mask = INPUT_EVENT_MASK_KEY,
487c76f397SPeter Maydell     .event = stellaris_gamepad_event,
497c76f397SPeter Maydell };
507c76f397SPeter Maydell 
stellaris_gamepad_realize(DeviceState * dev,Error ** errp)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);
637c76f397SPeter Maydell     qemu_input_handler_register(dev, &stellaris_gamepad_handler);
64c45460deSPeter Maydell }
65a75f336bSPeter Maydell 
stellaris_gamepad_finalize(Object * obj)666e782ffdSPhilippe Mathieu-Daudé static void stellaris_gamepad_finalize(Object *obj)
676e782ffdSPhilippe Mathieu-Daudé {
686e782ffdSPhilippe Mathieu-Daudé     StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
696e782ffdSPhilippe Mathieu-Daudé 
706e782ffdSPhilippe Mathieu-Daudé     g_free(s->keycodes);
716e782ffdSPhilippe Mathieu-Daudé }
726e782ffdSPhilippe Mathieu-Daudé 
stellaris_gamepad_reset_enter(Object * obj,ResetType type)73a75f336bSPeter Maydell static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
74a75f336bSPeter Maydell {
75a75f336bSPeter Maydell     StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
76a75f336bSPeter Maydell 
77a75f336bSPeter Maydell     memset(s->pressed, 0, s->num_buttons * sizeof(uint8_t));
78a75f336bSPeter Maydell }
79a75f336bSPeter Maydell 
80a75f336bSPeter Maydell static Property stellaris_gamepad_properties[] = {
81a75f336bSPeter Maydell     DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons,
82a75f336bSPeter Maydell                       keycodes, qdev_prop_uint32, uint32_t),
83a75f336bSPeter Maydell     DEFINE_PROP_END_OF_LIST(),
84a75f336bSPeter Maydell };
85a75f336bSPeter Maydell 
stellaris_gamepad_class_init(ObjectClass * klass,void * data)86a75f336bSPeter Maydell static void stellaris_gamepad_class_init(ObjectClass *klass, void *data)
87a75f336bSPeter Maydell {
88a75f336bSPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
89a75f336bSPeter Maydell     ResettableClass *rc = RESETTABLE_CLASS(klass);
90a75f336bSPeter Maydell 
91a75f336bSPeter Maydell     rc->phases.enter = stellaris_gamepad_reset_enter;
92a75f336bSPeter Maydell     dc->realize = stellaris_gamepad_realize;
93a75f336bSPeter Maydell     dc->vmsd = &vmstate_stellaris_gamepad;
94a75f336bSPeter Maydell     device_class_set_props(dc, stellaris_gamepad_properties);
95a75f336bSPeter Maydell }
96a75f336bSPeter Maydell 
97a75f336bSPeter Maydell static const TypeInfo stellaris_gamepad_info[] = {
98a75f336bSPeter Maydell     {
99a75f336bSPeter Maydell         .name = TYPE_STELLARIS_GAMEPAD,
100a75f336bSPeter Maydell         .parent = TYPE_SYS_BUS_DEVICE,
101a75f336bSPeter Maydell         .instance_size = sizeof(StellarisGamepad),
1026e782ffdSPhilippe Mathieu-Daudé         .instance_finalize = stellaris_gamepad_finalize,
103a75f336bSPeter Maydell         .class_init = stellaris_gamepad_class_init,
104a75f336bSPeter Maydell     },
105a75f336bSPeter Maydell };
106a75f336bSPeter Maydell 
107a75f336bSPeter Maydell DEFINE_TYPES(stellaris_gamepad_info);
108