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