xref: /qemu/hw/input/stellaris_gamepad.c (revision 12d1a768bdfea6e27a3a829228840d72507613a1)
1cf0dbb21Spbrook /*
2cf0dbb21Spbrook  * Gamepad style buttons connected to IRQ/GPIO lines
3cf0dbb21Spbrook  *
4cf0dbb21Spbrook  * Copyright (c) 2007 CodeSourcery.
5cf0dbb21Spbrook  * Written by Paul Brook
6cf0dbb21Spbrook  *
78e31bf38SMatthew Fernandez  * This code is licensed under the GPL.
8cf0dbb21Spbrook  */
964552b6bSMarkus Armbruster 
108ef94f0bSPeter Maydell #include "qemu/osdep.h"
11a75f336bSPeter Maydell #include "qapi/error.h"
12c45460deSPeter Maydell #include "hw/input/stellaris_gamepad.h"
1364552b6bSMarkus Armbruster #include "hw/irq.h"
14a75f336bSPeter Maydell #include "hw/qdev-properties.h"
15d6454270SMarkus Armbruster #include "migration/vmstate.h"
1628ecbaeeSPaolo Bonzini #include "ui/console.h"
17cf0dbb21Spbrook 
stellaris_gamepad_event(DeviceState * dev,QemuConsole * src,InputEvent * evt)187c76f397SPeter Maydell static void stellaris_gamepad_event(DeviceState *dev, QemuConsole *src,
197c76f397SPeter Maydell                                     InputEvent *evt)
20cf0dbb21Spbrook {
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);
24cf0dbb21Spbrook     int i;
25cf0dbb21Spbrook 
26cf0dbb21Spbrook     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);
30cf0dbb21Spbrook         }
31cf0dbb21Spbrook     }
32cf0dbb21Spbrook }
33cf0dbb21Spbrook 
344483c7acSJuan Quintela static const VMStateDescription vmstate_stellaris_gamepad = {
354483c7acSJuan Quintela     .name = "stellaris_gamepad",
367c76f397SPeter Maydell     .version_id = 4,
377c76f397SPeter Maydell     .minimum_version_id = 4,
38af0f07dfSRichard Henderson     .fields = (const VMStateField[]) {
395f8d505eSPeter Maydell         VMSTATE_VARRAY_UINT32(pressed, StellarisGamepad, num_buttons,
405f8d505eSPeter Maydell                               0, vmstate_info_uint8, uint8_t),
414483c7acSJuan Quintela         VMSTATE_END_OF_LIST()
4223e39294Spbrook     }
434483c7acSJuan Quintela };
4423e39294Spbrook 
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)
52cf0dbb21Spbrook {
53a75f336bSPeter Maydell     StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
54cf0dbb21Spbrook 
55a75f336bSPeter Maydell     if (s->num_buttons == 0) {
56a75f336bSPeter Maydell         error_setg(errp, "keycodes property array must be set");
57a75f336bSPeter Maydell         return;
58cf0dbb21Spbrook     }
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);
64cf0dbb21Spbrook }
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 
809eb5c799SRichard Henderson static const Property stellaris_gamepad_properties[] = {
81a75f336bSPeter Maydell     DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons,
82a75f336bSPeter Maydell                       keycodes, qdev_prop_uint32, uint32_t),
83a75f336bSPeter Maydell };
84a75f336bSPeter Maydell 
stellaris_gamepad_class_init(ObjectClass * klass,const void * data)85*12d1a768SPhilippe Mathieu-Daudé static void stellaris_gamepad_class_init(ObjectClass *klass, const void *data)
86a75f336bSPeter Maydell {
87a75f336bSPeter Maydell     DeviceClass *dc = DEVICE_CLASS(klass);
88a75f336bSPeter Maydell     ResettableClass *rc = RESETTABLE_CLASS(klass);
89a75f336bSPeter Maydell 
90a75f336bSPeter Maydell     rc->phases.enter = stellaris_gamepad_reset_enter;
91a75f336bSPeter Maydell     dc->realize = stellaris_gamepad_realize;
92a75f336bSPeter Maydell     dc->vmsd = &vmstate_stellaris_gamepad;
93a75f336bSPeter Maydell     device_class_set_props(dc, stellaris_gamepad_properties);
94a75f336bSPeter Maydell }
95a75f336bSPeter Maydell 
96a75f336bSPeter Maydell static const TypeInfo stellaris_gamepad_info[] = {
97a75f336bSPeter Maydell     {
98a75f336bSPeter Maydell         .name = TYPE_STELLARIS_GAMEPAD,
99a75f336bSPeter Maydell         .parent = TYPE_SYS_BUS_DEVICE,
100a75f336bSPeter Maydell         .instance_size = sizeof(StellarisGamepad),
1016e782ffdSPhilippe Mathieu-Daudé         .instance_finalize = stellaris_gamepad_finalize,
102a75f336bSPeter Maydell         .class_init = stellaris_gamepad_class_init,
103a75f336bSPeter Maydell     },
104a75f336bSPeter Maydell };
105a75f336bSPeter Maydell 
106a75f336bSPeter Maydell DEFINE_TYPES(stellaris_gamepad_info);
107