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