4 * Copyright (c) 2009 Filip Navara
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 typedef struct RotaryCoderState
{
35 uint32_t key_left_alt
;
36 uint32_t key_right_alt
;
39 static void rotary_update(RotaryCoderState
*s
, int direction
)
41 s
->state
+= direction
;
44 qemu_set_irq(s
->out
[0], s
->state
== 1 || s
->state
== 2);
45 qemu_set_irq(s
->out
[1], s
->state
== 2 || s
->state
== 3);
48 static void rotary_keyboard_event(void *opaque
, int keycode
)
50 RotaryCoderState
*s
= opaque
;
52 if (keycode
== 0xe0 && !s
->extension
) {
57 if (!(keycode
& 0x80)) {
59 keycode
|= s
->extension
;
61 if (keycode
== s
->key_left
|| keycode
== s
->key_left_alt
) {
63 } else if (keycode
== s
->key_right
|| keycode
== s
->key_right_alt
) {
71 static void rotary_save(QEMUFile
*f
, void *opaque
)
73 RotaryCoderState
*s
= opaque
;
75 qemu_put_byte(f
, s
->state
);
76 qemu_put_byte(f
, s
->extension
);
79 static int rotary_load(QEMUFile
*f
, void *opaque
, int version_id
)
81 RotaryCoderState
*s
= opaque
;
86 s
->state
= qemu_get_byte(f
);
87 s
->extension
= qemu_get_byte(f
);
93 static void rotary_late_init(DeviceState *dev)
95 RotaryCoderState *s = FROM_SYSBUS(RotaryCoderState, sysbus_from_qdev(dev));
101 static void rotary_init(SysBusDevice
*dev
)
103 RotaryCoderState
*s
= FROM_SYSBUS(RotaryCoderState
, dev
);
105 qdev_init_gpio_out(&dev
->qdev
, s
->out
, 2);
106 qemu_add_kbd_event_handler(rotary_keyboard_event
, s
);
107 register_savevm("gpio_rotary", -1, 1, rotary_save
, rotary_load
, s
);
110 static SysBusDeviceInfo rotary_info
= {
112 /* .qdev.late_init = rotary_late_init, */
113 .qdev
.name
= "gpio,rotary",
114 .qdev
.size
= sizeof(RotaryCoderState
),
115 .qdev
.props
= (Property
[]) {
118 .info
= &qdev_prop_uint32
,
119 .offset
= offsetof(RotaryCoderState
, key_left
),
120 .defval
= (uint32_t[]) { 0xcb },
124 .info
= &qdev_prop_uint32
,
125 .offset
= offsetof(RotaryCoderState
, key_right
),
126 .defval
= (uint32_t[]) { 0xcd },
129 .name
= "key-left-alt",
130 .info
= &qdev_prop_uint32
,
131 .offset
= offsetof(RotaryCoderState
, key_left_alt
),
132 .defval
= (uint32_t[]) { 0x4b },
135 .name
= "key-right-alt",
136 .info
= &qdev_prop_uint32
,
137 .offset
= offsetof(RotaryCoderState
, key_right_alt
),
138 .defval
= (uint32_t[]) { 0x4d },
144 static void rotary_register(void)
146 sysbus_register_withprop(&rotary_info
);
149 device_init(rotary_register
)