xref: /openbmc/qemu/hw/input/stellaris_gamepad.c (revision c45460decbda7f94d188d2e18ead91b7c60d4e24)
1*c45460deSPeter Maydell /*
2*c45460deSPeter Maydell  * Gamepad style buttons connected to IRQ/GPIO lines
3*c45460deSPeter Maydell  *
4*c45460deSPeter Maydell  * Copyright (c) 2007 CodeSourcery.
5*c45460deSPeter Maydell  * Written by Paul Brook
6*c45460deSPeter Maydell  *
7*c45460deSPeter Maydell  * This code is licensed under the GPL.
8*c45460deSPeter Maydell  */
9*c45460deSPeter Maydell 
10*c45460deSPeter Maydell #include "qemu/osdep.h"
11*c45460deSPeter Maydell #include "hw/input/stellaris_gamepad.h"
12*c45460deSPeter Maydell #include "hw/irq.h"
13*c45460deSPeter Maydell #include "migration/vmstate.h"
14*c45460deSPeter Maydell #include "ui/console.h"
15*c45460deSPeter Maydell 
16*c45460deSPeter Maydell typedef struct {
17*c45460deSPeter Maydell     qemu_irq irq;
18*c45460deSPeter Maydell     int keycode;
19*c45460deSPeter Maydell     uint8_t pressed;
20*c45460deSPeter Maydell } gamepad_button;
21*c45460deSPeter Maydell 
22*c45460deSPeter Maydell typedef struct {
23*c45460deSPeter Maydell     gamepad_button *buttons;
24*c45460deSPeter Maydell     int num_buttons;
25*c45460deSPeter Maydell     int extension;
26*c45460deSPeter Maydell } gamepad_state;
27*c45460deSPeter Maydell 
28*c45460deSPeter Maydell static void stellaris_gamepad_put_key(void * opaque, int keycode)
29*c45460deSPeter Maydell {
30*c45460deSPeter Maydell     gamepad_state *s = (gamepad_state *)opaque;
31*c45460deSPeter Maydell     int i;
32*c45460deSPeter Maydell     int down;
33*c45460deSPeter Maydell 
34*c45460deSPeter Maydell     if (keycode == 0xe0 && !s->extension) {
35*c45460deSPeter Maydell         s->extension = 0x80;
36*c45460deSPeter Maydell         return;
37*c45460deSPeter Maydell     }
38*c45460deSPeter Maydell 
39*c45460deSPeter Maydell     down = (keycode & 0x80) == 0;
40*c45460deSPeter Maydell     keycode = (keycode & 0x7f) | s->extension;
41*c45460deSPeter Maydell 
42*c45460deSPeter Maydell     for (i = 0; i < s->num_buttons; i++) {
43*c45460deSPeter Maydell         if (s->buttons[i].keycode == keycode
44*c45460deSPeter Maydell                 && s->buttons[i].pressed != down) {
45*c45460deSPeter Maydell             s->buttons[i].pressed = down;
46*c45460deSPeter Maydell             qemu_set_irq(s->buttons[i].irq, down);
47*c45460deSPeter Maydell         }
48*c45460deSPeter Maydell     }
49*c45460deSPeter Maydell 
50*c45460deSPeter Maydell     s->extension = 0;
51*c45460deSPeter Maydell }
52*c45460deSPeter Maydell 
53*c45460deSPeter Maydell static const VMStateDescription vmstate_stellaris_button = {
54*c45460deSPeter Maydell     .name = "stellaris_button",
55*c45460deSPeter Maydell     .version_id = 0,
56*c45460deSPeter Maydell     .minimum_version_id = 0,
57*c45460deSPeter Maydell     .fields = (VMStateField[]) {
58*c45460deSPeter Maydell         VMSTATE_UINT8(pressed, gamepad_button),
59*c45460deSPeter Maydell         VMSTATE_END_OF_LIST()
60*c45460deSPeter Maydell     }
61*c45460deSPeter Maydell };
62*c45460deSPeter Maydell 
63*c45460deSPeter Maydell static const VMStateDescription vmstate_stellaris_gamepad = {
64*c45460deSPeter Maydell     .name = "stellaris_gamepad",
65*c45460deSPeter Maydell     .version_id = 2,
66*c45460deSPeter Maydell     .minimum_version_id = 2,
67*c45460deSPeter Maydell     .fields = (VMStateField[]) {
68*c45460deSPeter Maydell         VMSTATE_INT32(extension, gamepad_state),
69*c45460deSPeter Maydell         VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state,
70*c45460deSPeter Maydell                                             num_buttons,
71*c45460deSPeter Maydell                                             vmstate_stellaris_button,
72*c45460deSPeter Maydell                                             gamepad_button),
73*c45460deSPeter Maydell         VMSTATE_END_OF_LIST()
74*c45460deSPeter Maydell     }
75*c45460deSPeter Maydell };
76*c45460deSPeter Maydell 
77*c45460deSPeter Maydell /* Returns an array of 5 output slots.  */
78*c45460deSPeter Maydell void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
79*c45460deSPeter Maydell {
80*c45460deSPeter Maydell     gamepad_state *s;
81*c45460deSPeter Maydell     int i;
82*c45460deSPeter Maydell 
83*c45460deSPeter Maydell     s = g_new0(gamepad_state, 1);
84*c45460deSPeter Maydell     s->buttons = g_new0(gamepad_button, n);
85*c45460deSPeter Maydell     for (i = 0; i < n; i++) {
86*c45460deSPeter Maydell         s->buttons[i].irq = irq[i];
87*c45460deSPeter Maydell         s->buttons[i].keycode = keycode[i];
88*c45460deSPeter Maydell     }
89*c45460deSPeter Maydell     s->num_buttons = n;
90*c45460deSPeter Maydell     qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
91*c45460deSPeter Maydell     vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
92*c45460deSPeter Maydell                      &vmstate_stellaris_gamepad, s);
93*c45460deSPeter Maydell }
94