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" 11a75f336bSPeter Maydell #include "qapi/error.h" 12c45460deSPeter Maydell #include "hw/input/stellaris_gamepad.h" 13c45460deSPeter Maydell #include "hw/irq.h" 14a75f336bSPeter Maydell #include "hw/qdev-properties.h" 15c45460deSPeter Maydell #include "migration/vmstate.h" 16c45460deSPeter Maydell #include "ui/console.h" 17c45460deSPeter Maydell 18*7c76f397SPeter Maydell static void stellaris_gamepad_event(DeviceState *dev, QemuConsole *src, 19*7c76f397SPeter Maydell InputEvent *evt) 20c45460deSPeter Maydell { 21*7c76f397SPeter Maydell StellarisGamepad *s = STELLARIS_GAMEPAD(dev); 22*7c76f397SPeter Maydell InputKeyEvent *key = evt->u.key.data; 23*7c76f397SPeter Maydell int qcode = qemu_input_key_value_to_qcode(key->key); 24c45460deSPeter Maydell int i; 25c45460deSPeter Maydell 26c45460deSPeter Maydell for (i = 0; i < s->num_buttons; i++) { 27*7c76f397SPeter Maydell if (s->keycodes[i] == qcode && s->pressed[i] != key->down) { 28*7c76f397SPeter Maydell s->pressed[i] = key->down; 29*7c76f397SPeter Maydell qemu_set_irq(s->irqs[i], key->down); 30c45460deSPeter Maydell } 31c45460deSPeter Maydell } 32c45460deSPeter Maydell } 33c45460deSPeter Maydell 34c45460deSPeter Maydell static const VMStateDescription vmstate_stellaris_gamepad = { 35c45460deSPeter Maydell .name = "stellaris_gamepad", 36*7c76f397SPeter Maydell .version_id = 4, 37*7c76f397SPeter Maydell .minimum_version_id = 4, 38c45460deSPeter Maydell .fields = (VMStateField[]) { 395f8d505eSPeter Maydell VMSTATE_VARRAY_UINT32(pressed, StellarisGamepad, num_buttons, 405f8d505eSPeter Maydell 0, vmstate_info_uint8, uint8_t), 41c45460deSPeter Maydell VMSTATE_END_OF_LIST() 42c45460deSPeter Maydell } 43c45460deSPeter Maydell }; 44c45460deSPeter Maydell 45*7c76f397SPeter Maydell static const QemuInputHandler stellaris_gamepad_handler = { 46*7c76f397SPeter Maydell .name = "Stellaris Gamepad", 47*7c76f397SPeter Maydell .mask = INPUT_EVENT_MASK_KEY, 48*7c76f397SPeter Maydell .event = stellaris_gamepad_event, 49*7c76f397SPeter Maydell }; 50*7c76f397SPeter Maydell 51a75f336bSPeter Maydell static void stellaris_gamepad_realize(DeviceState *dev, Error **errp) 52c45460deSPeter Maydell { 53a75f336bSPeter Maydell StellarisGamepad *s = STELLARIS_GAMEPAD(dev); 54c45460deSPeter Maydell 55a75f336bSPeter Maydell if (s->num_buttons == 0) { 56a75f336bSPeter Maydell error_setg(errp, "keycodes property array must be set"); 57a75f336bSPeter Maydell return; 58c45460deSPeter Maydell } 59a75f336bSPeter Maydell 60a75f336bSPeter Maydell s->irqs = g_new0(qemu_irq, s->num_buttons); 61a75f336bSPeter Maydell s->pressed = g_new0(uint8_t, s->num_buttons); 62a75f336bSPeter Maydell qdev_init_gpio_out(dev, s->irqs, s->num_buttons); 63*7c76f397SPeter Maydell qemu_input_handler_register(dev, &stellaris_gamepad_handler); 64c45460deSPeter Maydell } 65a75f336bSPeter Maydell 66a75f336bSPeter Maydell static void stellaris_gamepad_reset_enter(Object *obj, ResetType type) 67a75f336bSPeter Maydell { 68a75f336bSPeter Maydell StellarisGamepad *s = STELLARIS_GAMEPAD(obj); 69a75f336bSPeter Maydell 70a75f336bSPeter Maydell memset(s->pressed, 0, s->num_buttons * sizeof(uint8_t)); 71a75f336bSPeter Maydell } 72a75f336bSPeter Maydell 73a75f336bSPeter Maydell static Property stellaris_gamepad_properties[] = { 74a75f336bSPeter Maydell DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons, 75a75f336bSPeter Maydell keycodes, qdev_prop_uint32, uint32_t), 76a75f336bSPeter Maydell DEFINE_PROP_END_OF_LIST(), 77a75f336bSPeter Maydell }; 78a75f336bSPeter Maydell 79a75f336bSPeter Maydell static void stellaris_gamepad_class_init(ObjectClass *klass, void *data) 80a75f336bSPeter Maydell { 81a75f336bSPeter Maydell DeviceClass *dc = DEVICE_CLASS(klass); 82a75f336bSPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(klass); 83a75f336bSPeter Maydell 84a75f336bSPeter Maydell rc->phases.enter = stellaris_gamepad_reset_enter; 85a75f336bSPeter Maydell dc->realize = stellaris_gamepad_realize; 86a75f336bSPeter Maydell dc->vmsd = &vmstate_stellaris_gamepad; 87a75f336bSPeter Maydell device_class_set_props(dc, stellaris_gamepad_properties); 88a75f336bSPeter Maydell } 89a75f336bSPeter Maydell 90a75f336bSPeter Maydell static const TypeInfo stellaris_gamepad_info[] = { 91a75f336bSPeter Maydell { 92a75f336bSPeter Maydell .name = TYPE_STELLARIS_GAMEPAD, 93a75f336bSPeter Maydell .parent = TYPE_SYS_BUS_DEVICE, 94a75f336bSPeter Maydell .instance_size = sizeof(StellarisGamepad), 95a75f336bSPeter Maydell .class_init = stellaris_gamepad_class_init, 96a75f336bSPeter Maydell }, 97a75f336bSPeter Maydell }; 98a75f336bSPeter Maydell 99a75f336bSPeter Maydell DEFINE_TYPES(stellaris_gamepad_info); 100