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