aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2020-06-23 21:49:21 +0100
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2020-06-26 10:13:51 +0100
commitda52c083ac4af9bf934898470dfdeef0f6ead343 (patch)
tree5db0bc9df8504b3fd64843e7a015c4f109c2e00e /hw
parent0606b2883038b4b9a31a46fd1275a31323ec22d0 (diff)
downloadqemu-da52c083ac4af9bf934898470dfdeef0f6ead343.zip
qemu-da52c083ac4af9bf934898470dfdeef0f6ead343.tar.gz
qemu-da52c083ac4af9bf934898470dfdeef0f6ead343.tar.bz2
adb: create autopoll variables directly within ADBBusState
Rather than each ADB implementation requiring its own functions to manage autopoll state, timers, and autopoll masks prepare to move this information directly into ADBBusState. Add external functions within adb.h to allow each ADB implementation to manage the new autopoll variables. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Finn Thain <fthain@telegraphics.com.au> Acked-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20200623204936.24064-8-mark.cave-ayland@ilande.co.uk>
Diffstat (limited to 'hw')
-rw-r--r--hw/input/adb.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 21a9b3a..bb36ce6 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -27,6 +27,7 @@
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
+#include "qemu/timer.h"
#include "adb-internal.h"
/* error codes */
@@ -89,19 +90,92 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
return olen;
}
+void adb_set_autopoll_enabled(ADBBusState *s, bool enabled)
+{
+ if (s->autopoll_enabled != enabled) {
+ s->autopoll_enabled = enabled;
+ if (s->autopoll_enabled) {
+ timer_mod(s->autopoll_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+ s->autopoll_rate_ms);
+ } else {
+ timer_del(s->autopoll_timer);
+ }
+ }
+}
+
+void adb_set_autopoll_rate_ms(ADBBusState *s, int rate_ms)
+{
+ s->autopoll_rate_ms = rate_ms;
+
+ if (s->autopoll_enabled) {
+ timer_mod(s->autopoll_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+ s->autopoll_rate_ms);
+ }
+}
+
+void adb_set_autopoll_mask(ADBBusState *s, uint16_t mask)
+{
+ if (s->autopoll_mask != mask) {
+ s->autopoll_mask = mask;
+ if (s->autopoll_enabled && s->autopoll_mask) {
+ timer_mod(s->autopoll_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+ s->autopoll_rate_ms);
+ } else {
+ timer_del(s->autopoll_timer);
+ }
+ }
+}
+
+static void adb_autopoll(void *opaque)
+{
+ ADBBusState *s = opaque;
+
+ s->autopoll_cb(s->autopoll_cb_opaque);
+
+ timer_mod(s->autopoll_timer,
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+ s->autopoll_rate_ms);
+}
+
+void adb_register_autopoll_callback(ADBBusState *s, void (*cb)(void *opaque),
+ void *opaque)
+{
+ s->autopoll_cb = cb;
+ s->autopoll_cb_opaque = opaque;
+}
+
static const VMStateDescription vmstate_adb_bus = {
.name = "adb_bus",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
+ VMSTATE_TIMER_PTR(autopoll_timer, ADBBusState),
+ VMSTATE_BOOL(autopoll_enabled, ADBBusState),
+ VMSTATE_UINT8(autopoll_rate_ms, ADBBusState),
+ VMSTATE_UINT16(autopoll_mask, ADBBusState),
VMSTATE_END_OF_LIST()
}
};
+static void adb_bus_reset(BusState *qbus)
+{
+ ADBBusState *adb_bus = ADB_BUS(qbus);
+
+ adb_bus->autopoll_enabled = false;
+ adb_bus->autopoll_mask = 0xffff;
+ adb_bus->autopoll_rate_ms = 20;
+}
+
static void adb_bus_realize(BusState *qbus, Error **errp)
{
ADBBusState *adb_bus = ADB_BUS(qbus);
+ adb_bus->autopoll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, adb_autopoll,
+ adb_bus);
+
vmstate_register(NULL, -1, &vmstate_adb_bus, adb_bus);
}
@@ -109,6 +183,8 @@ static void adb_bus_unrealize(BusState *qbus)
{
ADBBusState *adb_bus = ADB_BUS(qbus);
+ timer_del(adb_bus->autopoll_timer);
+
vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus);
}
@@ -118,6 +194,7 @@ static void adb_bus_class_init(ObjectClass *klass, void *data)
k->realize = adb_bus_realize;
k->unrealize = adb_bus_unrealize;
+ k->reset = adb_bus_reset;
}
static const TypeInfo adb_bus_type_info = {