adb: only call autopoll callbacks when autopoll is not blocked
[qemu/rayw.git] / hw / input / adb.c
blobfe0f6c7ef304fefc77598929246c3052ed6d7ddf
1 /*
2 * QEMU ADB support
4 * Copyright (c) 2004 Fabrice Bellard
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
22 * THE SOFTWARE.
25 #include "qemu/osdep.h"
26 #include "hw/input/adb.h"
27 #include "hw/qdev-properties.h"
28 #include "migration/vmstate.h"
29 #include "qemu/module.h"
30 #include "qemu/timer.h"
31 #include "adb-internal.h"
33 /* error codes */
34 #define ADB_RET_NOTPRESENT (-2)
36 static void adb_device_reset(ADBDevice *d)
38 qdev_reset_all(DEVICE(d));
41 static int do_adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf,
42 int len)
44 ADBDevice *d;
45 ADBDeviceClass *adc;
46 int devaddr, cmd, olen, i;
48 cmd = buf[0] & 0xf;
49 if (cmd == ADB_BUSRESET) {
50 for (i = 0; i < s->nb_devices; i++) {
51 d = s->devices[i];
52 adb_device_reset(d);
54 s->status = 0;
55 return 0;
58 s->pending = 0;
59 for (i = 0; i < s->nb_devices; i++) {
60 d = s->devices[i];
61 adc = ADB_DEVICE_GET_CLASS(d);
63 if (adc->devhasdata(d)) {
64 s->pending |= (1 << d->devaddr);
68 s->status = 0;
69 devaddr = buf[0] >> 4;
70 for (i = 0; i < s->nb_devices; i++) {
71 d = s->devices[i];
72 adc = ADB_DEVICE_GET_CLASS(d);
74 if (d->devaddr == devaddr) {
75 olen = adc->devreq(d, obuf, buf, len);
76 if (!olen) {
77 s->status |= ADB_STATUS_BUSTIMEOUT;
79 return olen;
83 s->status |= ADB_STATUS_BUSTIMEOUT;
84 return ADB_RET_NOTPRESENT;
87 int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
89 assert(s->autopoll_blocked);
91 return do_adb_request(s, obuf, buf, len);
94 int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
96 ADBDevice *d;
97 int olen, i;
98 uint8_t buf[1];
100 olen = 0;
101 for (i = 0; i < s->nb_devices; i++) {
102 if (s->poll_index >= s->nb_devices) {
103 s->poll_index = 0;
105 d = s->devices[s->poll_index];
106 if ((1 << d->devaddr) & poll_mask) {
107 buf[0] = ADB_READREG | (d->devaddr << 4);
108 olen = do_adb_request(s, obuf + 1, buf, 1);
109 /* if there is data, we poll again the same device */
110 if (olen > 0) {
111 s->status |= ADB_STATUS_POLLREPLY;
112 obuf[0] = buf[0];
113 olen++;
114 return olen;
117 s->poll_index++;
119 return olen;
122 void adb_set_autopoll_enabled(ADBBusState *s, bool enabled)
124 if (s->autopoll_enabled != enabled) {
125 s->autopoll_enabled = enabled;
126 if (s->autopoll_enabled) {
127 timer_mod(s->autopoll_timer,
128 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
129 s->autopoll_rate_ms);
130 } else {
131 timer_del(s->autopoll_timer);
136 void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms)
138 s->autopoll_rate_ms = rate_ms;
140 if (s->autopoll_enabled) {
141 timer_mod(s->autopoll_timer,
142 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
143 s->autopoll_rate_ms);
147 void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
149 if (s->autopoll_mask != mask) {
150 s->autopoll_mask = mask;
151 if (s->autopoll_enabled && s->autopoll_mask) {
152 timer_mod(s->autopoll_timer,
153 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
154 s->autopoll_rate_ms);
155 } else {
156 timer_del(s->autopoll_timer);
161 void adb_autopoll_block(ADBBusState *s)
163 s->autopoll_blocked = true;
165 if (s->autopoll_enabled) {
166 timer_del(s->autopoll_timer);
170 void adb_autopoll_unblock(ADBBusState *s)
172 s->autopoll_blocked = false;
174 if (s->autopoll_enabled) {
175 timer_mod(s->autopoll_timer,
176 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
177 s->autopoll_rate_ms);
181 static void adb_autopoll(void *opaque)
183 ADBBusState *s = opaque;
185 if (!s->autopoll_blocked) {
186 s->autopoll_cb(s->autopoll_cb_opaque);
189 timer_mod(s->autopoll_timer,
190 qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
191 s->autopoll_rate_ms);
194 void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
195 void *opaque)
197 s->autopoll_cb = cb;
198 s->autopoll_cb_opaque = opaque;
201 static const VMStateDescription vmstate_adb_bus = {
202 .name = "adb_bus",
203 .version_id = 0,
204 .minimum_version_id = 0,
205 .fields = (VMStateField[]) {
206 VMSTATE_TIMER_PTR(autopoll_timer, ADBBusState),
207 VMSTATE_BOOL(autopoll_enabled, ADBBusState),
208 VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
209 VMSTATE_UINT16(autopoll_mask, ADBBusState),
210 VMSTATE_BOOL(autopoll_blocked, ADBBusState),
211 VMSTATE_END_OF_LIST()
215 static void adb_bus_reset(BusState *qbus)
217 ADBBusState *adb_bus = ADB_BUS(qbus);
219 adb_bus->autopoll_enabled = false;
220 adb_bus->autopoll_mask = 0xffff;
221 adb_bus->autopoll_rate_ms = 20;
224 static void adb_bus_realize(BusState *qbus, Error **errp)
226 ADBBusState *adb_bus = ADB_BUS(qbus);
228 adb_bus->autopoll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, adb_autopoll,
229 adb_bus);
231 vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
234 static void adb_bus_unrealize(BusState *qbus)
236 ADBBusState *adb_bus = ADB_BUS(qbus);
238 timer_del(adb_bus->autopoll_timer);
240 vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus);
243 static void adb_bus_class_init(ObjectClass *klass, void *data)
245 BusClass *k = BUS_CLASS(klass);
247 k->realize = adb_bus_realize;
248 k->unrealize = adb_bus_unrealize;
249 k->reset = adb_bus_reset;
252 static const TypeInfo adb_bus_type_info = {
253 .name = TYPE_ADB_BUS,
254 .parent = TYPE_BUS,
255 .instance_size = sizeof(ADBBusState),
256 .class_init = adb_bus_class_init,
259 const VMStateDescription vmstate_adb_device = {
260 .name = "adb_device",
261 .version_id = 0,
262 .minimum_version_id = 0,
263 .fields = (VMStateField[]) {
264 VMSTATE_INT32(devaddr, ADBDevice),
265 VMSTATE_INT32(handler, ADBDevice),
266 VMSTATE_END_OF_LIST()
270 static void adb_device_realizefn(DeviceState *dev, Error **errp)
272 ADBDevice *d = ADB_DEVICE(dev);
273 ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
275 if (bus->nb_devices >= MAX_ADB_DEVICES) {
276 return;
279 bus->devices[bus->nb_devices++] = d;
282 static void adb_device_class_init(ObjectClass *oc, void *data)
284 DeviceClass *dc = DEVICE_CLASS(oc);
286 dc->realize = adb_device_realizefn;
287 dc->bus_type = TYPE_ADB_BUS;
290 static const TypeInfo adb_device_type_info = {
291 .name = TYPE_ADB_DEVICE,
292 .parent = TYPE_DEVICE,
293 .instance_size = sizeof(ADBDevice),
294 .abstract = true,
295 .class_init = adb_device_class_init,
298 static void adb_register_types(void)
300 type_register_static(&adb_bus_type_info);
301 type_register_static(&adb_device_type_info);
304 type_init(adb_register_types)