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