2 * Gamepad style buttons connected to IRQ/GPIO lines
4 * Copyright (c) 2007 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licensed under the GPL.
10 #include "qemu/osdep.h"
11 #include "qapi/error.h"
12 #include "hw/input/stellaris_gamepad.h"
14 #include "hw/qdev-properties.h"
15 #include "migration/vmstate.h"
16 #include "ui/console.h"
18 static void stellaris_gamepad_event(DeviceState
*dev
, QemuConsole
*src
,
21 StellarisGamepad
*s
= STELLARIS_GAMEPAD(dev
);
22 InputKeyEvent
*key
= evt
->u
.key
.data
;
23 int qcode
= qemu_input_key_value_to_qcode(key
->key
);
26 for (i
= 0; i
< s
->num_buttons
; i
++) {
27 if (s
->keycodes
[i
] == qcode
&& s
->pressed
[i
] != key
->down
) {
28 s
->pressed
[i
] = key
->down
;
29 qemu_set_irq(s
->irqs
[i
], key
->down
);
34 static const VMStateDescription vmstate_stellaris_gamepad
= {
35 .name
= "stellaris_gamepad",
37 .minimum_version_id
= 4,
38 .fields
= (VMStateField
[]) {
39 VMSTATE_VARRAY_UINT32(pressed
, StellarisGamepad
, num_buttons
,
40 0, vmstate_info_uint8
, uint8_t),
45 static const QemuInputHandler stellaris_gamepad_handler
= {
46 .name
= "Stellaris Gamepad",
47 .mask
= INPUT_EVENT_MASK_KEY
,
48 .event
= stellaris_gamepad_event
,
51 static void stellaris_gamepad_realize(DeviceState
*dev
, Error
**errp
)
53 StellarisGamepad
*s
= STELLARIS_GAMEPAD(dev
);
55 if (s
->num_buttons
== 0) {
56 error_setg(errp
, "keycodes property array must be set");
60 s
->irqs
= g_new0(qemu_irq
, s
->num_buttons
);
61 s
->pressed
= g_new0(uint8_t, s
->num_buttons
);
62 qdev_init_gpio_out(dev
, s
->irqs
, s
->num_buttons
);
63 qemu_input_handler_register(dev
, &stellaris_gamepad_handler
);
66 static void stellaris_gamepad_finalize(Object
*obj
)
68 StellarisGamepad
*s
= STELLARIS_GAMEPAD(obj
);
73 static void stellaris_gamepad_reset_enter(Object
*obj
, ResetType type
)
75 StellarisGamepad
*s
= STELLARIS_GAMEPAD(obj
);
77 memset(s
->pressed
, 0, s
->num_buttons
* sizeof(uint8_t));
80 static Property stellaris_gamepad_properties
[] = {
81 DEFINE_PROP_ARRAY("keycodes", StellarisGamepad
, num_buttons
,
82 keycodes
, qdev_prop_uint32
, uint32_t),
83 DEFINE_PROP_END_OF_LIST(),
86 static void stellaris_gamepad_class_init(ObjectClass
*klass
, void *data
)
88 DeviceClass
*dc
= DEVICE_CLASS(klass
);
89 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
91 rc
->phases
.enter
= stellaris_gamepad_reset_enter
;
92 dc
->realize
= stellaris_gamepad_realize
;
93 dc
->vmsd
= &vmstate_stellaris_gamepad
;
94 device_class_set_props(dc
, stellaris_gamepad_properties
);
97 static const TypeInfo stellaris_gamepad_info
[] = {
99 .name
= TYPE_STELLARIS_GAMEPAD
,
100 .parent
= TYPE_SYS_BUS_DEVICE
,
101 .instance_size
= sizeof(StellarisGamepad
),
102 .instance_finalize
= stellaris_gamepad_finalize
,
103 .class_init
= stellaris_gamepad_class_init
,
107 DEFINE_TYPES(stellaris_gamepad_info
);