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" 11*c45460deSPeter Maydell #include "hw/input/stellaris_gamepad.h" 1264552b6bSMarkus Armbruster #include "hw/irq.h" 13d6454270SMarkus Armbruster #include "migration/vmstate.h" 1428ecbaeeSPaolo Bonzini #include "ui/console.h" 15cf0dbb21Spbrook 16cf0dbb21Spbrook typedef struct { 17cf0dbb21Spbrook qemu_irq irq; 18cf0dbb21Spbrook int keycode; 194483c7acSJuan Quintela uint8_t pressed; 20cf0dbb21Spbrook } gamepad_button; 21cf0dbb21Spbrook 22cf0dbb21Spbrook typedef struct { 23cf0dbb21Spbrook gamepad_button *buttons; 24cf0dbb21Spbrook int num_buttons; 25cf0dbb21Spbrook int extension; 26cf0dbb21Spbrook } gamepad_state; 27cf0dbb21Spbrook 28cf0dbb21Spbrook static void stellaris_gamepad_put_key(void * opaque, int keycode) 29cf0dbb21Spbrook { 30cf0dbb21Spbrook gamepad_state *s = (gamepad_state *)opaque; 31cf0dbb21Spbrook int i; 32cf0dbb21Spbrook int down; 33cf0dbb21Spbrook 34cf0dbb21Spbrook if (keycode == 0xe0 && !s->extension) { 35cf0dbb21Spbrook s->extension = 0x80; 36cf0dbb21Spbrook return; 37cf0dbb21Spbrook } 38cf0dbb21Spbrook 39cf0dbb21Spbrook down = (keycode & 0x80) == 0; 40cf0dbb21Spbrook keycode = (keycode & 0x7f) | s->extension; 41cf0dbb21Spbrook 42cf0dbb21Spbrook for (i = 0; i < s->num_buttons; i++) { 43cf0dbb21Spbrook if (s->buttons[i].keycode == keycode 44cf0dbb21Spbrook && s->buttons[i].pressed != down) { 45cf0dbb21Spbrook s->buttons[i].pressed = down; 46cf0dbb21Spbrook qemu_set_irq(s->buttons[i].irq, down); 47cf0dbb21Spbrook } 48cf0dbb21Spbrook } 49cf0dbb21Spbrook 50cf0dbb21Spbrook s->extension = 0; 51cf0dbb21Spbrook } 52cf0dbb21Spbrook 534483c7acSJuan Quintela static const VMStateDescription vmstate_stellaris_button = { 544483c7acSJuan Quintela .name = "stellaris_button", 554483c7acSJuan Quintela .version_id = 0, 564483c7acSJuan Quintela .minimum_version_id = 0, 574483c7acSJuan Quintela .fields = (VMStateField[]) { 584483c7acSJuan Quintela VMSTATE_UINT8(pressed, gamepad_button), 594483c7acSJuan Quintela VMSTATE_END_OF_LIST() 6023e39294Spbrook } 614483c7acSJuan Quintela }; 6223e39294Spbrook 634483c7acSJuan Quintela static const VMStateDescription vmstate_stellaris_gamepad = { 644483c7acSJuan Quintela .name = "stellaris_gamepad", 65372e458eSPeter Maydell .version_id = 2, 66372e458eSPeter Maydell .minimum_version_id = 2, 674483c7acSJuan Quintela .fields = (VMStateField[]) { 684483c7acSJuan Quintela VMSTATE_INT32(extension, gamepad_state), 69372e458eSPeter Maydell VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state, 70372e458eSPeter Maydell num_buttons, 71372e458eSPeter Maydell vmstate_stellaris_button, 72372e458eSPeter Maydell gamepad_button), 734483c7acSJuan Quintela VMSTATE_END_OF_LIST() 7423e39294Spbrook } 754483c7acSJuan Quintela }; 7623e39294Spbrook 7767cc32ebSVeres Lajos /* Returns an array of 5 output slots. */ 78cf0dbb21Spbrook void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) 79cf0dbb21Spbrook { 80cf0dbb21Spbrook gamepad_state *s; 81cf0dbb21Spbrook int i; 82cf0dbb21Spbrook 83b45c03f5SMarkus Armbruster s = g_new0(gamepad_state, 1); 84b45c03f5SMarkus Armbruster s->buttons = g_new0(gamepad_button, n); 85cf0dbb21Spbrook for (i = 0; i < n; i++) { 86cf0dbb21Spbrook s->buttons[i].irq = irq[i]; 87cf0dbb21Spbrook s->buttons[i].keycode = keycode[i]; 88cf0dbb21Spbrook } 89cf0dbb21Spbrook s->num_buttons = n; 90cf0dbb21Spbrook qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s); 911df2c9a2SPeter Xu vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, 921df2c9a2SPeter Xu &vmstate_stellaris_gamepad, s); 93cf0dbb21Spbrook } 94