xref: /openbmc/qemu/hw/input/stellaris_gamepad.c (revision 5f8d505e3a60b957530c7ad9b1214cc440d8b951)
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"
11c45460deSPeter Maydell #include "hw/input/stellaris_gamepad.h"
12c45460deSPeter Maydell #include "hw/irq.h"
13c45460deSPeter Maydell #include "migration/vmstate.h"
14c45460deSPeter Maydell #include "ui/console.h"
15c45460deSPeter Maydell 
16c45460deSPeter Maydell typedef struct {
17*5f8d505eSPeter Maydell     uint32_t num_buttons;
18c45460deSPeter Maydell     int extension;
19*5f8d505eSPeter Maydell     qemu_irq *irqs;
20*5f8d505eSPeter Maydell     uint32_t *keycodes;
21*5f8d505eSPeter Maydell     uint8_t *pressed;
22281e4618SPeter Maydell } StellarisGamepad;
23c45460deSPeter Maydell 
24c45460deSPeter Maydell static void stellaris_gamepad_put_key(void * opaque, int keycode)
25c45460deSPeter Maydell {
26281e4618SPeter Maydell     StellarisGamepad *s = (StellarisGamepad *)opaque;
27c45460deSPeter Maydell     int i;
28c45460deSPeter Maydell     int down;
29c45460deSPeter Maydell 
30c45460deSPeter Maydell     if (keycode == 0xe0 && !s->extension) {
31c45460deSPeter Maydell         s->extension = 0x80;
32c45460deSPeter Maydell         return;
33c45460deSPeter Maydell     }
34c45460deSPeter Maydell 
35c45460deSPeter Maydell     down = (keycode & 0x80) == 0;
36c45460deSPeter Maydell     keycode = (keycode & 0x7f) | s->extension;
37c45460deSPeter Maydell 
38c45460deSPeter Maydell     for (i = 0; i < s->num_buttons; i++) {
39*5f8d505eSPeter Maydell         if (s->keycodes[i] == keycode && s->pressed[i] != down) {
40*5f8d505eSPeter Maydell             s->pressed[i] = down;
41*5f8d505eSPeter Maydell             qemu_set_irq(s->irqs[i], down);
42c45460deSPeter Maydell         }
43c45460deSPeter Maydell     }
44c45460deSPeter Maydell 
45c45460deSPeter Maydell     s->extension = 0;
46c45460deSPeter Maydell }
47c45460deSPeter Maydell 
48c45460deSPeter Maydell static const VMStateDescription vmstate_stellaris_gamepad = {
49c45460deSPeter Maydell     .name = "stellaris_gamepad",
50*5f8d505eSPeter Maydell     .version_id = 3,
51*5f8d505eSPeter Maydell     .minimum_version_id = 3,
52c45460deSPeter Maydell     .fields = (VMStateField[]) {
53281e4618SPeter Maydell         VMSTATE_INT32(extension, StellarisGamepad),
54*5f8d505eSPeter Maydell         VMSTATE_VARRAY_UINT32(pressed, StellarisGamepad, num_buttons,
55*5f8d505eSPeter Maydell                               0, vmstate_info_uint8, uint8_t),
56c45460deSPeter Maydell         VMSTATE_END_OF_LIST()
57c45460deSPeter Maydell     }
58c45460deSPeter Maydell };
59c45460deSPeter Maydell 
60c45460deSPeter Maydell /* Returns an array of 5 output slots.  */
61c45460deSPeter Maydell void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
62c45460deSPeter Maydell {
63281e4618SPeter Maydell     StellarisGamepad *s;
64c45460deSPeter Maydell     int i;
65c45460deSPeter Maydell 
66281e4618SPeter Maydell     s = g_new0(StellarisGamepad, 1);
67*5f8d505eSPeter Maydell     s->irqs = g_new0(qemu_irq, n);
68*5f8d505eSPeter Maydell     s->keycodes = g_new0(uint32_t, n);
69*5f8d505eSPeter Maydell     s->pressed = g_new0(uint8_t, n);
70c45460deSPeter Maydell     for (i = 0; i < n; i++) {
71*5f8d505eSPeter Maydell         s->irqs[i] = irq[i];
72*5f8d505eSPeter Maydell         s->keycodes[i] = keycode[i];
73c45460deSPeter Maydell     }
74c45460deSPeter Maydell     s->num_buttons = n;
75c45460deSPeter Maydell     qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
76c45460deSPeter Maydell     vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
77c45460deSPeter Maydell                      &vmstate_stellaris_gamepad, s);
78c45460deSPeter Maydell }
79