summaryrefslogtreecommitdiffstats
path: root/qemu/hw/input
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/hw/input
parenta14b48d18a9ed03ec191cf16b162206998a895ce (diff)
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/hw/input')
-rw-r--r--qemu/hw/input/Makefile.objs19
-rw-r--r--qemu/hw/input/adb.c598
-rw-r--r--qemu/hw/input/hid.c618
-rw-r--r--qemu/hw/input/lm832x.c525
-rw-r--r--qemu/hw/input/milkymist-softusb.c319
-rw-r--r--qemu/hw/input/pckbd.c595
-rw-r--r--qemu/hw/input/pl050.c206
-rw-r--r--qemu/hw/input/ps2.c813
-rw-r--r--qemu/hw/input/pxa2xx_keypad.c335
-rw-r--r--qemu/hw/input/stellaris_input.c88
-rw-r--r--qemu/hw/input/tsc2005.c595
-rw-r--r--qemu/hw/input/tsc210x.c1273
-rw-r--r--qemu/hw/input/virtio-input-hid.c525
-rw-r--r--qemu/hw/input/virtio-input-host.c257
-rw-r--r--qemu/hw/input/virtio-input.c343
-rw-r--r--qemu/hw/input/vmmouse.c304
16 files changed, 0 insertions, 7413 deletions
diff --git a/qemu/hw/input/Makefile.objs b/qemu/hw/input/Makefile.objs
deleted file mode 100644
index 7715d7230..000000000
--- a/qemu/hw/input/Makefile.objs
+++ /dev/null
@@ -1,19 +0,0 @@
-common-obj-$(CONFIG_ADB) += adb.o
-common-obj-y += hid.o
-common-obj-$(CONFIG_LM832X) += lm832x.o
-common-obj-$(CONFIG_PCKBD) += pckbd.o
-common-obj-$(CONFIG_PL050) += pl050.o
-common-obj-y += ps2.o
-common-obj-$(CONFIG_STELLARIS_INPUT) += stellaris_input.o
-common-obj-$(CONFIG_TSC2005) += tsc2005.o
-common-obj-$(CONFIG_VMMOUSE) += vmmouse.o
-
-common-obj-$(CONFIG_VIRTIO) += virtio-input.o
-common-obj-$(CONFIG_VIRTIO) += virtio-input-hid.o
-ifeq ($(CONFIG_LINUX),y)
-common-obj-$(CONFIG_VIRTIO) += virtio-input-host.o
-endif
-
-obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
-obj-$(CONFIG_PXA2XX) += pxa2xx_keypad.o
-obj-$(CONFIG_TSC210X) += tsc210x.o
diff --git a/qemu/hw/input/adb.c b/qemu/hw/input/adb.c
deleted file mode 100644
index f0ad0d447..000000000
--- a/qemu/hw/input/adb.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * QEMU ADB support
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/input/adb.h"
-#include "ui/console.h"
-
-/* debug ADB */
-//#define DEBUG_ADB
-
-#ifdef DEBUG_ADB
-#define ADB_DPRINTF(fmt, ...) \
-do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define ADB_DPRINTF(fmt, ...)
-#endif
-
-/* ADB commands */
-#define ADB_BUSRESET 0x00
-#define ADB_FLUSH 0x01
-#define ADB_WRITEREG 0x08
-#define ADB_READREG 0x0c
-
-/* ADB device commands */
-#define ADB_CMD_SELF_TEST 0xff
-#define ADB_CMD_CHANGE_ID 0xfe
-#define ADB_CMD_CHANGE_ID_AND_ACT 0xfd
-#define ADB_CMD_CHANGE_ID_AND_ENABLE 0x00
-
-/* ADB default device IDs (upper 4 bits of ADB command byte) */
-#define ADB_DEVID_DONGLE 1
-#define ADB_DEVID_KEYBOARD 2
-#define ADB_DEVID_MOUSE 3
-#define ADB_DEVID_TABLET 4
-#define ADB_DEVID_MODEM 5
-#define ADB_DEVID_MISC 7
-
-/* error codes */
-#define ADB_RET_NOTPRESENT (-2)
-
-static void adb_device_reset(ADBDevice *d)
-{
- qdev_reset_all(DEVICE(d));
-}
-
-int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
-{
- ADBDevice *d;
- int devaddr, cmd, i;
-
- cmd = buf[0] & 0xf;
- if (cmd == ADB_BUSRESET) {
- for(i = 0; i < s->nb_devices; i++) {
- d = s->devices[i];
- adb_device_reset(d);
- }
- return 0;
- }
- devaddr = buf[0] >> 4;
- for(i = 0; i < s->nb_devices; i++) {
- d = s->devices[i];
- if (d->devaddr == devaddr) {
- ADBDeviceClass *adc = ADB_DEVICE_GET_CLASS(d);
- return adc->devreq(d, obuf, buf, len);
- }
- }
- return ADB_RET_NOTPRESENT;
-}
-
-/* XXX: move that to cuda ? */
-int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
-{
- ADBDevice *d;
- int olen, i;
- uint8_t buf[1];
-
- olen = 0;
- for(i = 0; i < s->nb_devices; i++) {
- if (s->poll_index >= s->nb_devices)
- s->poll_index = 0;
- d = s->devices[s->poll_index];
- if ((1 << d->devaddr) & poll_mask) {
- buf[0] = ADB_READREG | (d->devaddr << 4);
- olen = adb_request(s, obuf + 1, buf, 1);
- /* if there is data, we poll again the same device */
- if (olen > 0) {
- obuf[0] = buf[0];
- olen++;
- break;
- }
- }
- s->poll_index++;
- }
- return olen;
-}
-
-static const TypeInfo adb_bus_type_info = {
- .name = TYPE_ADB_BUS,
- .parent = TYPE_BUS,
- .instance_size = sizeof(ADBBusState),
-};
-
-static const VMStateDescription vmstate_adb_device = {
- .name = "adb_device",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(devaddr, ADBDevice),
- VMSTATE_INT32(handler, ADBDevice),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void adb_device_realizefn(DeviceState *dev, Error **errp)
-{
- ADBDevice *d = ADB_DEVICE(dev);
- ADBBusState *bus = ADB_BUS(qdev_get_parent_bus(dev));
-
- if (bus->nb_devices >= MAX_ADB_DEVICES) {
- return;
- }
-
- bus->devices[bus->nb_devices++] = d;
-}
-
-static void adb_device_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = adb_device_realizefn;
- dc->bus_type = TYPE_ADB_BUS;
-}
-
-static const TypeInfo adb_device_type_info = {
- .name = TYPE_ADB_DEVICE,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(ADBDevice),
- .abstract = true,
- .class_init = adb_device_class_init,
-};
-
-/***************************************************************/
-/* Keyboard ADB device */
-
-#define ADB_KEYBOARD(obj) OBJECT_CHECK(KBDState, (obj), TYPE_ADB_KEYBOARD)
-
-typedef struct KBDState {
- /*< private >*/
- ADBDevice parent_obj;
- /*< public >*/
-
- uint8_t data[128];
- int rptr, wptr, count;
-} KBDState;
-
-#define ADB_KEYBOARD_CLASS(class) \
- OBJECT_CLASS_CHECK(ADBKeyboardClass, (class), TYPE_ADB_KEYBOARD)
-#define ADB_KEYBOARD_GET_CLASS(obj) \
- OBJECT_GET_CLASS(ADBKeyboardClass, (obj), TYPE_ADB_KEYBOARD)
-
-typedef struct ADBKeyboardClass {
- /*< private >*/
- ADBDeviceClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
-} ADBKeyboardClass;
-
-static const uint8_t pc_to_adb_keycode[256] = {
- 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
- 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
- 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
- 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
- 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
- 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
- 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-static void adb_kbd_put_keycode(void *opaque, int keycode)
-{
- KBDState *s = opaque;
-
- if (s->count < sizeof(s->data)) {
- s->data[s->wptr] = keycode;
- if (++s->wptr == sizeof(s->data))
- s->wptr = 0;
- s->count++;
- }
-}
-
-static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
-{
- static int ext_keycode;
- KBDState *s = ADB_KEYBOARD(d);
- int adb_keycode, keycode;
- int olen;
-
- olen = 0;
- for(;;) {
- if (s->count == 0)
- break;
- keycode = s->data[s->rptr];
- if (++s->rptr == sizeof(s->data))
- s->rptr = 0;
- s->count--;
-
- if (keycode == 0xe0) {
- ext_keycode = 1;
- } else {
- if (ext_keycode)
- adb_keycode = pc_to_adb_keycode[keycode | 0x80];
- else
- adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
- obuf[0] = adb_keycode | (keycode & 0x80);
- /* NOTE: could put a second keycode if needed */
- obuf[1] = 0xff;
- olen = 2;
- ext_keycode = 0;
- break;
- }
- }
- return olen;
-}
-
-static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
- const uint8_t *buf, int len)
-{
- KBDState *s = ADB_KEYBOARD(d);
- int cmd, reg, olen;
-
- if ((buf[0] & 0x0f) == ADB_FLUSH) {
- /* flush keyboard fifo */
- s->wptr = s->rptr = s->count = 0;
- return 0;
- }
-
- cmd = buf[0] & 0xc;
- reg = buf[0] & 0x3;
- olen = 0;
- switch(cmd) {
- case ADB_WRITEREG:
- switch(reg) {
- case 2:
- /* LED status */
- break;
- case 3:
- switch(buf[2]) {
- case ADB_CMD_SELF_TEST:
- break;
- case ADB_CMD_CHANGE_ID:
- case ADB_CMD_CHANGE_ID_AND_ACT:
- case ADB_CMD_CHANGE_ID_AND_ENABLE:
- d->devaddr = buf[1] & 0xf;
- break;
- default:
- /* XXX: check this */
- d->devaddr = buf[1] & 0xf;
- d->handler = buf[2];
- break;
- }
- }
- break;
- case ADB_READREG:
- switch(reg) {
- case 0:
- olen = adb_kbd_poll(d, obuf);
- break;
- case 1:
- break;
- case 2:
- obuf[0] = 0x00; /* XXX: check this */
- obuf[1] = 0x07; /* led status */
- olen = 2;
- break;
- case 3:
- obuf[0] = d->handler;
- obuf[1] = d->devaddr;
- olen = 2;
- break;
- }
- break;
- }
- return olen;
-}
-
-static const VMStateDescription vmstate_adb_kbd = {
- .name = "adb_kbd",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDevice),
- VMSTATE_BUFFER(data, KBDState),
- VMSTATE_INT32(rptr, KBDState),
- VMSTATE_INT32(wptr, KBDState),
- VMSTATE_INT32(count, KBDState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void adb_kbd_reset(DeviceState *dev)
-{
- ADBDevice *d = ADB_DEVICE(dev);
- KBDState *s = ADB_KEYBOARD(dev);
-
- d->handler = 1;
- d->devaddr = ADB_DEVID_KEYBOARD;
- memset(s->data, 0, sizeof(s->data));
- s->rptr = 0;
- s->wptr = 0;
- s->count = 0;
-}
-
-static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
-{
- ADBDevice *d = ADB_DEVICE(dev);
- ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
-
- akc->parent_realize(dev, errp);
-
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
-}
-
-static void adb_kbd_initfn(Object *obj)
-{
- ADBDevice *d = ADB_DEVICE(obj);
-
- d->devaddr = ADB_DEVID_KEYBOARD;
-}
-
-static void adb_kbd_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
- ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
-
- akc->parent_realize = dc->realize;
- dc->realize = adb_kbd_realizefn;
- set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
-
- adc->devreq = adb_kbd_request;
- dc->reset = adb_kbd_reset;
- dc->vmsd = &vmstate_adb_kbd;
-}
-
-static const TypeInfo adb_kbd_type_info = {
- .name = TYPE_ADB_KEYBOARD,
- .parent = TYPE_ADB_DEVICE,
- .instance_size = sizeof(KBDState),
- .instance_init = adb_kbd_initfn,
- .class_init = adb_kbd_class_init,
- .class_size = sizeof(ADBKeyboardClass),
-};
-
-/***************************************************************/
-/* Mouse ADB device */
-
-#define ADB_MOUSE(obj) OBJECT_CHECK(MouseState, (obj), TYPE_ADB_MOUSE)
-
-typedef struct MouseState {
- /*< public >*/
- ADBDevice parent_obj;
- /*< private >*/
-
- int buttons_state, last_buttons_state;
- int dx, dy, dz;
-} MouseState;
-
-#define ADB_MOUSE_CLASS(class) \
- OBJECT_CLASS_CHECK(ADBMouseClass, (class), TYPE_ADB_MOUSE)
-#define ADB_MOUSE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(ADBMouseClass, (obj), TYPE_ADB_MOUSE)
-
-typedef struct ADBMouseClass {
- /*< public >*/
- ADBDeviceClass parent_class;
- /*< private >*/
-
- DeviceRealize parent_realize;
-} ADBMouseClass;
-
-static void adb_mouse_event(void *opaque,
- int dx1, int dy1, int dz1, int buttons_state)
-{
- MouseState *s = opaque;
-
- s->dx += dx1;
- s->dy += dy1;
- s->dz += dz1;
- s->buttons_state = buttons_state;
-}
-
-
-static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
-{
- MouseState *s = ADB_MOUSE(d);
- int dx, dy;
-
- if (s->last_buttons_state == s->buttons_state &&
- s->dx == 0 && s->dy == 0)
- return 0;
-
- dx = s->dx;
- if (dx < -63)
- dx = -63;
- else if (dx > 63)
- dx = 63;
-
- dy = s->dy;
- if (dy < -63)
- dy = -63;
- else if (dy > 63)
- dy = 63;
-
- s->dx -= dx;
- s->dy -= dy;
- s->last_buttons_state = s->buttons_state;
-
- dx &= 0x7f;
- dy &= 0x7f;
-
- if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
- dy |= 0x80;
- if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
- dx |= 0x80;
-
- obuf[0] = dy;
- obuf[1] = dx;
- return 2;
-}
-
-static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
- const uint8_t *buf, int len)
-{
- MouseState *s = ADB_MOUSE(d);
- int cmd, reg, olen;
-
- if ((buf[0] & 0x0f) == ADB_FLUSH) {
- /* flush mouse fifo */
- s->buttons_state = s->last_buttons_state;
- s->dx = 0;
- s->dy = 0;
- s->dz = 0;
- return 0;
- }
-
- cmd = buf[0] & 0xc;
- reg = buf[0] & 0x3;
- olen = 0;
- switch(cmd) {
- case ADB_WRITEREG:
- ADB_DPRINTF("write reg %d val 0x%2.2x\n", reg, buf[1]);
- switch(reg) {
- case 2:
- break;
- case 3:
- switch(buf[2]) {
- case ADB_CMD_SELF_TEST:
- break;
- case ADB_CMD_CHANGE_ID:
- case ADB_CMD_CHANGE_ID_AND_ACT:
- case ADB_CMD_CHANGE_ID_AND_ENABLE:
- d->devaddr = buf[1] & 0xf;
- break;
- default:
- /* XXX: check this */
- d->devaddr = buf[1] & 0xf;
- break;
- }
- }
- break;
- case ADB_READREG:
- switch(reg) {
- case 0:
- olen = adb_mouse_poll(d, obuf);
- break;
- case 1:
- break;
- case 3:
- obuf[0] = d->handler;
- obuf[1] = d->devaddr;
- olen = 2;
- break;
- }
- ADB_DPRINTF("read reg %d obuf[0] 0x%2.2x obuf[1] 0x%2.2x\n", reg,
- obuf[0], obuf[1]);
- break;
- }
- return olen;
-}
-
-static void adb_mouse_reset(DeviceState *dev)
-{
- ADBDevice *d = ADB_DEVICE(dev);
- MouseState *s = ADB_MOUSE(dev);
-
- d->handler = 2;
- d->devaddr = ADB_DEVID_MOUSE;
- s->last_buttons_state = s->buttons_state = 0;
- s->dx = s->dy = s->dz = 0;
-}
-
-static const VMStateDescription vmstate_adb_mouse = {
- .name = "adb_mouse",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
- ADBDevice),
- VMSTATE_INT32(buttons_state, MouseState),
- VMSTATE_INT32(last_buttons_state, MouseState),
- VMSTATE_INT32(dx, MouseState),
- VMSTATE_INT32(dy, MouseState),
- VMSTATE_INT32(dz, MouseState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void adb_mouse_realizefn(DeviceState *dev, Error **errp)
-{
- MouseState *s = ADB_MOUSE(dev);
- ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);
-
- amc->parent_realize(dev, errp);
-
- qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");
-}
-
-static void adb_mouse_initfn(Object *obj)
-{
- ADBDevice *d = ADB_DEVICE(obj);
-
- d->devaddr = ADB_DEVID_MOUSE;
-}
-
-static void adb_mouse_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
- ADBMouseClass *amc = ADB_MOUSE_CLASS(oc);
-
- amc->parent_realize = dc->realize;
- dc->realize = adb_mouse_realizefn;
- set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
-
- adc->devreq = adb_mouse_request;
- dc->reset = adb_mouse_reset;
- dc->vmsd = &vmstate_adb_mouse;
-}
-
-static const TypeInfo adb_mouse_type_info = {
- .name = TYPE_ADB_MOUSE,
- .parent = TYPE_ADB_DEVICE,
- .instance_size = sizeof(MouseState),
- .instance_init = adb_mouse_initfn,
- .class_init = adb_mouse_class_init,
- .class_size = sizeof(ADBMouseClass),
-};
-
-
-static void adb_register_types(void)
-{
- type_register_static(&adb_bus_type_info);
- type_register_static(&adb_device_type_info);
- type_register_static(&adb_kbd_type_info);
- type_register_static(&adb_mouse_type_info);
-}
-
-type_init(adb_register_types)
diff --git a/qemu/hw/input/hid.c b/qemu/hw/input/hid.c
deleted file mode 100644
index d92c7463b..000000000
--- a/qemu/hw/input/hid.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * QEMU HID devices
- *
- * Copyright (c) 2005 Fabrice Bellard
- * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "qemu/timer.h"
-#include "hw/input/hid.h"
-
-#define HID_USAGE_ERROR_ROLLOVER 0x01
-#define HID_USAGE_POSTFAIL 0x02
-#define HID_USAGE_ERROR_UNDEFINED 0x03
-
-/* Indices are QEMU keycodes, values are from HID Usage Table. Indices
- * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
-static const uint8_t hid_usage_keys[0x100] = {
- 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
- 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
- 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
- 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
- 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
- 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
- 0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
- 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
- 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
- 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x64, 0x44,
- 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
- 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
-
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
- 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
- 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
- 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-bool hid_has_events(HIDState *hs)
-{
- return hs->n > 0 || hs->idle_pending;
-}
-
-static void hid_idle_timer(void *opaque)
-{
- HIDState *hs = opaque;
-
- hs->idle_pending = true;
- hs->event(hs);
-}
-
-static void hid_del_idle_timer(HIDState *hs)
-{
- if (hs->idle_timer) {
- timer_del(hs->idle_timer);
- timer_free(hs->idle_timer);
- hs->idle_timer = NULL;
- }
-}
-
-void hid_set_next_idle(HIDState *hs)
-{
- if (hs->idle) {
- uint64_t expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- NANOSECONDS_PER_SECOND * hs->idle * 4 / 1000;
- if (!hs->idle_timer) {
- hs->idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hid_idle_timer, hs);
- }
- timer_mod_ns(hs->idle_timer, expire_time);
- } else {
- hid_del_idle_timer(hs);
- }
-}
-
-static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- static const int bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = 0x01,
- [INPUT_BUTTON_RIGHT] = 0x02,
- [INPUT_BUTTON_MIDDLE] = 0x04,
- };
- HIDState *hs = (HIDState *)dev;
- HIDPointerEvent *e;
- InputMoveEvent *move;
- InputBtnEvent *btn;
-
- assert(hs->n < QUEUE_LENGTH);
- e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
-
- switch (evt->type) {
- case INPUT_EVENT_KIND_REL:
- move = evt->u.rel.data;
- if (move->axis == INPUT_AXIS_X) {
- e->xdx += move->value;
- } else if (move->axis == INPUT_AXIS_Y) {
- e->ydy += move->value;
- }
- break;
-
- case INPUT_EVENT_KIND_ABS:
- move = evt->u.abs.data;
- if (move->axis == INPUT_AXIS_X) {
- e->xdx = move->value;
- } else if (move->axis == INPUT_AXIS_Y) {
- e->ydy = move->value;
- }
- break;
-
- case INPUT_EVENT_KIND_BTN:
- btn = evt->u.btn.data;
- if (btn->down) {
- e->buttons_state |= bmap[btn->button];
- if (btn->button == INPUT_BUTTON_WHEEL_UP) {
- e->dz--;
- } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
- e->dz++;
- }
- } else {
- e->buttons_state &= ~bmap[btn->button];
- }
- break;
-
- default:
- /* keep gcc happy */
- break;
- }
-
-}
-
-static void hid_pointer_sync(DeviceState *dev)
-{
- HIDState *hs = (HIDState *)dev;
- HIDPointerEvent *prev, *curr, *next;
- bool event_compression = false;
-
- if (hs->n == QUEUE_LENGTH-1) {
- /*
- * Queue full. We are losing information, but we at least
- * keep track of most recent button state.
- */
- return;
- }
-
- prev = &hs->ptr.queue[(hs->head + hs->n - 1) & QUEUE_MASK];
- curr = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
- next = &hs->ptr.queue[(hs->head + hs->n + 1) & QUEUE_MASK];
-
- if (hs->n > 0) {
- /*
- * No button state change between previous and current event
- * (and previous wasn't seen by the guest yet), so there is
- * motion information only and we can combine the two event
- * into one.
- */
- if (curr->buttons_state == prev->buttons_state) {
- event_compression = true;
- }
- }
-
- if (event_compression) {
- /* add current motion to previous, clear current */
- if (hs->kind == HID_MOUSE) {
- prev->xdx += curr->xdx;
- curr->xdx = 0;
- prev->ydy += curr->ydy;
- curr->ydy = 0;
- } else {
- prev->xdx = curr->xdx;
- prev->ydy = curr->ydy;
- }
- prev->dz += curr->dz;
- curr->dz = 0;
- } else {
- /* prepate next (clear rel, copy abs + btns) */
- if (hs->kind == HID_MOUSE) {
- next->xdx = 0;
- next->ydy = 0;
- } else {
- next->xdx = curr->xdx;
- next->ydy = curr->ydy;
- }
- next->dz = 0;
- next->buttons_state = curr->buttons_state;
- /* make current guest visible, notify guest */
- hs->n++;
- hs->event(hs);
- }
-}
-
-static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- HIDState *hs = (HIDState *)dev;
- int scancodes[3], i, count;
- int slot;
- InputKeyEvent *key = evt->u.key.data;
-
- count = qemu_input_key_value_to_scancode(key->key,
- key->down,
- scancodes);
- if (hs->n + count > QUEUE_LENGTH) {
- fprintf(stderr, "usb-kbd: warning: key event queue full\n");
- return;
- }
- for (i = 0; i < count; i++) {
- slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
- hs->kbd.keycodes[slot] = scancodes[i];
- }
- hs->event(hs);
-}
-
-static void hid_keyboard_process_keycode(HIDState *hs)
-{
- uint8_t hid_code, index, key;
- int i, keycode, slot;
-
- if (hs->n == 0) {
- return;
- }
- slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
- keycode = hs->kbd.keycodes[slot];
-
- key = keycode & 0x7f;
- index = key | ((hs->kbd.modifiers & (1 << 8)) >> 1);
- hid_code = hid_usage_keys[index];
- hs->kbd.modifiers &= ~(1 << 8);
-
- switch (hid_code) {
- case 0x00:
- return;
-
- case 0xe0:
- assert(key == 0x1d);
- if (hs->kbd.modifiers & (1 << 9)) {
- /* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0.
- * Here we're processing the second hid_code. By dropping bit 9
- * and setting bit 8, the scancode after 0x1d will access the
- * second half of the table.
- */
- hs->kbd.modifiers ^= (1 << 8) | (1 << 9);
- return;
- }
- /* fall through to process Ctrl_L */
- case 0xe1 ... 0xe7:
- /* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R.
- * Handle releases here, or fall through to process presses.
- */
- if (keycode & (1 << 7)) {
- hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
- return;
- }
- /* fall through */
- case 0xe8 ... 0xe9:
- /* USB modifiers are just 1 byte long. Bits 8 and 9 of
- * hs->kbd.modifiers implement a state machine that detects the
- * 0xe0 and 0xe1/0x1d sequences. These bits do not follow the
- * usual rules where bit 7 marks released keys; they are cleared
- * elsewhere in the function as the state machine dictates.
- */
- hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
- return;
-
- case 0xea ... 0xef:
- abort();
-
- default:
- break;
- }
-
- if (keycode & (1 << 7)) {
- for (i = hs->kbd.keys - 1; i >= 0; i--) {
- if (hs->kbd.key[i] == hid_code) {
- hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
- hs->kbd.key[hs->kbd.keys] = 0x00;
- break;
- }
- }
- if (i < 0) {
- return;
- }
- } else {
- for (i = hs->kbd.keys - 1; i >= 0; i--) {
- if (hs->kbd.key[i] == hid_code) {
- break;
- }
- }
- if (i < 0) {
- if (hs->kbd.keys < sizeof(hs->kbd.key)) {
- hs->kbd.key[hs->kbd.keys++] = hid_code;
- }
- } else {
- return;
- }
- }
-}
-
-static inline int int_clamp(int val, int vmin, int vmax)
-{
- if (val < vmin) {
- return vmin;
- } else if (val > vmax) {
- return vmax;
- } else {
- return val;
- }
-}
-
-void hid_pointer_activate(HIDState *hs)
-{
- if (!hs->ptr.mouse_grabbed) {
- qemu_input_handler_activate(hs->s);
- hs->ptr.mouse_grabbed = 1;
- }
-}
-
-int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
-{
- int dx, dy, dz, l;
- int index;
- HIDPointerEvent *e;
-
- hs->idle_pending = false;
-
- hid_pointer_activate(hs);
-
- /* When the buffer is empty, return the last event. Relative
- movements will all be zero. */
- index = (hs->n ? hs->head : hs->head - 1);
- e = &hs->ptr.queue[index & QUEUE_MASK];
-
- if (hs->kind == HID_MOUSE) {
- dx = int_clamp(e->xdx, -127, 127);
- dy = int_clamp(e->ydy, -127, 127);
- e->xdx -= dx;
- e->ydy -= dy;
- } else {
- dx = e->xdx;
- dy = e->ydy;
- }
- dz = int_clamp(e->dz, -127, 127);
- e->dz -= dz;
-
- if (hs->n &&
- !e->dz &&
- (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
- /* that deals with this event */
- QUEUE_INCR(hs->head);
- hs->n--;
- }
-
- /* Appears we have to invert the wheel direction */
- dz = 0 - dz;
- l = 0;
- switch (hs->kind) {
- case HID_MOUSE:
- if (len > l) {
- buf[l++] = e->buttons_state;
- }
- if (len > l) {
- buf[l++] = dx;
- }
- if (len > l) {
- buf[l++] = dy;
- }
- if (len > l) {
- buf[l++] = dz;
- }
- break;
-
- case HID_TABLET:
- if (len > l) {
- buf[l++] = e->buttons_state;
- }
- if (len > l) {
- buf[l++] = dx & 0xff;
- }
- if (len > l) {
- buf[l++] = dx >> 8;
- }
- if (len > l) {
- buf[l++] = dy & 0xff;
- }
- if (len > l) {
- buf[l++] = dy >> 8;
- }
- if (len > l) {
- buf[l++] = dz;
- }
- break;
-
- default:
- abort();
- }
-
- return l;
-}
-
-int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
-{
- hs->idle_pending = false;
-
- if (len < 2) {
- return 0;
- }
-
- hid_keyboard_process_keycode(hs);
-
- buf[0] = hs->kbd.modifiers & 0xff;
- buf[1] = 0;
- if (hs->kbd.keys > 6) {
- memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
- } else {
- memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
- }
-
- return MIN(8, len);
-}
-
-int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
-{
- if (len > 0) {
- int ledstate = 0;
- /* 0x01: Num Lock LED
- * 0x02: Caps Lock LED
- * 0x04: Scroll Lock LED
- * 0x08: Compose LED
- * 0x10: Kana LED */
- hs->kbd.leds = buf[0];
- if (hs->kbd.leds & 0x04) {
- ledstate |= QEMU_SCROLL_LOCK_LED;
- }
- if (hs->kbd.leds & 0x01) {
- ledstate |= QEMU_NUM_LOCK_LED;
- }
- if (hs->kbd.leds & 0x02) {
- ledstate |= QEMU_CAPS_LOCK_LED;
- }
- kbd_put_ledstate(ledstate);
- }
- return 0;
-}
-
-void hid_reset(HIDState *hs)
-{
- switch (hs->kind) {
- case HID_KEYBOARD:
- memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
- memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
- hs->kbd.keys = 0;
- break;
- case HID_MOUSE:
- case HID_TABLET:
- memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
- break;
- }
- hs->head = 0;
- hs->n = 0;
- hs->protocol = 1;
- hs->idle = 0;
- hs->idle_pending = false;
- hid_del_idle_timer(hs);
-}
-
-void hid_free(HIDState *hs)
-{
- qemu_input_handler_unregister(hs->s);
- hid_del_idle_timer(hs);
-}
-
-static QemuInputHandler hid_keyboard_handler = {
- .name = "QEMU HID Keyboard",
- .mask = INPUT_EVENT_MASK_KEY,
- .event = hid_keyboard_event,
-};
-
-static QemuInputHandler hid_mouse_handler = {
- .name = "QEMU HID Mouse",
- .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
- .event = hid_pointer_event,
- .sync = hid_pointer_sync,
-};
-
-static QemuInputHandler hid_tablet_handler = {
- .name = "QEMU HID Tablet",
- .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
- .event = hid_pointer_event,
- .sync = hid_pointer_sync,
-};
-
-void hid_init(HIDState *hs, int kind, HIDEventFunc event)
-{
- hs->kind = kind;
- hs->event = event;
-
- if (hs->kind == HID_KEYBOARD) {
- hs->s = qemu_input_handler_register((DeviceState *)hs,
- &hid_keyboard_handler);
- qemu_input_handler_activate(hs->s);
- } else if (hs->kind == HID_MOUSE) {
- hs->s = qemu_input_handler_register((DeviceState *)hs,
- &hid_mouse_handler);
- } else if (hs->kind == HID_TABLET) {
- hs->s = qemu_input_handler_register((DeviceState *)hs,
- &hid_tablet_handler);
- }
-}
-
-static int hid_post_load(void *opaque, int version_id)
-{
- HIDState *s = opaque;
-
- hid_set_next_idle(s);
-
- if (s->n == QUEUE_LENGTH && (s->kind == HID_TABLET ||
- s->kind == HID_MOUSE)) {
- /*
- * Handle ptr device migration from old qemu with full queue.
- *
- * Throw away everything but the last event, so we propagate
- * at least the current button state to the guest. Also keep
- * current position for the tablet, signal "no motion" for the
- * mouse.
- */
- HIDPointerEvent evt;
- evt = s->ptr.queue[(s->head+s->n) & QUEUE_MASK];
- if (s->kind == HID_MOUSE) {
- evt.xdx = 0;
- evt.ydy = 0;
- }
- s->ptr.queue[0] = evt;
- s->head = 0;
- s->n = 1;
- }
- return 0;
-}
-
-static const VMStateDescription vmstate_hid_ptr_queue = {
- .name = "HIDPointerEventQueue",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(xdx, HIDPointerEvent),
- VMSTATE_INT32(ydy, HIDPointerEvent),
- VMSTATE_INT32(dz, HIDPointerEvent),
- VMSTATE_INT32(buttons_state, HIDPointerEvent),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_hid_ptr_device = {
- .name = "HIDPointerDevice",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = hid_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0,
- vmstate_hid_ptr_queue, HIDPointerEvent),
- VMSTATE_UINT32(head, HIDState),
- VMSTATE_UINT32(n, HIDState),
- VMSTATE_INT32(protocol, HIDState),
- VMSTATE_UINT8(idle, HIDState),
- VMSTATE_END_OF_LIST(),
- }
-};
-
-const VMStateDescription vmstate_hid_keyboard_device = {
- .name = "HIDKeyboardDevice",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = hid_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH),
- VMSTATE_UINT32(head, HIDState),
- VMSTATE_UINT32(n, HIDState),
- VMSTATE_UINT16(kbd.modifiers, HIDState),
- VMSTATE_UINT8(kbd.leds, HIDState),
- VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16),
- VMSTATE_INT32(kbd.keys, HIDState),
- VMSTATE_INT32(protocol, HIDState),
- VMSTATE_UINT8(idle, HIDState),
- VMSTATE_END_OF_LIST(),
- }
-};
diff --git a/qemu/hw/input/lm832x.c b/qemu/hw/input/lm832x.c
deleted file mode 100644
index 539682cac..000000000
--- a/qemu/hw/input/lm832x.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * National Semiconductor LM8322/8323 GPIO keyboard & PWM chips.
- *
- * Copyright (C) 2008 Nokia Corporation
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/i2c/i2c.h"
-#include "qemu/timer.h"
-#include "ui/console.h"
-
-#define TYPE_LM8323 "lm8323"
-#define LM8323(obj) OBJECT_CHECK(LM823KbdState, (obj), TYPE_LM8323)
-
-typedef struct {
- I2CSlave parent_obj;
-
- uint8_t i2c_dir;
- uint8_t i2c_cycle;
- uint8_t reg;
-
- qemu_irq nirq;
- uint16_t model;
-
- struct {
- qemu_irq out[2];
- int in[2][2];
- } mux;
-
- uint8_t config;
- uint8_t status;
- uint8_t acttime;
- uint8_t error;
- uint8_t clock;
-
- struct {
- uint16_t pull;
- uint16_t mask;
- uint16_t dir;
- uint16_t level;
- qemu_irq out[16];
- } gpio;
-
- struct {
- uint8_t dbnctime;
- uint8_t size;
- uint8_t start;
- uint8_t len;
- uint8_t fifo[16];
- } kbd;
-
- struct {
- uint16_t file[256];
- uint8_t faddr;
- uint8_t addr[3];
- QEMUTimer *tm[3];
- } pwm;
-} LM823KbdState;
-
-#define INT_KEYPAD (1 << 0)
-#define INT_ERROR (1 << 3)
-#define INT_NOINIT (1 << 4)
-#define INT_PWMEND(n) (1 << (5 + n))
-
-#define ERR_BADPAR (1 << 0)
-#define ERR_CMDUNK (1 << 1)
-#define ERR_KEYOVR (1 << 2)
-#define ERR_FIFOOVR (1 << 6)
-
-static void lm_kbd_irq_update(LM823KbdState *s)
-{
- qemu_set_irq(s->nirq, !s->status);
-}
-
-static void lm_kbd_gpio_update(LM823KbdState *s)
-{
-}
-
-static void lm_kbd_reset(LM823KbdState *s)
-{
- s->config = 0x80;
- s->status = INT_NOINIT;
- s->acttime = 125;
- s->kbd.dbnctime = 3;
- s->kbd.size = 0x33;
- s->clock = 0x08;
-
- lm_kbd_irq_update(s);
- lm_kbd_gpio_update(s);
-}
-
-static void lm_kbd_error(LM823KbdState *s, int err)
-{
- s->error |= err;
- s->status |= INT_ERROR;
- lm_kbd_irq_update(s);
-}
-
-static void lm_kbd_pwm_tick(LM823KbdState *s, int line)
-{
-}
-
-static void lm_kbd_pwm_start(LM823KbdState *s, int line)
-{
- lm_kbd_pwm_tick(s, line);
-}
-
-static void lm_kbd_pwm0_tick(void *opaque)
-{
- lm_kbd_pwm_tick(opaque, 0);
-}
-static void lm_kbd_pwm1_tick(void *opaque)
-{
- lm_kbd_pwm_tick(opaque, 1);
-}
-static void lm_kbd_pwm2_tick(void *opaque)
-{
- lm_kbd_pwm_tick(opaque, 2);
-}
-
-enum {
- LM832x_CMD_READ_ID = 0x80, /* Read chip ID. */
- LM832x_CMD_WRITE_CFG = 0x81, /* Set configuration item. */
- LM832x_CMD_READ_INT = 0x82, /* Get interrupt status. */
- LM832x_CMD_RESET = 0x83, /* Reset, same as external one */
- LM823x_CMD_WRITE_PULL_DOWN = 0x84, /* Select GPIO pull-up/down. */
- LM832x_CMD_WRITE_PORT_SEL = 0x85, /* Select GPIO in/out. */
- LM832x_CMD_WRITE_PORT_STATE = 0x86, /* Set GPIO pull-up/down. */
- LM832x_CMD_READ_PORT_SEL = 0x87, /* Get GPIO in/out. */
- LM832x_CMD_READ_PORT_STATE = 0x88, /* Get GPIO pull-up/down. */
- LM832x_CMD_READ_FIFO = 0x89, /* Read byte from FIFO. */
- LM832x_CMD_RPT_READ_FIFO = 0x8a, /* Read FIFO (no increment). */
- LM832x_CMD_SET_ACTIVE = 0x8b, /* Set active time. */
- LM832x_CMD_READ_ERROR = 0x8c, /* Get error status. */
- LM832x_CMD_READ_ROTATOR = 0x8e, /* Read rotator status. */
- LM832x_CMD_SET_DEBOUNCE = 0x8f, /* Set debouncing time. */
- LM832x_CMD_SET_KEY_SIZE = 0x90, /* Set keypad size. */
- LM832x_CMD_READ_KEY_SIZE = 0x91, /* Get keypad size. */
- LM832x_CMD_READ_CFG = 0x92, /* Get configuration item. */
- LM832x_CMD_WRITE_CLOCK = 0x93, /* Set clock config. */
- LM832x_CMD_READ_CLOCK = 0x94, /* Get clock config. */
- LM832x_CMD_PWM_WRITE = 0x95, /* Write PWM script. */
- LM832x_CMD_PWM_START = 0x96, /* Start PWM engine. */
- LM832x_CMD_PWM_STOP = 0x97, /* Stop PWM engine. */
- LM832x_GENERAL_ERROR = 0xff, /* There was one error.
- Previously was represented by -1
- This is not a command */
-};
-
-#define LM832x_MAX_KPX 8
-#define LM832x_MAX_KPY 12
-
-static uint8_t lm_kbd_read(LM823KbdState *s, int reg, int byte)
-{
- int ret;
-
- switch (reg) {
- case LM832x_CMD_READ_ID:
- ret = 0x0400;
- break;
-
- case LM832x_CMD_READ_INT:
- ret = s->status;
- if (!(s->status & INT_NOINIT)) {
- s->status = 0;
- lm_kbd_irq_update(s);
- }
- break;
-
- case LM832x_CMD_READ_PORT_SEL:
- ret = s->gpio.dir;
- break;
- case LM832x_CMD_READ_PORT_STATE:
- ret = s->gpio.mask;
- break;
-
- case LM832x_CMD_READ_FIFO:
- if (s->kbd.len <= 1)
- return 0x00;
-
- /* Example response from the two commands after a INT_KEYPAD
- * interrupt caused by the key 0x3c being pressed:
- * RPT_READ_FIFO: 55 bc 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
- * READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
- * RPT_READ_FIFO: bc 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9 01
- *
- * 55 is the code of the key release event serviced in the previous
- * interrupt handling.
- *
- * TODO: find out whether the FIFO is advanced a single character
- * before reading every byte or the whole size of the FIFO at the
- * last LM832x_CMD_READ_FIFO. This affects LM832x_CMD_RPT_READ_FIFO
- * output in cases where there are more than one event in the FIFO.
- * Assume 0xbc and 0x3c events are in the FIFO:
- * RPT_READ_FIFO: 55 bc 3c 00 4e ff 0a 50 08 00 29 d9 08 01 c9
- * READ_FIFO: bc 3c 00 00 4e ff 0a 50 08 00 29 d9 08 01 c9
- * Does RPT_READ_FIFO now return 0xbc and 0x3c or only 0x3c?
- */
- s->kbd.start ++;
- s->kbd.start &= sizeof(s->kbd.fifo) - 1;
- s->kbd.len --;
-
- return s->kbd.fifo[s->kbd.start];
- case LM832x_CMD_RPT_READ_FIFO:
- if (byte >= s->kbd.len)
- return 0x00;
-
- return s->kbd.fifo[(s->kbd.start + byte) & (sizeof(s->kbd.fifo) - 1)];
-
- case LM832x_CMD_READ_ERROR:
- return s->error;
-
- case LM832x_CMD_READ_ROTATOR:
- return 0;
-
- case LM832x_CMD_READ_KEY_SIZE:
- return s->kbd.size;
-
- case LM832x_CMD_READ_CFG:
- return s->config & 0xf;
-
- case LM832x_CMD_READ_CLOCK:
- return (s->clock & 0xfc) | 2;
-
- default:
- lm_kbd_error(s, ERR_CMDUNK);
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
- return 0x00;
- }
-
- return ret >> (byte << 3);
-}
-
-static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
-{
- switch (reg) {
- case LM832x_CMD_WRITE_CFG:
- s->config = value;
- /* This must be done whenever s->mux.in is updated (never). */
- if ((s->config >> 1) & 1) /* MUX1EN */
- qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 0) & 1]);
- if ((s->config >> 3) & 1) /* MUX2EN */
- qemu_set_irq(s->mux.out[0], s->mux.in[0][(s->config >> 2) & 1]);
- /* TODO: check that this is issued only following the chip reset
- * and not in the middle of operation and that it is followed by
- * the GPIO ports re-resablishing through WRITE_PORT_SEL and
- * WRITE_PORT_STATE (using a timer perhaps) and otherwise output
- * warnings. */
- s->status = 0;
- lm_kbd_irq_update(s);
- s->kbd.len = 0;
- s->kbd.start = 0;
- s->reg = LM832x_GENERAL_ERROR;
- break;
-
- case LM832x_CMD_RESET:
- if (value == 0xaa)
- lm_kbd_reset(s);
- else
- lm_kbd_error(s, ERR_BADPAR);
- s->reg = LM832x_GENERAL_ERROR;
- break;
-
- case LM823x_CMD_WRITE_PULL_DOWN:
- if (!byte)
- s->gpio.pull = value;
- else {
- s->gpio.pull |= value << 8;
- lm_kbd_gpio_update(s);
- s->reg = LM832x_GENERAL_ERROR;
- }
- break;
- case LM832x_CMD_WRITE_PORT_SEL:
- if (!byte)
- s->gpio.dir = value;
- else {
- s->gpio.dir |= value << 8;
- lm_kbd_gpio_update(s);
- s->reg = LM832x_GENERAL_ERROR;
- }
- break;
- case LM832x_CMD_WRITE_PORT_STATE:
- if (!byte)
- s->gpio.mask = value;
- else {
- s->gpio.mask |= value << 8;
- lm_kbd_gpio_update(s);
- s->reg = LM832x_GENERAL_ERROR;
- }
- break;
-
- case LM832x_CMD_SET_ACTIVE:
- s->acttime = value;
- s->reg = LM832x_GENERAL_ERROR;
- break;
-
- case LM832x_CMD_SET_DEBOUNCE:
- s->kbd.dbnctime = value;
- s->reg = LM832x_GENERAL_ERROR;
- if (!value)
- lm_kbd_error(s, ERR_BADPAR);
- break;
-
- case LM832x_CMD_SET_KEY_SIZE:
- s->kbd.size = value;
- s->reg = LM832x_GENERAL_ERROR;
- if (
- (value & 0xf) < 3 || (value & 0xf) > LM832x_MAX_KPY ||
- (value >> 4) < 3 || (value >> 4) > LM832x_MAX_KPX)
- lm_kbd_error(s, ERR_BADPAR);
- break;
-
- case LM832x_CMD_WRITE_CLOCK:
- s->clock = value;
- s->reg = LM832x_GENERAL_ERROR;
- if ((value & 3) && (value & 3) != 3) {
- lm_kbd_error(s, ERR_BADPAR);
- fprintf(stderr, "%s: invalid clock setting in RCPWM\n",
- __FUNCTION__);
- }
- /* TODO: Validate that the command is only issued once */
- break;
-
- case LM832x_CMD_PWM_WRITE:
- if (byte == 0) {
- if (!(value & 3) || (value >> 2) > 59) {
- lm_kbd_error(s, ERR_BADPAR);
- s->reg = LM832x_GENERAL_ERROR;
- break;
- }
-
- s->pwm.faddr = value;
- s->pwm.file[s->pwm.faddr] = 0;
- } else if (byte == 1) {
- s->pwm.file[s->pwm.faddr] |= value << 8;
- } else if (byte == 2) {
- s->pwm.file[s->pwm.faddr] |= value << 0;
- s->reg = LM832x_GENERAL_ERROR;
- }
- break;
- case LM832x_CMD_PWM_START:
- s->reg = LM832x_GENERAL_ERROR;
- if (!(value & 3) || (value >> 2) > 59) {
- lm_kbd_error(s, ERR_BADPAR);
- break;
- }
-
- s->pwm.addr[(value & 3) - 1] = value >> 2;
- lm_kbd_pwm_start(s, (value & 3) - 1);
- break;
- case LM832x_CMD_PWM_STOP:
- s->reg = LM832x_GENERAL_ERROR;
- if (!(value & 3)) {
- lm_kbd_error(s, ERR_BADPAR);
- break;
- }
-
- timer_del(s->pwm.tm[(value & 3) - 1]);
- break;
-
- case LM832x_GENERAL_ERROR:
- lm_kbd_error(s, ERR_BADPAR);
- break;
- default:
- lm_kbd_error(s, ERR_CMDUNK);
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
- break;
- }
-}
-
-static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
-{
- LM823KbdState *s = LM8323(i2c);
-
- switch (event) {
- case I2C_START_RECV:
- case I2C_START_SEND:
- s->i2c_cycle = 0;
- s->i2c_dir = (event == I2C_START_SEND);
- break;
-
- default:
- break;
- }
-}
-
-static int lm_i2c_rx(I2CSlave *i2c)
-{
- LM823KbdState *s = LM8323(i2c);
-
- return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
-}
-
-static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
-{
- LM823KbdState *s = LM8323(i2c);
-
- if (!s->i2c_cycle)
- s->reg = data;
- else
- lm_kbd_write(s, s->reg, s->i2c_cycle - 1, data);
- s->i2c_cycle ++;
-
- return 0;
-}
-
-static int lm_kbd_post_load(void *opaque, int version_id)
-{
- LM823KbdState *s = opaque;
-
- lm_kbd_irq_update(s);
- lm_kbd_gpio_update(s);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_lm_kbd = {
- .name = "LM8323",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = lm_kbd_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_I2C_SLAVE(parent_obj, LM823KbdState),
- VMSTATE_UINT8(i2c_dir, LM823KbdState),
- VMSTATE_UINT8(i2c_cycle, LM823KbdState),
- VMSTATE_UINT8(reg, LM823KbdState),
- VMSTATE_UINT8(config, LM823KbdState),
- VMSTATE_UINT8(status, LM823KbdState),
- VMSTATE_UINT8(acttime, LM823KbdState),
- VMSTATE_UINT8(error, LM823KbdState),
- VMSTATE_UINT8(clock, LM823KbdState),
- VMSTATE_UINT16(gpio.pull, LM823KbdState),
- VMSTATE_UINT16(gpio.mask, LM823KbdState),
- VMSTATE_UINT16(gpio.dir, LM823KbdState),
- VMSTATE_UINT16(gpio.level, LM823KbdState),
- VMSTATE_UINT8(kbd.dbnctime, LM823KbdState),
- VMSTATE_UINT8(kbd.size, LM823KbdState),
- VMSTATE_UINT8(kbd.start, LM823KbdState),
- VMSTATE_UINT8(kbd.len, LM823KbdState),
- VMSTATE_BUFFER(kbd.fifo, LM823KbdState),
- VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256),
- VMSTATE_UINT8(pwm.faddr, LM823KbdState),
- VMSTATE_BUFFER(pwm.addr, LM823KbdState),
- VMSTATE_TIMER_PTR_ARRAY(pwm.tm, LM823KbdState, 3),
- VMSTATE_END_OF_LIST()
- }
-};
-
-
-static int lm8323_init(I2CSlave *i2c)
-{
- LM823KbdState *s = LM8323(i2c);
-
- s->model = 0x8323;
- s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
- s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
- s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
- qdev_init_gpio_out(DEVICE(i2c), &s->nirq, 1);
-
- lm_kbd_reset(s);
-
- qemu_register_reset((void *) lm_kbd_reset, s);
- return 0;
-}
-
-void lm832x_key_event(DeviceState *dev, int key, int state)
-{
- LM823KbdState *s = LM8323(dev);
-
- if ((s->status & INT_ERROR) && (s->error & ERR_FIFOOVR))
- return;
-
- if (s->kbd.len >= sizeof(s->kbd.fifo)) {
- lm_kbd_error(s, ERR_FIFOOVR);
- return;
- }
-
- s->kbd.fifo[(s->kbd.start + s->kbd.len ++) & (sizeof(s->kbd.fifo) - 1)] =
- key | (state << 7);
-
- /* We never set ERR_KEYOVR because we support multiple keys fine. */
- s->status |= INT_KEYPAD;
- lm_kbd_irq_update(s);
-}
-
-static void lm8323_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
-
- k->init = lm8323_init;
- k->event = lm_i2c_event;
- k->recv = lm_i2c_rx;
- k->send = lm_i2c_tx;
- dc->vmsd = &vmstate_lm_kbd;
-}
-
-static const TypeInfo lm8323_info = {
- .name = TYPE_LM8323,
- .parent = TYPE_I2C_SLAVE,
- .instance_size = sizeof(LM823KbdState),
- .class_init = lm8323_class_init,
-};
-
-static void lm832x_register_types(void)
-{
- type_register_static(&lm8323_info);
-}
-
-type_init(lm832x_register_types)
diff --git a/qemu/hw/input/milkymist-softusb.c b/qemu/hw/input/milkymist-softusb.c
deleted file mode 100644
index 40dfca157..000000000
--- a/qemu/hw/input/milkymist-softusb.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * QEMU model of the Milkymist SoftUSB block.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- *
- * Specification available at:
- * not available yet
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "trace.h"
-#include "ui/console.h"
-#include "hw/input/hid.h"
-#include "qemu/error-report.h"
-
-enum {
- R_CTRL = 0,
- R_MAX
-};
-
-enum {
- CTRL_RESET = (1<<0),
-};
-
-#define COMLOC_DEBUG_PRODUCE 0x1000
-#define COMLOC_DEBUG_BASE 0x1001
-#define COMLOC_MEVT_PRODUCE 0x1101
-#define COMLOC_MEVT_BASE 0x1102
-#define COMLOC_KEVT_PRODUCE 0x1142
-#define COMLOC_KEVT_BASE 0x1143
-
-#define TYPE_MILKYMIST_SOFTUSB "milkymist-softusb"
-#define MILKYMIST_SOFTUSB(obj) \
- OBJECT_CHECK(MilkymistSoftUsbState, (obj), TYPE_MILKYMIST_SOFTUSB)
-
-struct MilkymistSoftUsbState {
- SysBusDevice parent_obj;
-
- HIDState hid_kbd;
- HIDState hid_mouse;
-
- MemoryRegion regs_region;
- MemoryRegion pmem;
- MemoryRegion dmem;
- qemu_irq irq;
-
- void *pmem_ptr;
- void *dmem_ptr;
-
- /* device properties */
- uint32_t pmem_size;
- uint32_t dmem_size;
-
- /* device registers */
- uint32_t regs[R_MAX];
-
- /* mouse state */
- uint8_t mouse_hid_buffer[4];
-
- /* keyboard state */
- uint8_t kbd_hid_buffer[8];
-};
-typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
-
-static uint64_t softusb_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistSoftUsbState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_softusb: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_softusb_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void
-softusb_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistSoftUsbState *s = opaque;
-
- trace_milkymist_softusb_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- s->regs[addr] = value;
- break;
-
- default:
- error_report("milkymist_softusb: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps softusb_mmio_ops = {
- .read = softusb_read,
- .write = softusb_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
- uint32_t offset, uint8_t *buf, uint32_t len)
-{
- if (offset + len >= s->dmem_size) {
- error_report("milkymist_softusb: read dmem out of bounds "
- "at offset 0x%x, len %d", offset, len);
- memset(buf, 0, len);
- return;
- }
-
- memcpy(buf, s->dmem_ptr + offset, len);
-}
-
-static inline void softusb_write_dmem(MilkymistSoftUsbState *s,
- uint32_t offset, uint8_t *buf, uint32_t len)
-{
- if (offset + len >= s->dmem_size) {
- error_report("milkymist_softusb: write dmem out of bounds "
- "at offset 0x%x, len %d", offset, len);
- return;
- }
-
- memcpy(s->dmem_ptr + offset, buf, len);
-}
-
-static void softusb_mouse_changed(MilkymistSoftUsbState *s)
-{
- uint8_t m;
-
- softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
- trace_milkymist_softusb_mevt(m);
- softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4);
- m = (m + 1) & 0xf;
- softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
-
- trace_milkymist_softusb_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static void softusb_kbd_changed(MilkymistSoftUsbState *s)
-{
- uint8_t m;
-
- softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
- trace_milkymist_softusb_kevt(m);
- softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8);
- m = (m + 1) & 0x7;
- softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
-
- trace_milkymist_softusb_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static void softusb_kbd_hid_datain(HIDState *hs)
-{
- MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd);
- int len;
-
- /* if device is in reset, do nothing */
- if (s->regs[R_CTRL] & CTRL_RESET) {
- return;
- }
-
- while (hid_has_events(hs)) {
- len = hid_keyboard_poll(hs, s->kbd_hid_buffer,
- sizeof(s->kbd_hid_buffer));
-
- if (len == 8) {
- softusb_kbd_changed(s);
- }
- }
-}
-
-static void softusb_mouse_hid_datain(HIDState *hs)
-{
- MilkymistSoftUsbState *s =
- container_of(hs, MilkymistSoftUsbState, hid_mouse);
- int len;
-
- /* if device is in reset, do nothing */
- if (s->regs[R_CTRL] & CTRL_RESET) {
- return;
- }
-
- while (hid_has_events(hs)) {
- len = hid_pointer_poll(hs, s->mouse_hid_buffer,
- sizeof(s->mouse_hid_buffer));
-
- if (len == 4) {
- softusb_mouse_changed(s);
- }
- }
-}
-
-static void milkymist_softusb_reset(DeviceState *d)
-{
- MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
- memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer));
- memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer));
-
- hid_reset(&s->hid_kbd);
- hid_reset(&s->hid_mouse);
-
- /* defaults */
- s->regs[R_CTRL] = CTRL_RESET;
-}
-
-static int milkymist_softusb_init(SysBusDevice *dev)
-{
- MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev);
-
- sysbus_init_irq(dev, &s->irq);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s,
- "milkymist-softusb", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-
- /* register pmem and dmem */
- memory_region_init_ram(&s->pmem, OBJECT(s), "milkymist-softusb.pmem",
- s->pmem_size, &error_fatal);
- vmstate_register_ram_global(&s->pmem);
- s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem);
- sysbus_init_mmio(dev, &s->pmem);
- memory_region_init_ram(&s->dmem, OBJECT(s), "milkymist-softusb.dmem",
- s->dmem_size, &error_fatal);
- vmstate_register_ram_global(&s->dmem);
- s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem);
- sysbus_init_mmio(dev, &s->dmem);
-
- hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
- hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_milkymist_softusb = {
- .name = "milkymist-softusb",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX),
- VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState),
- VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState),
- VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState),
- VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_softusb_properties[] = {
- DEFINE_PROP_UINT32("pmem_size", MilkymistSoftUsbState, pmem_size, 0x00001000),
- DEFINE_PROP_UINT32("dmem_size", MilkymistSoftUsbState, dmem_size, 0x00002000),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = milkymist_softusb_init;
- dc->reset = milkymist_softusb_reset;
- dc->vmsd = &vmstate_milkymist_softusb;
- dc->props = milkymist_softusb_properties;
-}
-
-static const TypeInfo milkymist_softusb_info = {
- .name = TYPE_MILKYMIST_SOFTUSB,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistSoftUsbState),
- .class_init = milkymist_softusb_class_init,
-};
-
-static void milkymist_softusb_register_types(void)
-{
- type_register_static(&milkymist_softusb_info);
-}
-
-type_init(milkymist_softusb_register_types)
diff --git a/qemu/hw/input/pckbd.c b/qemu/hw/input/pckbd.c
deleted file mode 100644
index 1d932ec19..000000000
--- a/qemu/hw/input/pckbd.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * QEMU PC keyboard emulation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/isa/isa.h"
-#include "hw/i386/pc.h"
-#include "hw/input/ps2.h"
-#include "sysemu/sysemu.h"
-
-/* debug PC keyboard */
-//#define DEBUG_KBD
-#ifdef DEBUG_KBD
-#define DPRINTF(fmt, ...) \
- do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-/* Keyboard Controller Commands */
-#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
-#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
-#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
-#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
-#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
-#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
-#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
-#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
-#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
-#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
-#define KBD_CCMD_READ_INPORT 0xC0 /* read input port */
-#define KBD_CCMD_READ_OUTPORT 0xD0 /* read output port */
-#define KBD_CCMD_WRITE_OUTPORT 0xD1 /* write output port */
-#define KBD_CCMD_WRITE_OBUF 0xD2
-#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
- initiated by the auxiliary device */
-#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
-#define KBD_CCMD_DISABLE_A20 0xDD /* HP vectra only ? */
-#define KBD_CCMD_ENABLE_A20 0xDF /* HP vectra only ? */
-#define KBD_CCMD_PULSE_BITS_3_0 0xF0 /* Pulse bits 3-0 of the output port P2. */
-#define KBD_CCMD_RESET 0xFE /* Pulse bit 0 of the output port P2 = CPU reset. */
-#define KBD_CCMD_NO_OP 0xFF /* Pulse no bits of the output port P2. */
-
-/* Keyboard Commands */
-#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
-#define KBD_CMD_ECHO 0xEE
-#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
-#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
-#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
-#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
-#define KBD_CMD_RESET 0xFF /* Reset */
-
-/* Keyboard Replies */
-#define KBD_REPLY_POR 0xAA /* Power on reset */
-#define KBD_REPLY_ACK 0xFA /* Command ACK */
-#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
-
-/* Status Register Bits */
-#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
-#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
-#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
-#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
-#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
-#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
-#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
-#define KBD_STAT_PERR 0x80 /* Parity error */
-
-/* Controller Mode Register Bits */
-#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
-#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
-#define KBD_MODE_SYS 0x04 /* The system flag (?) */
-#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
-#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
-#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
-#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
-#define KBD_MODE_RFU 0x80
-
-/* Output Port Bits */
-#define KBD_OUT_RESET 0x01 /* 1=normal mode, 0=reset */
-#define KBD_OUT_A20 0x02 /* x86 only */
-#define KBD_OUT_OBF 0x10 /* Keyboard output buffer full */
-#define KBD_OUT_MOUSE_OBF 0x20 /* Mouse output buffer full */
-
-/* OSes typically write 0xdd/0xdf to turn the A20 line off and on.
- * We make the default value of the outport include these four bits,
- * so that the subsection is rarely necessary.
- */
-#define KBD_OUT_ONES 0xcc
-
-/* Mouse Commands */
-#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
-#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
-#define AUX_SET_RES 0xE8 /* Set resolution */
-#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
-#define AUX_SET_STREAM 0xEA /* Set stream mode */
-#define AUX_POLL 0xEB /* Poll */
-#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
-#define AUX_SET_WRAP 0xEE /* Set wrap mode */
-#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
-#define AUX_GET_TYPE 0xF2 /* Get type */
-#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
-#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
-#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
-#define AUX_SET_DEFAULT 0xF6
-#define AUX_RESET 0xFF /* Reset aux device */
-#define AUX_ACK 0xFA /* Command byte ACK. */
-
-#define MOUSE_STATUS_REMOTE 0x40
-#define MOUSE_STATUS_ENABLED 0x20
-#define MOUSE_STATUS_SCALE21 0x10
-
-#define KBD_PENDING_KBD 1
-#define KBD_PENDING_AUX 2
-
-typedef struct KBDState {
- uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
- uint8_t status;
- uint8_t mode;
- uint8_t outport;
- bool outport_present;
- /* Bitmask of devices with data available. */
- uint8_t pending;
- void *kbd;
- void *mouse;
-
- qemu_irq irq_kbd;
- qemu_irq irq_mouse;
- qemu_irq *a20_out;
- hwaddr mask;
-} KBDState;
-
-/* update irq and KBD_STAT_[MOUSE_]OBF */
-/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
- incorrect, but it avoids having to simulate exact delays */
-static void kbd_update_irq(KBDState *s)
-{
- int irq_kbd_level, irq_mouse_level;
-
- irq_kbd_level = 0;
- irq_mouse_level = 0;
- s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
- s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF);
- if (s->pending) {
- s->status |= KBD_STAT_OBF;
- s->outport |= KBD_OUT_OBF;
- /* kbd data takes priority over aux data. */
- if (s->pending == KBD_PENDING_AUX) {
- s->status |= KBD_STAT_MOUSE_OBF;
- s->outport |= KBD_OUT_MOUSE_OBF;
- if (s->mode & KBD_MODE_MOUSE_INT)
- irq_mouse_level = 1;
- } else {
- if ((s->mode & KBD_MODE_KBD_INT) &&
- !(s->mode & KBD_MODE_DISABLE_KBD))
- irq_kbd_level = 1;
- }
- }
- qemu_set_irq(s->irq_kbd, irq_kbd_level);
- qemu_set_irq(s->irq_mouse, irq_mouse_level);
-}
-
-static void kbd_update_kbd_irq(void *opaque, int level)
-{
- KBDState *s = (KBDState *)opaque;
-
- if (level)
- s->pending |= KBD_PENDING_KBD;
- else
- s->pending &= ~KBD_PENDING_KBD;
- kbd_update_irq(s);
-}
-
-static void kbd_update_aux_irq(void *opaque, int level)
-{
- KBDState *s = (KBDState *)opaque;
-
- if (level)
- s->pending |= KBD_PENDING_AUX;
- else
- s->pending &= ~KBD_PENDING_AUX;
- kbd_update_irq(s);
-}
-
-static uint64_t kbd_read_status(void *opaque, hwaddr addr,
- unsigned size)
-{
- KBDState *s = opaque;
- int val;
- val = s->status;
- DPRINTF("kbd: read status=0x%02x\n", val);
- return val;
-}
-
-static void kbd_queue(KBDState *s, int b, int aux)
-{
- if (aux)
- ps2_queue(s->mouse, b);
- else
- ps2_queue(s->kbd, b);
-}
-
-static void outport_write(KBDState *s, uint32_t val)
-{
- DPRINTF("kbd: write outport=0x%02x\n", val);
- s->outport = val;
- if (s->a20_out) {
- qemu_set_irq(*s->a20_out, (val >> 1) & 1);
- }
- if (!(val & 1)) {
- qemu_system_reset_request();
- }
-}
-
-static void kbd_write_command(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- KBDState *s = opaque;
-
- DPRINTF("kbd: write cmd=0x%02" PRIx64 "\n", val);
-
- /* Bits 3-0 of the output port P2 of the keyboard controller may be pulsed
- * low for approximately 6 micro seconds. Bits 3-0 of the KBD_CCMD_PULSE
- * command specify the output port bits to be pulsed.
- * 0: Bit should be pulsed. 1: Bit should not be modified.
- * The only useful version of this command is pulsing bit 0,
- * which does a CPU reset.
- */
- if((val & KBD_CCMD_PULSE_BITS_3_0) == KBD_CCMD_PULSE_BITS_3_0) {
- if(!(val & 1))
- val = KBD_CCMD_RESET;
- else
- val = KBD_CCMD_NO_OP;
- }
-
- switch(val) {
- case KBD_CCMD_READ_MODE:
- kbd_queue(s, s->mode, 0);
- break;
- case KBD_CCMD_WRITE_MODE:
- case KBD_CCMD_WRITE_OBUF:
- case KBD_CCMD_WRITE_AUX_OBUF:
- case KBD_CCMD_WRITE_MOUSE:
- case KBD_CCMD_WRITE_OUTPORT:
- s->write_cmd = val;
- break;
- case KBD_CCMD_MOUSE_DISABLE:
- s->mode |= KBD_MODE_DISABLE_MOUSE;
- break;
- case KBD_CCMD_MOUSE_ENABLE:
- s->mode &= ~KBD_MODE_DISABLE_MOUSE;
- break;
- case KBD_CCMD_TEST_MOUSE:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_SELF_TEST:
- s->status |= KBD_STAT_SELFTEST;
- kbd_queue(s, 0x55, 0);
- break;
- case KBD_CCMD_KBD_TEST:
- kbd_queue(s, 0x00, 0);
- break;
- case KBD_CCMD_KBD_DISABLE:
- s->mode |= KBD_MODE_DISABLE_KBD;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_KBD_ENABLE:
- s->mode &= ~KBD_MODE_DISABLE_KBD;
- kbd_update_irq(s);
- break;
- case KBD_CCMD_READ_INPORT:
- kbd_queue(s, 0x80, 0);
- break;
- case KBD_CCMD_READ_OUTPORT:
- kbd_queue(s, s->outport, 0);
- break;
- case KBD_CCMD_ENABLE_A20:
- if (s->a20_out) {
- qemu_irq_raise(*s->a20_out);
- }
- s->outport |= KBD_OUT_A20;
- break;
- case KBD_CCMD_DISABLE_A20:
- if (s->a20_out) {
- qemu_irq_lower(*s->a20_out);
- }
- s->outport &= ~KBD_OUT_A20;
- break;
- case KBD_CCMD_RESET:
- qemu_system_reset_request();
- break;
- case KBD_CCMD_NO_OP:
- /* ignore that */
- break;
- default:
- fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", (int)val);
- break;
- }
-}
-
-static uint64_t kbd_read_data(void *opaque, hwaddr addr,
- unsigned size)
-{
- KBDState *s = opaque;
- uint32_t val;
-
- if (s->pending == KBD_PENDING_AUX)
- val = ps2_read_data(s->mouse);
- else
- val = ps2_read_data(s->kbd);
-
- DPRINTF("kbd: read data=0x%02x\n", val);
- return val;
-}
-
-static void kbd_write_data(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- KBDState *s = opaque;
-
- DPRINTF("kbd: write data=0x%02" PRIx64 "\n", val);
-
- switch(s->write_cmd) {
- case 0:
- ps2_write_keyboard(s->kbd, val);
- break;
- case KBD_CCMD_WRITE_MODE:
- s->mode = val;
- ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0);
- /* ??? */
- kbd_update_irq(s);
- break;
- case KBD_CCMD_WRITE_OBUF:
- kbd_queue(s, val, 0);
- break;
- case KBD_CCMD_WRITE_AUX_OBUF:
- kbd_queue(s, val, 1);
- break;
- case KBD_CCMD_WRITE_OUTPORT:
- outport_write(s, val);
- break;
- case KBD_CCMD_WRITE_MOUSE:
- ps2_write_mouse(s->mouse, val);
- break;
- default:
- break;
- }
- s->write_cmd = 0;
-}
-
-static void kbd_reset(void *opaque)
-{
- KBDState *s = opaque;
-
- s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
- s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
- s->outport = KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES;
- s->outport_present = false;
-}
-
-static uint8_t kbd_outport_default(KBDState *s)
-{
- return KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES
- | (s->status & KBD_STAT_OBF ? KBD_OUT_OBF : 0)
- | (s->status & KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0);
-}
-
-static int kbd_outport_post_load(void *opaque, int version_id)
-{
- KBDState *s = opaque;
- s->outport_present = true;
- return 0;
-}
-
-static bool kbd_outport_needed(void *opaque)
-{
- KBDState *s = opaque;
- return s->outport != kbd_outport_default(s);
-}
-
-static const VMStateDescription vmstate_kbd_outport = {
- .name = "pckbd_outport",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = kbd_outport_post_load,
- .needed = kbd_outport_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(outport, KBDState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int kbd_post_load(void *opaque, int version_id)
-{
- KBDState *s = opaque;
- if (!s->outport_present) {
- s->outport = kbd_outport_default(s);
- }
- s->outport_present = false;
- return 0;
-}
-
-static const VMStateDescription vmstate_kbd = {
- .name = "pckbd",
- .version_id = 3,
- .minimum_version_id = 3,
- .post_load = kbd_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(write_cmd, KBDState),
- VMSTATE_UINT8(status, KBDState),
- VMSTATE_UINT8(mode, KBDState),
- VMSTATE_UINT8(pending, KBDState),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_kbd_outport,
- NULL
- }
-};
-
-/* Memory mapped interface */
-static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
-{
- KBDState *s = opaque;
-
- if (addr & s->mask)
- return kbd_read_status(s, 0, 1) & 0xff;
- else
- return kbd_read_data(s, 0, 1) & 0xff;
-}
-
-static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
-{
- KBDState *s = opaque;
-
- if (addr & s->mask)
- kbd_write_command(s, 0, value & 0xff, 1);
- else
- kbd_write_data(s, 0, value & 0xff, 1);
-}
-
-static const MemoryRegionOps i8042_mmio_ops = {
- .endianness = DEVICE_NATIVE_ENDIAN,
- .old_mmio = {
- .read = { kbd_mm_readb, kbd_mm_readb, kbd_mm_readb },
- .write = { kbd_mm_writeb, kbd_mm_writeb, kbd_mm_writeb },
- },
-};
-
-void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
- MemoryRegion *region, ram_addr_t size,
- hwaddr mask)
-{
- KBDState *s = g_malloc0(sizeof(KBDState));
-
- s->irq_kbd = kbd_irq;
- s->irq_mouse = mouse_irq;
- s->mask = mask;
-
- vmstate_register(NULL, 0, &vmstate_kbd, s);
-
- memory_region_init_io(region, NULL, &i8042_mmio_ops, s, "i8042", size);
-
- s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
- s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
- qemu_register_reset(kbd_reset, s);
-}
-
-#define TYPE_I8042 "i8042"
-#define I8042(obj) OBJECT_CHECK(ISAKBDState, (obj), TYPE_I8042)
-
-typedef struct ISAKBDState {
- ISADevice parent_obj;
-
- KBDState kbd;
- MemoryRegion io[2];
-} ISAKBDState;
-
-void i8042_isa_mouse_fake_event(void *opaque)
-{
- ISADevice *dev = opaque;
- ISAKBDState *isa = I8042(dev);
- KBDState *s = &isa->kbd;
-
- ps2_mouse_fake_event(s->mouse);
-}
-
-void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out)
-{
- ISAKBDState *isa = I8042(dev);
- KBDState *s = &isa->kbd;
-
- s->a20_out = a20_out;
-}
-
-static const VMStateDescription vmstate_kbd_isa = {
- .name = "pckbd",
- .version_id = 3,
- .minimum_version_id = 3,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(kbd, ISAKBDState, 0, vmstate_kbd, KBDState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const MemoryRegionOps i8042_data_ops = {
- .read = kbd_read_data,
- .write = kbd_write_data,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static const MemoryRegionOps i8042_cmd_ops = {
- .read = kbd_read_status,
- .write = kbd_write_command,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 1,
- },
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void i8042_initfn(Object *obj)
-{
- ISAKBDState *isa_s = I8042(obj);
- KBDState *s = &isa_s->kbd;
-
- memory_region_init_io(isa_s->io + 0, obj, &i8042_data_ops, s,
- "i8042-data", 1);
- memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s,
- "i8042-cmd", 1);
-}
-
-static void i8042_realizefn(DeviceState *dev, Error **errp)
-{
- ISADevice *isadev = ISA_DEVICE(dev);
- ISAKBDState *isa_s = I8042(dev);
- KBDState *s = &isa_s->kbd;
-
- isa_init_irq(isadev, &s->irq_kbd, 1);
- isa_init_irq(isadev, &s->irq_mouse, 12);
-
- isa_register_ioport(isadev, isa_s->io + 0, 0x60);
- isa_register_ioport(isadev, isa_s->io + 1, 0x64);
-
- s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
- s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
- qemu_register_reset(kbd_reset, s);
-}
-
-static void i8042_class_initfn(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = i8042_realizefn;
- dc->vmsd = &vmstate_kbd_isa;
-}
-
-static const TypeInfo i8042_info = {
- .name = TYPE_I8042,
- .parent = TYPE_ISA_DEVICE,
- .instance_size = sizeof(ISAKBDState),
- .instance_init = i8042_initfn,
- .class_init = i8042_class_initfn,
-};
-
-static void i8042_register_types(void)
-{
- type_register_static(&i8042_info);
-}
-
-type_init(i8042_register_types)
diff --git a/qemu/hw/input/pl050.c b/qemu/hw/input/pl050.c
deleted file mode 100644
index 3092b0fe3..000000000
--- a/qemu/hw/input/pl050.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Arm PrimeCell PL050 Keyboard / Mouse Interface
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "hw/input/ps2.h"
-
-#define TYPE_PL050 "pl050"
-#define PL050(obj) OBJECT_CHECK(PL050State, (obj), TYPE_PL050)
-
-typedef struct PL050State {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- void *dev;
- uint32_t cr;
- uint32_t clk;
- uint32_t last;
- int pending;
- qemu_irq irq;
- bool is_mouse;
-} PL050State;
-
-static const VMStateDescription vmstate_pl050 = {
- .name = "pl050",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(cr, PL050State),
- VMSTATE_UINT32(clk, PL050State),
- VMSTATE_UINT32(last, PL050State),
- VMSTATE_INT32(pending, PL050State),
- VMSTATE_END_OF_LIST()
- }
-};
-
-#define PL050_TXEMPTY (1 << 6)
-#define PL050_TXBUSY (1 << 5)
-#define PL050_RXFULL (1 << 4)
-#define PL050_RXBUSY (1 << 3)
-#define PL050_RXPARITY (1 << 2)
-#define PL050_KMIC (1 << 1)
-#define PL050_KMID (1 << 0)
-
-static const unsigned char pl050_id[] =
-{ 0x50, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
-
-static void pl050_update(void *opaque, int level)
-{
- PL050State *s = (PL050State *)opaque;
- int raise;
-
- s->pending = level;
- raise = (s->pending && (s->cr & 0x10) != 0)
- || (s->cr & 0x08) != 0;
- qemu_set_irq(s->irq, raise);
-}
-
-static uint64_t pl050_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PL050State *s = (PL050State *)opaque;
- if (offset >= 0xfe0 && offset < 0x1000)
- return pl050_id[(offset - 0xfe0) >> 2];
-
- switch (offset >> 2) {
- case 0: /* KMICR */
- return s->cr;
- case 1: /* KMISTAT */
- {
- uint8_t val;
- uint32_t stat;
-
- val = s->last;
- val = val ^ (val >> 4);
- val = val ^ (val >> 2);
- val = (val ^ (val >> 1)) & 1;
-
- stat = PL050_TXEMPTY;
- if (val)
- stat |= PL050_RXPARITY;
- if (s->pending)
- stat |= PL050_RXFULL;
-
- return stat;
- }
- case 2: /* KMIDATA */
- if (s->pending)
- s->last = ps2_read_data(s->dev);
- return s->last;
- case 3: /* KMICLKDIV */
- return s->clk;
- case 4: /* KMIIR */
- return s->pending | 2;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "pl050_read: Bad offset %x\n", (int)offset);
- return 0;
- }
-}
-
-static void pl050_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PL050State *s = (PL050State *)opaque;
- switch (offset >> 2) {
- case 0: /* KMICR */
- s->cr = value;
- pl050_update(s, s->pending);
- /* ??? Need to implement the enable/disable bit. */
- break;
- case 2: /* KMIDATA */
- /* ??? This should toggle the TX interrupt line. */
- /* ??? This means kbd/mouse can block each other. */
- if (s->is_mouse) {
- ps2_write_mouse(s->dev, value);
- } else {
- ps2_write_keyboard(s->dev, value);
- }
- break;
- case 3: /* KMICLKDIV */
- s->clk = value;
- return;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "pl050_write: Bad offset %x\n", (int)offset);
- }
-}
-static const MemoryRegionOps pl050_ops = {
- .read = pl050_read,
- .write = pl050_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int pl050_initfn(SysBusDevice *dev)
-{
- PL050State *s = PL050(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
- sysbus_init_irq(dev, &s->irq);
- if (s->is_mouse) {
- s->dev = ps2_mouse_init(pl050_update, s);
- } else {
- s->dev = ps2_kbd_init(pl050_update, s);
- }
- return 0;
-}
-
-static void pl050_keyboard_init(Object *obj)
-{
- PL050State *s = PL050(obj);
-
- s->is_mouse = false;
-}
-
-static void pl050_mouse_init(Object *obj)
-{
- PL050State *s = PL050(obj);
-
- s->is_mouse = true;
-}
-
-static const TypeInfo pl050_kbd_info = {
- .name = "pl050_keyboard",
- .parent = TYPE_PL050,
- .instance_init = pl050_keyboard_init,
-};
-
-static const TypeInfo pl050_mouse_info = {
- .name = "pl050_mouse",
- .parent = TYPE_PL050,
- .instance_init = pl050_mouse_init,
-};
-
-static void pl050_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc);
-
- sdc->init = pl050_initfn;
- dc->vmsd = &vmstate_pl050;
-}
-
-static const TypeInfo pl050_type_info = {
- .name = TYPE_PL050,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PL050State),
- .abstract = true,
- .class_init = pl050_class_init,
-};
-
-static void pl050_register_types(void)
-{
- type_register_static(&pl050_type_info);
- type_register_static(&pl050_kbd_info);
- type_register_static(&pl050_mouse_info);
-}
-
-type_init(pl050_register_types)
diff --git a/qemu/hw/input/ps2.c b/qemu/hw/input/ps2.c
deleted file mode 100644
index a8aa36f5c..000000000
--- a/qemu/hw/input/ps2.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * QEMU PS/2 keyboard/mouse emulation
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/input/ps2.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "sysemu/sysemu.h"
-
-#include "trace.h"
-
-/* debug PC keyboard */
-//#define DEBUG_KBD
-
-/* debug PC keyboard : only mouse */
-//#define DEBUG_MOUSE
-
-/* Keyboard Commands */
-#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
-#define KBD_CMD_ECHO 0xEE
-#define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
-#define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
-#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
-#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
-#define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
-#define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
-#define KBD_CMD_RESET 0xFF /* Reset */
-
-/* Keyboard Replies */
-#define KBD_REPLY_POR 0xAA /* Power on reset */
-#define KBD_REPLY_ID 0xAB /* Keyboard ID */
-#define KBD_REPLY_ACK 0xFA /* Command ACK */
-#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
-
-/* Mouse Commands */
-#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
-#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
-#define AUX_SET_RES 0xE8 /* Set resolution */
-#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
-#define AUX_SET_STREAM 0xEA /* Set stream mode */
-#define AUX_POLL 0xEB /* Poll */
-#define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
-#define AUX_SET_WRAP 0xEE /* Set wrap mode */
-#define AUX_SET_REMOTE 0xF0 /* Set remote mode */
-#define AUX_GET_TYPE 0xF2 /* Get type */
-#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
-#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
-#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
-#define AUX_SET_DEFAULT 0xF6
-#define AUX_RESET 0xFF /* Reset aux device */
-#define AUX_ACK 0xFA /* Command byte ACK. */
-
-#define MOUSE_STATUS_REMOTE 0x40
-#define MOUSE_STATUS_ENABLED 0x20
-#define MOUSE_STATUS_SCALE21 0x10
-
-#define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
-
-typedef struct {
- /* Keep the data array 256 bytes long, which compatibility
- with older qemu versions. */
- uint8_t data[256];
- int rptr, wptr, count;
-} PS2Queue;
-
-typedef struct {
- PS2Queue queue;
- int32_t write_cmd;
- void (*update_irq)(void *, int);
- void *update_arg;
-} PS2State;
-
-typedef struct {
- PS2State common;
- int scan_enabled;
- /* QEMU uses translated PC scancodes internally. To avoid multiple
- conversions we do the translation (if any) in the PS/2 emulation
- not the keyboard controller. */
- int translate;
- int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
- int ledstate;
-} PS2KbdState;
-
-typedef struct {
- PS2State common;
- uint8_t mouse_status;
- uint8_t mouse_resolution;
- uint8_t mouse_sample_rate;
- uint8_t mouse_wrap;
- uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
- uint8_t mouse_detect_state;
- int mouse_dx; /* current values, needed for 'poll' mode */
- int mouse_dy;
- int mouse_dz;
- uint8_t mouse_buttons;
-} PS2MouseState;
-
-/* Table to convert from PC scancodes to raw scancodes. */
-static const unsigned char ps2_raw_keycode[128] = {
- 0, 118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89, 124, 17, 41, 88, 5, 6, 4, 12, 3,
- 11, 2, 10, 1, 9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105,
-114, 122, 112, 113, 127, 96, 97, 120, 7, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
-};
-static const unsigned char ps2_raw_keycode_set3[128] = {
- 0, 8, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89, 126, 25, 41, 20, 7, 15, 23, 31, 39,
- 47, 2, 63, 71, 79, 118, 95, 108, 117, 125, 132, 107, 115, 116, 124, 105,
-114, 122, 112, 113, 127, 96, 97, 86, 94, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
-};
-
-void ps2_queue(void *opaque, int b)
-{
- PS2State *s = (PS2State *)opaque;
- PS2Queue *q = &s->queue;
-
- if (q->count >= PS2_QUEUE_SIZE - 1)
- return;
- q->data[q->wptr] = b;
- if (++q->wptr == PS2_QUEUE_SIZE)
- q->wptr = 0;
- q->count++;
- s->update_irq(s->update_arg, 1);
-}
-
-/*
- keycode is expressed as follow:
- bit 7 - 0 key pressed, 1 = key released
- bits 6-0 - translated scancode set 2
- */
-static void ps2_put_keycode(void *opaque, int keycode)
-{
- PS2KbdState *s = opaque;
-
- trace_ps2_put_keycode(opaque, keycode);
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
- /* XXX: add support for scancode set 1 */
- if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
- if (keycode & 0x80) {
- ps2_queue(&s->common, 0xf0);
- }
- if (s->scancode_set == 2) {
- keycode = ps2_raw_keycode[keycode & 0x7f];
- } else if (s->scancode_set == 3) {
- keycode = ps2_raw_keycode_set3[keycode & 0x7f];
- }
- }
- ps2_queue(&s->common, keycode);
-}
-
-static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- PS2KbdState *s = (PS2KbdState *)dev;
- int scancodes[3], i, count;
- InputKeyEvent *key = evt->u.key.data;
-
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
- count = qemu_input_key_value_to_scancode(key->key,
- key->down,
- scancodes);
- for (i = 0; i < count; i++) {
- ps2_put_keycode(s, scancodes[i]);
- }
-}
-
-uint32_t ps2_read_data(void *opaque)
-{
- PS2State *s = (PS2State *)opaque;
- PS2Queue *q;
- int val, index;
-
- trace_ps2_read_data(opaque);
- q = &s->queue;
- if (q->count == 0) {
- /* NOTE: if no data left, we return the last keyboard one
- (needed for EMM386) */
- /* XXX: need a timer to do things correctly */
- index = q->rptr - 1;
- if (index < 0)
- index = PS2_QUEUE_SIZE - 1;
- val = q->data[index];
- } else {
- val = q->data[q->rptr];
- if (++q->rptr == PS2_QUEUE_SIZE)
- q->rptr = 0;
- q->count--;
- /* reading deasserts IRQ */
- s->update_irq(s->update_arg, 0);
- /* reassert IRQs if data left */
- s->update_irq(s->update_arg, q->count != 0);
- }
- return val;
-}
-
-static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
-{
- trace_ps2_set_ledstate(s, ledstate);
- s->ledstate = ledstate;
- kbd_put_ledstate(ledstate);
-}
-
-static void ps2_reset_keyboard(PS2KbdState *s)
-{
- trace_ps2_reset_keyboard(s);
- s->scan_enabled = 1;
- s->scancode_set = 2;
- ps2_set_ledstate(s, 0);
-}
-
-void ps2_write_keyboard(void *opaque, int val)
-{
- PS2KbdState *s = (PS2KbdState *)opaque;
-
- trace_ps2_write_keyboard(opaque, val);
- switch(s->common.write_cmd) {
- default:
- case -1:
- switch(val) {
- case 0x00:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case 0x05:
- ps2_queue(&s->common, KBD_REPLY_RESEND);
- break;
- case KBD_CMD_GET_ID:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- /* We emulate a MF2 AT keyboard here */
- ps2_queue(&s->common, KBD_REPLY_ID);
- if (s->translate)
- ps2_queue(&s->common, 0x41);
- else
- ps2_queue(&s->common, 0x83);
- break;
- case KBD_CMD_ECHO:
- ps2_queue(&s->common, KBD_CMD_ECHO);
- break;
- case KBD_CMD_ENABLE:
- s->scan_enabled = 1;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_SCANCODE:
- case KBD_CMD_SET_LEDS:
- case KBD_CMD_SET_RATE:
- s->common.write_cmd = val;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_RESET_DISABLE:
- ps2_reset_keyboard(s);
- s->scan_enabled = 0;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_RESET_ENABLE:
- ps2_reset_keyboard(s);
- s->scan_enabled = 1;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- case KBD_CMD_RESET:
- ps2_reset_keyboard(s);
- ps2_queue(&s->common, KBD_REPLY_ACK);
- ps2_queue(&s->common, KBD_REPLY_POR);
- break;
- default:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- break;
- }
- break;
- case KBD_CMD_SCANCODE:
- if (val == 0) {
- if (s->scancode_set == 1)
- ps2_put_keycode(s, 0x43);
- else if (s->scancode_set == 2)
- ps2_put_keycode(s, 0x41);
- else if (s->scancode_set == 3)
- ps2_put_keycode(s, 0x3f);
- } else {
- if (val >= 1 && val <= 3)
- s->scancode_set = val;
- ps2_queue(&s->common, KBD_REPLY_ACK);
- }
- s->common.write_cmd = -1;
- break;
- case KBD_CMD_SET_LEDS:
- ps2_set_ledstate(s, val);
- ps2_queue(&s->common, KBD_REPLY_ACK);
- s->common.write_cmd = -1;
- break;
- case KBD_CMD_SET_RATE:
- ps2_queue(&s->common, KBD_REPLY_ACK);
- s->common.write_cmd = -1;
- break;
- }
-}
-
-/* Set the scancode translation mode.
- 0 = raw scancodes.
- 1 = translated scancodes (used by qemu internally). */
-
-void ps2_keyboard_set_translation(void *opaque, int mode)
-{
- PS2KbdState *s = (PS2KbdState *)opaque;
- trace_ps2_keyboard_set_translation(opaque, mode);
- s->translate = mode;
-}
-
-static void ps2_mouse_send_packet(PS2MouseState *s)
-{
- unsigned int b;
- int dx1, dy1, dz1;
-
- dx1 = s->mouse_dx;
- dy1 = s->mouse_dy;
- dz1 = s->mouse_dz;
- /* XXX: increase range to 8 bits ? */
- if (dx1 > 127)
- dx1 = 127;
- else if (dx1 < -127)
- dx1 = -127;
- if (dy1 > 127)
- dy1 = 127;
- else if (dy1 < -127)
- dy1 = -127;
- b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
- ps2_queue(&s->common, b);
- ps2_queue(&s->common, dx1 & 0xff);
- ps2_queue(&s->common, dy1 & 0xff);
- /* extra byte for IMPS/2 or IMEX */
- switch(s->mouse_type) {
- default:
- break;
- case 3:
- if (dz1 > 127)
- dz1 = 127;
- else if (dz1 < -127)
- dz1 = -127;
- ps2_queue(&s->common, dz1 & 0xff);
- break;
- case 4:
- if (dz1 > 7)
- dz1 = 7;
- else if (dz1 < -7)
- dz1 = -7;
- b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
- ps2_queue(&s->common, b);
- break;
- }
-
- trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
- /* update deltas */
- s->mouse_dx -= dx1;
- s->mouse_dy -= dy1;
- s->mouse_dz -= dz1;
-}
-
-static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- static const int bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
- [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
- [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
- };
- PS2MouseState *s = (PS2MouseState *)dev;
- InputMoveEvent *move;
- InputBtnEvent *btn;
-
- /* check if deltas are recorded when disabled */
- if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
- return;
-
- switch (evt->type) {
- case INPUT_EVENT_KIND_REL:
- move = evt->u.rel.data;
- if (move->axis == INPUT_AXIS_X) {
- s->mouse_dx += move->value;
- } else if (move->axis == INPUT_AXIS_Y) {
- s->mouse_dy -= move->value;
- }
- break;
-
- case INPUT_EVENT_KIND_BTN:
- btn = evt->u.btn.data;
- if (btn->down) {
- s->mouse_buttons |= bmap[btn->button];
- if (btn->button == INPUT_BUTTON_WHEEL_UP) {
- s->mouse_dz--;
- } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
- s->mouse_dz++;
- }
- } else {
- s->mouse_buttons &= ~bmap[btn->button];
- }
- break;
-
- default:
- /* keep gcc happy */
- break;
- }
-}
-
-static void ps2_mouse_sync(DeviceState *dev)
-{
- PS2MouseState *s = (PS2MouseState *)dev;
-
- if (s->mouse_buttons) {
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
- }
- if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
- while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
- /* if not remote, send event. Multiple events are sent if
- too big deltas */
- ps2_mouse_send_packet(s);
- if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
- break;
- }
- }
-}
-
-void ps2_mouse_fake_event(void *opaque)
-{
- PS2MouseState *s = opaque;
- trace_ps2_mouse_fake_event(opaque);
- s->mouse_dx++;
- ps2_mouse_sync(opaque);
-}
-
-void ps2_write_mouse(void *opaque, int val)
-{
- PS2MouseState *s = (PS2MouseState *)opaque;
-
- trace_ps2_write_mouse(opaque, val);
-#ifdef DEBUG_MOUSE
- printf("kbd: write mouse 0x%02x\n", val);
-#endif
- switch(s->common.write_cmd) {
- default:
- case -1:
- /* mouse command */
- if (s->mouse_wrap) {
- if (val == AUX_RESET_WRAP) {
- s->mouse_wrap = 0;
- ps2_queue(&s->common, AUX_ACK);
- return;
- } else if (val != AUX_RESET) {
- ps2_queue(&s->common, val);
- return;
- }
- }
- switch(val) {
- case AUX_SET_SCALE11:
- s->mouse_status &= ~MOUSE_STATUS_SCALE21;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_SCALE21:
- s->mouse_status |= MOUSE_STATUS_SCALE21;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_STREAM:
- s->mouse_status &= ~MOUSE_STATUS_REMOTE;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_WRAP:
- s->mouse_wrap = 1;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_REMOTE:
- s->mouse_status |= MOUSE_STATUS_REMOTE;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_GET_TYPE:
- ps2_queue(&s->common, AUX_ACK);
- ps2_queue(&s->common, s->mouse_type);
- break;
- case AUX_SET_RES:
- case AUX_SET_SAMPLE:
- s->common.write_cmd = val;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_GET_SCALE:
- ps2_queue(&s->common, AUX_ACK);
- ps2_queue(&s->common, s->mouse_status);
- ps2_queue(&s->common, s->mouse_resolution);
- ps2_queue(&s->common, s->mouse_sample_rate);
- break;
- case AUX_POLL:
- ps2_queue(&s->common, AUX_ACK);
- ps2_mouse_send_packet(s);
- break;
- case AUX_ENABLE_DEV:
- s->mouse_status |= MOUSE_STATUS_ENABLED;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_DISABLE_DEV:
- s->mouse_status &= ~MOUSE_STATUS_ENABLED;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_SET_DEFAULT:
- s->mouse_sample_rate = 100;
- s->mouse_resolution = 2;
- s->mouse_status = 0;
- ps2_queue(&s->common, AUX_ACK);
- break;
- case AUX_RESET:
- s->mouse_sample_rate = 100;
- s->mouse_resolution = 2;
- s->mouse_status = 0;
- s->mouse_type = 0;
- ps2_queue(&s->common, AUX_ACK);
- ps2_queue(&s->common, 0xaa);
- ps2_queue(&s->common, s->mouse_type);
- break;
- default:
- break;
- }
- break;
- case AUX_SET_SAMPLE:
- s->mouse_sample_rate = val;
- /* detect IMPS/2 or IMEX */
- switch(s->mouse_detect_state) {
- default:
- case 0:
- if (val == 200)
- s->mouse_detect_state = 1;
- break;
- case 1:
- if (val == 100)
- s->mouse_detect_state = 2;
- else if (val == 200)
- s->mouse_detect_state = 3;
- else
- s->mouse_detect_state = 0;
- break;
- case 2:
- if (val == 80)
- s->mouse_type = 3; /* IMPS/2 */
- s->mouse_detect_state = 0;
- break;
- case 3:
- if (val == 80)
- s->mouse_type = 4; /* IMEX */
- s->mouse_detect_state = 0;
- break;
- }
- ps2_queue(&s->common, AUX_ACK);
- s->common.write_cmd = -1;
- break;
- case AUX_SET_RES:
- s->mouse_resolution = val;
- ps2_queue(&s->common, AUX_ACK);
- s->common.write_cmd = -1;
- break;
- }
-}
-
-static void ps2_common_reset(PS2State *s)
-{
- PS2Queue *q;
- s->write_cmd = -1;
- q = &s->queue;
- q->rptr = 0;
- q->wptr = 0;
- q->count = 0;
- s->update_irq(s->update_arg, 0);
-}
-
-static void ps2_common_post_load(PS2State *s)
-{
- PS2Queue *q = &s->queue;
- int size;
- int i;
- int tmp_data[PS2_QUEUE_SIZE];
-
- /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
- size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
-
- /* move the queue elements to the start of data array */
- if (size > 0) {
- for (i = 0; i < size; i++) {
- /* move the queue elements to the temporary buffer */
- tmp_data[i] = q->data[q->rptr];
- if (++q->rptr == 256) {
- q->rptr = 0;
- }
- }
- memcpy(q->data, tmp_data, size);
- }
- /* reset rptr/wptr/count */
- q->rptr = 0;
- q->wptr = size;
- q->count = size;
- s->update_irq(s->update_arg, q->count != 0);
-}
-
-static void ps2_kbd_reset(void *opaque)
-{
- PS2KbdState *s = (PS2KbdState *) opaque;
-
- trace_ps2_kbd_reset(opaque);
- ps2_common_reset(&s->common);
- s->scan_enabled = 0;
- s->translate = 0;
- s->scancode_set = 2;
-}
-
-static void ps2_mouse_reset(void *opaque)
-{
- PS2MouseState *s = (PS2MouseState *) opaque;
-
- trace_ps2_mouse_reset(opaque);
- ps2_common_reset(&s->common);
- s->mouse_status = 0;
- s->mouse_resolution = 0;
- s->mouse_sample_rate = 0;
- s->mouse_wrap = 0;
- s->mouse_type = 0;
- s->mouse_detect_state = 0;
- s->mouse_dx = 0;
- s->mouse_dy = 0;
- s->mouse_dz = 0;
- s->mouse_buttons = 0;
-}
-
-static const VMStateDescription vmstate_ps2_common = {
- .name = "PS2 Common State",
- .version_id = 3,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(write_cmd, PS2State),
- VMSTATE_INT32(queue.rptr, PS2State),
- VMSTATE_INT32(queue.wptr, PS2State),
- VMSTATE_INT32(queue.count, PS2State),
- VMSTATE_BUFFER(queue.data, PS2State),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static bool ps2_keyboard_ledstate_needed(void *opaque)
-{
- PS2KbdState *s = opaque;
-
- return s->ledstate != 0; /* 0 is default state */
-}
-
-static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
-{
- PS2KbdState *s = opaque;
-
- kbd_put_ledstate(s->ledstate);
- return 0;
-}
-
-static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
- .name = "ps2kbd/ledstate",
- .version_id = 3,
- .minimum_version_id = 2,
- .post_load = ps2_kbd_ledstate_post_load,
- .needed = ps2_keyboard_ledstate_needed,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(ledstate, PS2KbdState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int ps2_kbd_post_load(void* opaque, int version_id)
-{
- PS2KbdState *s = (PS2KbdState*)opaque;
- PS2State *ps2 = &s->common;
-
- if (version_id == 2)
- s->scancode_set=2;
-
- ps2_common_post_load(ps2);
-
- return 0;
-}
-
-static void ps2_kbd_pre_save(void *opaque)
-{
- PS2KbdState *s = (PS2KbdState *)opaque;
- PS2State *ps2 = &s->common;
-
- ps2_common_post_load(ps2);
-}
-
-static const VMStateDescription vmstate_ps2_keyboard = {
- .name = "ps2kbd",
- .version_id = 3,
- .minimum_version_id = 2,
- .post_load = ps2_kbd_post_load,
- .pre_save = ps2_kbd_pre_save,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
- VMSTATE_INT32(scan_enabled, PS2KbdState),
- VMSTATE_INT32(translate, PS2KbdState),
- VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_ps2_keyboard_ledstate,
- NULL
- }
-};
-
-static int ps2_mouse_post_load(void *opaque, int version_id)
-{
- PS2MouseState *s = (PS2MouseState *)opaque;
- PS2State *ps2 = &s->common;
-
- ps2_common_post_load(ps2);
-
- return 0;
-}
-
-static void ps2_mouse_pre_save(void *opaque)
-{
- PS2MouseState *s = (PS2MouseState *)opaque;
- PS2State *ps2 = &s->common;
-
- ps2_common_post_load(ps2);
-}
-
-static const VMStateDescription vmstate_ps2_mouse = {
- .name = "ps2mouse",
- .version_id = 2,
- .minimum_version_id = 2,
- .post_load = ps2_mouse_post_load,
- .pre_save = ps2_mouse_pre_save,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
- VMSTATE_UINT8(mouse_status, PS2MouseState),
- VMSTATE_UINT8(mouse_resolution, PS2MouseState),
- VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
- VMSTATE_UINT8(mouse_wrap, PS2MouseState),
- VMSTATE_UINT8(mouse_type, PS2MouseState),
- VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
- VMSTATE_INT32(mouse_dx, PS2MouseState),
- VMSTATE_INT32(mouse_dy, PS2MouseState),
- VMSTATE_INT32(mouse_dz, PS2MouseState),
- VMSTATE_UINT8(mouse_buttons, PS2MouseState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static QemuInputHandler ps2_keyboard_handler = {
- .name = "QEMU PS/2 Keyboard",
- .mask = INPUT_EVENT_MASK_KEY,
- .event = ps2_keyboard_event,
-};
-
-void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
-{
- PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
-
- trace_ps2_kbd_init(s);
- s->common.update_irq = update_irq;
- s->common.update_arg = update_arg;
- s->scancode_set = 2;
- vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
- qemu_input_handler_register((DeviceState *)s,
- &ps2_keyboard_handler);
- qemu_register_reset(ps2_kbd_reset, s);
- return s;
-}
-
-static QemuInputHandler ps2_mouse_handler = {
- .name = "QEMU PS/2 Mouse",
- .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
- .event = ps2_mouse_event,
- .sync = ps2_mouse_sync,
-};
-
-void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
-{
- PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
-
- trace_ps2_mouse_init(s);
- s->common.update_irq = update_irq;
- s->common.update_arg = update_arg;
- vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
- qemu_input_handler_register((DeviceState *)s,
- &ps2_mouse_handler);
- qemu_register_reset(ps2_mouse_reset, s);
- return s;
-}
diff --git a/qemu/hw/input/pxa2xx_keypad.c b/qemu/hw/input/pxa2xx_keypad.c
deleted file mode 100644
index 2b70bbb95..000000000
--- a/qemu/hw/input/pxa2xx_keypad.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Intel PXA27X Keypad Controller emulation.
- *
- * Copyright (c) 2007 MontaVista Software, Inc
- * Written by Armin Kuster <akuster@kama-aina.net>
- * or <Akuster@mvista.com>
- *
- * This code is licensed under the GPLv2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "ui/console.h"
-
-/*
- * Keypad
- */
-#define KPC 0x00 /* Keypad Interface Control register */
-#define KPDK 0x08 /* Keypad Interface Direct Key register */
-#define KPREC 0x10 /* Keypad Interface Rotary Encoder register */
-#define KPMK 0x18 /* Keypad Interface Matrix Key register */
-#define KPAS 0x20 /* Keypad Interface Automatic Scan register */
-#define KPASMKP0 0x28 /* Keypad Interface Automatic Scan Multiple
- Key Presser register 0 */
-#define KPASMKP1 0x30 /* Keypad Interface Automatic Scan Multiple
- Key Presser register 1 */
-#define KPASMKP2 0x38 /* Keypad Interface Automatic Scan Multiple
- Key Presser register 2 */
-#define KPASMKP3 0x40 /* Keypad Interface Automatic Scan Multiple
- Key Presser register 3 */
-#define KPKDI 0x48 /* Keypad Interface Key Debounce Interval
- register */
-
-/* Keypad defines */
-#define KPC_AS (0x1 << 30) /* Automatic Scan bit */
-#define KPC_ASACT (0x1 << 29) /* Automatic Scan on Activity */
-#define KPC_MI (0x1 << 22) /* Matrix interrupt bit */
-#define KPC_IMKP (0x1 << 21) /* Ignore Multiple Key Press */
-#define KPC_MS7 (0x1 << 20) /* Matrix scan line 7 */
-#define KPC_MS6 (0x1 << 19) /* Matrix scan line 6 */
-#define KPC_MS5 (0x1 << 18) /* Matrix scan line 5 */
-#define KPC_MS4 (0x1 << 17) /* Matrix scan line 4 */
-#define KPC_MS3 (0x1 << 16) /* Matrix scan line 3 */
-#define KPC_MS2 (0x1 << 15) /* Matrix scan line 2 */
-#define KPC_MS1 (0x1 << 14) /* Matrix scan line 1 */
-#define KPC_MS0 (0x1 << 13) /* Matrix scan line 0 */
-#define KPC_ME (0x1 << 12) /* Matrix Keypad Enable */
-#define KPC_MIE (0x1 << 11) /* Matrix Interrupt Enable */
-#define KPC_DK_DEB_SEL (0x1 << 9) /* Direct Keypad Debounce Select */
-#define KPC_DI (0x1 << 5) /* Direct key interrupt bit */
-#define KPC_RE_ZERO_DEB (0x1 << 4) /* Rotary Encoder Zero Debounce */
-#define KPC_REE1 (0x1 << 3) /* Rotary Encoder1 Enable */
-#define KPC_REE0 (0x1 << 2) /* Rotary Encoder0 Enable */
-#define KPC_DE (0x1 << 1) /* Direct Keypad Enable */
-#define KPC_DIE (0x1 << 0) /* Direct Keypad interrupt Enable */
-
-#define KPDK_DKP (0x1 << 31)
-#define KPDK_DK7 (0x1 << 7)
-#define KPDK_DK6 (0x1 << 6)
-#define KPDK_DK5 (0x1 << 5)
-#define KPDK_DK4 (0x1 << 4)
-#define KPDK_DK3 (0x1 << 3)
-#define KPDK_DK2 (0x1 << 2)
-#define KPDK_DK1 (0x1 << 1)
-#define KPDK_DK0 (0x1 << 0)
-
-#define KPREC_OF1 (0x1 << 31)
-#define KPREC_UF1 (0x1 << 30)
-#define KPREC_OF0 (0x1 << 15)
-#define KPREC_UF0 (0x1 << 14)
-
-#define KPMK_MKP (0x1 << 31)
-#define KPAS_SO (0x1 << 31)
-#define KPASMKPx_SO (0x1 << 31)
-
-
-#define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2)))
-
-#define PXAKBD_MAXROW 8
-#define PXAKBD_MAXCOL 8
-
-struct PXA2xxKeyPadState {
- MemoryRegion iomem;
- qemu_irq irq;
- const struct keymap *map;
- int pressed_cnt;
- int alt_code;
-
- uint32_t kpc;
- uint32_t kpdk;
- uint32_t kprec;
- uint32_t kpmk;
- uint32_t kpas;
- uint32_t kpasmkp[4];
- uint32_t kpkdi;
-};
-
-static void pxa27x_keypad_find_pressed_key(PXA2xxKeyPadState *kp, int *row, int *col)
-{
- int i;
- for (i = 0; i < 4; i++)
- {
- *col = i * 2;
- for (*row = 0; *row < 8; (*row)++) {
- if (kp->kpasmkp[i] & (1 << *row))
- return;
- }
- *col = i * 2 + 1;
- for (*row = 0; *row < 8; (*row)++) {
- if (kp->kpasmkp[i] & (1 << (*row + 16)))
- return;
- }
- }
-}
-
-static void pxa27x_keyboard_event (PXA2xxKeyPadState *kp, int keycode)
-{
- int row, col, rel, assert_irq = 0;
- uint32_t val;
-
- if (keycode == 0xe0) {
- kp->alt_code = 1;
- return;
- }
-
- if(!(kp->kpc & KPC_ME)) /* skip if not enabled */
- return;
-
- rel = (keycode & 0x80) ? 1 : 0; /* key release from qemu */
- keycode &= ~0x80; /* strip qemu key release bit */
- if (kp->alt_code) {
- keycode |= 0x80;
- kp->alt_code = 0;
- }
-
- row = kp->map[keycode].row;
- col = kp->map[keycode].column;
- if (row == -1 || col == -1) {
- return;
- }
-
- val = KPASMKPx_MKC(row, col);
- if (rel) {
- if (kp->kpasmkp[col / 2] & val) {
- kp->kpasmkp[col / 2] &= ~val;
- kp->pressed_cnt--;
- assert_irq = 1;
- }
- } else {
- if (!(kp->kpasmkp[col / 2] & val)) {
- kp->kpasmkp[col / 2] |= val;
- kp->pressed_cnt++;
- assert_irq = 1;
- }
- }
- kp->kpas = ((kp->pressed_cnt & 0x1f) << 26) | (0xf << 4) | 0xf;
- if (kp->pressed_cnt == 1) {
- kp->kpas &= ~((0xf << 4) | 0xf);
- if (rel) {
- pxa27x_keypad_find_pressed_key(kp, &row, &col);
- }
- kp->kpas |= ((row & 0xf) << 4) | (col & 0xf);
- }
-
- if (!(kp->kpc & (KPC_AS | KPC_ASACT)))
- assert_irq = 0;
-
- if (assert_irq && (kp->kpc & KPC_MIE)) {
- kp->kpc |= KPC_MI;
- qemu_irq_raise(kp->irq);
- }
-}
-
-static uint64_t pxa2xx_keypad_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
- uint32_t tmp;
-
- switch (offset) {
- case KPC:
- tmp = s->kpc;
- if(tmp & KPC_MI)
- s->kpc &= ~(KPC_MI);
- if(tmp & KPC_DI)
- s->kpc &= ~(KPC_DI);
- qemu_irq_lower(s->irq);
- return tmp;
- break;
- case KPDK:
- return s->kpdk;
- break;
- case KPREC:
- tmp = s->kprec;
- if(tmp & KPREC_OF1)
- s->kprec &= ~(KPREC_OF1);
- if(tmp & KPREC_UF1)
- s->kprec &= ~(KPREC_UF1);
- if(tmp & KPREC_OF0)
- s->kprec &= ~(KPREC_OF0);
- if(tmp & KPREC_UF0)
- s->kprec &= ~(KPREC_UF0);
- return tmp;
- break;
- case KPMK:
- tmp = s->kpmk;
- if(tmp & KPMK_MKP)
- s->kpmk &= ~(KPMK_MKP);
- return tmp;
- break;
- case KPAS:
- return s->kpas;
- break;
- case KPASMKP0:
- return s->kpasmkp[0];
- break;
- case KPASMKP1:
- return s->kpasmkp[1];
- break;
- case KPASMKP2:
- return s->kpasmkp[2];
- break;
- case KPASMKP3:
- return s->kpasmkp[3];
- break;
- case KPKDI:
- return s->kpkdi;
- break;
- default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
- }
-
- return 0;
-}
-
-static void pxa2xx_keypad_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PXA2xxKeyPadState *s = (PXA2xxKeyPadState *) opaque;
-
- switch (offset) {
- case KPC:
- s->kpc = value;
- if (s->kpc & KPC_AS) {
- s->kpc &= ~(KPC_AS);
- }
- break;
- case KPDK:
- s->kpdk = value;
- break;
- case KPREC:
- s->kprec = value;
- break;
- case KPMK:
- s->kpmk = value;
- break;
- case KPAS:
- s->kpas = value;
- break;
- case KPASMKP0:
- s->kpasmkp[0] = value;
- break;
- case KPASMKP1:
- s->kpasmkp[1] = value;
- break;
- case KPASMKP2:
- s->kpasmkp[2] = value;
- break;
- case KPASMKP3:
- s->kpasmkp[3] = value;
- break;
- case KPKDI:
- s->kpkdi = value;
- break;
-
- default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
- }
-}
-
-static const MemoryRegionOps pxa2xx_keypad_ops = {
- .read = pxa2xx_keypad_read,
- .write = pxa2xx_keypad_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_pxa2xx_keypad = {
- .name = "pxa2xx_keypad",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(kpc, PXA2xxKeyPadState),
- VMSTATE_UINT32(kpdk, PXA2xxKeyPadState),
- VMSTATE_UINT32(kprec, PXA2xxKeyPadState),
- VMSTATE_UINT32(kpmk, PXA2xxKeyPadState),
- VMSTATE_UINT32(kpas, PXA2xxKeyPadState),
- VMSTATE_UINT32_ARRAY(kpasmkp, PXA2xxKeyPadState, 4),
- VMSTATE_UINT32(kpkdi, PXA2xxKeyPadState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
- hwaddr base,
- qemu_irq irq)
-{
- PXA2xxKeyPadState *s;
-
- s = (PXA2xxKeyPadState *) g_malloc0(sizeof(PXA2xxKeyPadState));
- s->irq = irq;
-
- memory_region_init_io(&s->iomem, NULL, &pxa2xx_keypad_ops, s,
- "pxa2xx-keypad", 0x00100000);
- memory_region_add_subregion(sysmem, base, &s->iomem);
-
- vmstate_register(NULL, 0, &vmstate_pxa2xx_keypad, s);
-
- return s;
-}
-
-void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
- const struct keymap *map, int size)
-{
- if(!map || size < 0x80) {
- fprintf(stderr, "%s - No PXA keypad map defined\n", __FUNCTION__);
- exit(-1);
- }
-
- kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
-}
diff --git a/qemu/hw/input/stellaris_input.c b/qemu/hw/input/stellaris_input.c
deleted file mode 100644
index 99168bfee..000000000
--- a/qemu/hw/input/stellaris_input.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Gamepad style buttons connected to IRQ/GPIO lines
- *
- * Copyright (c) 2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/devices.h"
-#include "ui/console.h"
-
-typedef struct {
- qemu_irq irq;
- int keycode;
- uint8_t pressed;
-} gamepad_button;
-
-typedef struct {
- gamepad_button *buttons;
- int num_buttons;
- int extension;
-} gamepad_state;
-
-static void stellaris_gamepad_put_key(void * opaque, int keycode)
-{
- gamepad_state *s = (gamepad_state *)opaque;
- int i;
- int down;
-
- if (keycode == 0xe0 && !s->extension) {
- s->extension = 0x80;
- return;
- }
-
- down = (keycode & 0x80) == 0;
- keycode = (keycode & 0x7f) | s->extension;
-
- for (i = 0; i < s->num_buttons; i++) {
- if (s->buttons[i].keycode == keycode
- && s->buttons[i].pressed != down) {
- s->buttons[i].pressed = down;
- qemu_set_irq(s->buttons[i].irq, down);
- }
- }
-
- s->extension = 0;
-}
-
-static const VMStateDescription vmstate_stellaris_button = {
- .name = "stellaris_button",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(pressed, gamepad_button),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_stellaris_gamepad = {
- .name = "stellaris_gamepad",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(extension, gamepad_state),
- VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
- vmstate_stellaris_button, gamepad_button),
- VMSTATE_END_OF_LIST()
- }
-};
-
-/* Returns an array of 5 output slots. */
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
-{
- gamepad_state *s;
- int i;
-
- s = g_new0(gamepad_state, 1);
- s->buttons = g_new0(gamepad_button, n);
- for (i = 0; i < n; i++) {
- s->buttons[i].irq = irq[i];
- s->buttons[i].keycode = keycode[i];
- }
- s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
- vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s);
-}
diff --git a/qemu/hw/input/tsc2005.c b/qemu/hw/input/tsc2005.c
deleted file mode 100644
index 9b359aaec..000000000
--- a/qemu/hw/input/tsc2005.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * TI TSC2005 emulator.
- *
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "qemu/timer.h"
-#include "ui/console.h"
-#include "hw/devices.h"
-
-#define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - (p ? 12 : 10)))
-
-typedef struct {
- qemu_irq pint; /* Combination of the nPENIRQ and DAV signals */
- QEMUTimer *timer;
- uint16_t model;
-
- int x, y;
- int pressure;
-
- int state, reg, irq, command;
- uint16_t data, dav;
-
- int busy;
- int enabled;
- int host_mode;
- int function;
- int nextfunction;
- int precision;
- int nextprecision;
- int filter;
- int pin_func;
- int timing[2];
- int noise;
- int reset;
- int pdst;
- int pnd0;
- uint16_t temp_thr[2];
- uint16_t aux_thr[2];
-
- int tr[8];
-} TSC2005State;
-
-enum {
- TSC_MODE_XYZ_SCAN = 0x0,
- TSC_MODE_XY_SCAN,
- TSC_MODE_X,
- TSC_MODE_Y,
- TSC_MODE_Z,
- TSC_MODE_AUX,
- TSC_MODE_TEMP1,
- TSC_MODE_TEMP2,
- TSC_MODE_AUX_SCAN,
- TSC_MODE_X_TEST,
- TSC_MODE_Y_TEST,
- TSC_MODE_TS_TEST,
- TSC_MODE_RESERVED,
- TSC_MODE_XX_DRV,
- TSC_MODE_YY_DRV,
- TSC_MODE_YX_DRV,
-};
-
-static const uint16_t mode_regs[16] = {
- 0xf000, /* X, Y, Z scan */
- 0xc000, /* X, Y scan */
- 0x8000, /* X */
- 0x4000, /* Y */
- 0x3000, /* Z */
- 0x0800, /* AUX */
- 0x0400, /* TEMP1 */
- 0x0200, /* TEMP2 */
- 0x0800, /* AUX scan */
- 0x0040, /* X test */
- 0x0020, /* Y test */
- 0x0080, /* Short-circuit test */
- 0x0000, /* Reserved */
- 0x0000, /* X+, X- drivers */
- 0x0000, /* Y+, Y- drivers */
- 0x0000, /* Y+, X- drivers */
-};
-
-#define X_TRANSFORM(s) \
- ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
-#define Y_TRANSFORM(s) \
- ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
-#define Z1_TRANSFORM(s) \
- ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
-#define Z2_TRANSFORM(s) \
- ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
-
-#define AUX_VAL (700 << 4) /* +/- 3 at 12-bit */
-#define TEMP1_VAL (1264 << 4) /* +/- 5 at 12-bit */
-#define TEMP2_VAL (1531 << 4) /* +/- 5 at 12-bit */
-
-static uint16_t tsc2005_read(TSC2005State *s, int reg)
-{
- uint16_t ret;
-
- switch (reg) {
- case 0x0: /* X */
- s->dav &= ~mode_regs[TSC_MODE_X];
- return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
- (s->noise & 3);
- case 0x1: /* Y */
- s->dav &= ~mode_regs[TSC_MODE_Y];
- s->noise ++;
- return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
- (s->noise & 3);
- case 0x2: /* Z1 */
- s->dav &= 0xdfff;
- return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
- (s->noise & 3);
- case 0x3: /* Z2 */
- s->dav &= 0xefff;
- return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
- (s->noise & 3);
-
- case 0x4: /* AUX */
- s->dav &= ~mode_regs[TSC_MODE_AUX];
- return TSC_CUT_RESOLUTION(AUX_VAL, s->precision);
-
- case 0x5: /* TEMP1 */
- s->dav &= ~mode_regs[TSC_MODE_TEMP1];
- return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
- (s->noise & 5);
- case 0x6: /* TEMP2 */
- s->dav &= 0xdfff;
- s->dav &= ~mode_regs[TSC_MODE_TEMP2];
- return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
- (s->noise & 3);
-
- case 0x7: /* Status */
- ret = s->dav | (s->reset << 7) | (s->pdst << 2) | 0x0;
- s->dav &= ~(mode_regs[TSC_MODE_X_TEST] | mode_regs[TSC_MODE_Y_TEST] |
- mode_regs[TSC_MODE_TS_TEST]);
- s->reset = 1;
- return ret;
-
- case 0x8: /* AUX high treshold */
- return s->aux_thr[1];
- case 0x9: /* AUX low treshold */
- return s->aux_thr[0];
-
- case 0xa: /* TEMP high treshold */
- return s->temp_thr[1];
- case 0xb: /* TEMP low treshold */
- return s->temp_thr[0];
-
- case 0xc: /* CFR0 */
- return (s->pressure << 15) | ((!s->busy) << 14) |
- (s->nextprecision << 13) | s->timing[0];
- case 0xd: /* CFR1 */
- return s->timing[1];
- case 0xe: /* CFR2 */
- return (s->pin_func << 14) | s->filter;
-
- case 0xf: /* Function select status */
- return s->function >= 0 ? 1 << s->function : 0;
- }
-
- /* Never gets here */
- return 0xffff;
-}
-
-static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
-{
- switch (reg) {
- case 0x8: /* AUX high treshold */
- s->aux_thr[1] = data;
- break;
- case 0x9: /* AUX low treshold */
- s->aux_thr[0] = data;
- break;
-
- case 0xa: /* TEMP high treshold */
- s->temp_thr[1] = data;
- break;
- case 0xb: /* TEMP low treshold */
- s->temp_thr[0] = data;
- break;
-
- case 0xc: /* CFR0 */
- s->host_mode = data >> 15;
- if (s->enabled != !(data & 0x4000)) {
- s->enabled = !(data & 0x4000);
- fprintf(stderr, "%s: touchscreen sense %sabled\n",
- __FUNCTION__, s->enabled ? "en" : "dis");
- if (s->busy && !s->enabled)
- timer_del(s->timer);
- s->busy &= s->enabled;
- }
- s->nextprecision = (data >> 13) & 1;
- s->timing[0] = data & 0x1fff;
- if ((s->timing[0] >> 11) == 3)
- fprintf(stderr, "%s: illegal conversion clock setting\n",
- __FUNCTION__);
- break;
- case 0xd: /* CFR1 */
- s->timing[1] = data & 0xf07;
- break;
- case 0xe: /* CFR2 */
- s->pin_func = (data >> 14) & 3;
- s->filter = data & 0x3fff;
- break;
-
- default:
- fprintf(stderr, "%s: write into read-only register %x\n",
- __FUNCTION__, reg);
- }
-}
-
-/* This handles most of the chip's logic. */
-static void tsc2005_pin_update(TSC2005State *s)
-{
- int64_t expires;
- int pin_state;
-
- switch (s->pin_func) {
- case 0:
- pin_state = !s->pressure && !!s->dav;
- break;
- case 1:
- case 3:
- default:
- pin_state = !s->dav;
- break;
- case 2:
- pin_state = !s->pressure;
- }
-
- if (pin_state != s->irq) {
- s->irq = pin_state;
- qemu_set_irq(s->pint, s->irq);
- }
-
- switch (s->nextfunction) {
- case TSC_MODE_XYZ_SCAN:
- case TSC_MODE_XY_SCAN:
- if (!s->host_mode && s->dav)
- s->enabled = 0;
- if (!s->pressure)
- return;
- /* Fall through */
- case TSC_MODE_AUX_SCAN:
- break;
-
- case TSC_MODE_X:
- case TSC_MODE_Y:
- case TSC_MODE_Z:
- if (!s->pressure)
- return;
- /* Fall through */
- case TSC_MODE_AUX:
- case TSC_MODE_TEMP1:
- case TSC_MODE_TEMP2:
- case TSC_MODE_X_TEST:
- case TSC_MODE_Y_TEST:
- case TSC_MODE_TS_TEST:
- if (s->dav)
- s->enabled = 0;
- break;
-
- case TSC_MODE_RESERVED:
- case TSC_MODE_XX_DRV:
- case TSC_MODE_YY_DRV:
- case TSC_MODE_YX_DRV:
- default:
- return;
- }
-
- if (!s->enabled || s->busy)
- return;
-
- s->busy = 1;
- s->precision = s->nextprecision;
- s->function = s->nextfunction;
- s->pdst = !s->pnd0; /* Synchronised on internal clock */
- expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND >> 7);
- timer_mod(s->timer, expires);
-}
-
-static void tsc2005_reset(TSC2005State *s)
-{
- s->state = 0;
- s->pin_func = 0;
- s->enabled = 0;
- s->busy = 0;
- s->nextprecision = 0;
- s->nextfunction = 0;
- s->timing[0] = 0;
- s->timing[1] = 0;
- s->irq = 0;
- s->dav = 0;
- s->reset = 0;
- s->pdst = 1;
- s->pnd0 = 0;
- s->function = -1;
- s->temp_thr[0] = 0x000;
- s->temp_thr[1] = 0xfff;
- s->aux_thr[0] = 0x000;
- s->aux_thr[1] = 0xfff;
-
- tsc2005_pin_update(s);
-}
-
-static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
-{
- TSC2005State *s = opaque;
- uint32_t ret = 0;
-
- switch (s->state ++) {
- case 0:
- if (value & 0x80) {
- /* Command */
- if (value & (1 << 1))
- tsc2005_reset(s);
- else {
- s->nextfunction = (value >> 3) & 0xf;
- s->nextprecision = (value >> 2) & 1;
- if (s->enabled != !(value & 1)) {
- s->enabled = !(value & 1);
- fprintf(stderr, "%s: touchscreen sense %sabled\n",
- __FUNCTION__, s->enabled ? "en" : "dis");
- if (s->busy && !s->enabled)
- timer_del(s->timer);
- s->busy &= s->enabled;
- }
- tsc2005_pin_update(s);
- }
-
- s->state = 0;
- } else if (value) {
- /* Data transfer */
- s->reg = (value >> 3) & 0xf;
- s->pnd0 = (value >> 1) & 1;
- s->command = value & 1;
-
- if (s->command) {
- /* Read */
- s->data = tsc2005_read(s, s->reg);
- tsc2005_pin_update(s);
- } else
- s->data = 0;
- } else
- s->state = 0;
- break;
-
- case 1:
- if (s->command)
- ret = (s->data >> 8) & 0xff;
- else
- s->data |= value << 8;
- break;
-
- case 2:
- if (s->command)
- ret = s->data & 0xff;
- else {
- s->data |= value;
- tsc2005_write(s, s->reg, s->data);
- tsc2005_pin_update(s);
- }
-
- s->state = 0;
- break;
- }
-
- return ret;
-}
-
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len)
-{
- uint32_t ret = 0;
-
- len &= ~7;
- while (len > 0) {
- len -= 8;
- ret |= tsc2005_txrx_word(opaque, (value >> len) & 0xff) << len;
- }
-
- return ret;
-}
-
-static void tsc2005_timer_tick(void *opaque)
-{
- TSC2005State *s = opaque;
-
- /* Timer ticked -- a set of conversions has been finished. */
-
- if (!s->busy)
- return;
-
- s->busy = 0;
- s->dav |= mode_regs[s->function];
- s->function = -1;
- tsc2005_pin_update(s);
-}
-
-static void tsc2005_touchscreen_event(void *opaque,
- int x, int y, int z, int buttons_state)
-{
- TSC2005State *s = opaque;
- int p = s->pressure;
-
- if (buttons_state) {
- s->x = x;
- s->y = y;
- }
- s->pressure = !!buttons_state;
-
- /*
- * Note: We would get better responsiveness in the guest by
- * signaling TS events immediately, but for now we simulate
- * the first conversion delay for sake of correctness.
- */
- if (p != s->pressure)
- tsc2005_pin_update(s);
-}
-
-static void tsc2005_save(QEMUFile *f, void *opaque)
-{
- TSC2005State *s = (TSC2005State *) opaque;
- int i;
-
- qemu_put_be16(f, s->x);
- qemu_put_be16(f, s->y);
- qemu_put_byte(f, s->pressure);
-
- qemu_put_byte(f, s->state);
- qemu_put_byte(f, s->reg);
- qemu_put_byte(f, s->command);
-
- qemu_put_byte(f, s->irq);
- qemu_put_be16s(f, &s->dav);
- qemu_put_be16s(f, &s->data);
-
- timer_put(f, s->timer);
- qemu_put_byte(f, s->enabled);
- qemu_put_byte(f, s->host_mode);
- qemu_put_byte(f, s->function);
- qemu_put_byte(f, s->nextfunction);
- qemu_put_byte(f, s->precision);
- qemu_put_byte(f, s->nextprecision);
- qemu_put_be16(f, s->filter);
- qemu_put_byte(f, s->pin_func);
- qemu_put_be16(f, s->timing[0]);
- qemu_put_be16(f, s->timing[1]);
- qemu_put_be16s(f, &s->temp_thr[0]);
- qemu_put_be16s(f, &s->temp_thr[1]);
- qemu_put_be16s(f, &s->aux_thr[0]);
- qemu_put_be16s(f, &s->aux_thr[1]);
- qemu_put_be32(f, s->noise);
- qemu_put_byte(f, s->reset);
- qemu_put_byte(f, s->pdst);
- qemu_put_byte(f, s->pnd0);
-
- for (i = 0; i < 8; i ++)
- qemu_put_be32(f, s->tr[i]);
-}
-
-static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
-{
- TSC2005State *s = (TSC2005State *) opaque;
- int i;
-
- s->x = qemu_get_be16(f);
- s->y = qemu_get_be16(f);
- s->pressure = qemu_get_byte(f);
-
- s->state = qemu_get_byte(f);
- s->reg = qemu_get_byte(f);
- s->command = qemu_get_byte(f);
-
- s->irq = qemu_get_byte(f);
- qemu_get_be16s(f, &s->dav);
- qemu_get_be16s(f, &s->data);
-
- timer_get(f, s->timer);
- s->enabled = qemu_get_byte(f);
- s->host_mode = qemu_get_byte(f);
- s->function = qemu_get_byte(f);
- s->nextfunction = qemu_get_byte(f);
- s->precision = qemu_get_byte(f);
- s->nextprecision = qemu_get_byte(f);
- s->filter = qemu_get_be16(f);
- s->pin_func = qemu_get_byte(f);
- s->timing[0] = qemu_get_be16(f);
- s->timing[1] = qemu_get_be16(f);
- qemu_get_be16s(f, &s->temp_thr[0]);
- qemu_get_be16s(f, &s->temp_thr[1]);
- qemu_get_be16s(f, &s->aux_thr[0]);
- qemu_get_be16s(f, &s->aux_thr[1]);
- s->noise = qemu_get_be32(f);
- s->reset = qemu_get_byte(f);
- s->pdst = qemu_get_byte(f);
- s->pnd0 = qemu_get_byte(f);
-
- for (i = 0; i < 8; i ++)
- s->tr[i] = qemu_get_be32(f);
-
- s->busy = timer_pending(s->timer);
- tsc2005_pin_update(s);
-
- return 0;
-}
-
-void *tsc2005_init(qemu_irq pintdav)
-{
- TSC2005State *s;
-
- s = (TSC2005State *)
- g_malloc0(sizeof(TSC2005State));
- s->x = 400;
- s->y = 240;
- s->pressure = 0;
- s->precision = s->nextprecision = 0;
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc2005_timer_tick, s);
- s->pint = pintdav;
- s->model = 0x2005;
-
- s->tr[0] = 0;
- s->tr[1] = 1;
- s->tr[2] = 1;
- s->tr[3] = 0;
- s->tr[4] = 1;
- s->tr[5] = 0;
- s->tr[6] = 1;
- s->tr[7] = 0;
-
- tsc2005_reset(s);
-
- qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, 1,
- "QEMU TSC2005-driven Touchscreen");
-
- qemu_register_reset((void *) tsc2005_reset, s);
- register_savevm(NULL, "tsc2005", -1, 0, tsc2005_save, tsc2005_load, s);
-
- return s;
-}
-
-/*
- * Use tslib generated calibration data to generate ADC input values
- * from the touchscreen. Assuming 12-bit precision was used during
- * tslib calibration.
- */
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info)
-{
- TSC2005State *s = (TSC2005State *) opaque;
-
- /* This version assumes touchscreen X & Y axis are parallel or
- * perpendicular to LCD's X & Y axis in some way. */
- if (abs(info->a[0]) > abs(info->a[1])) {
- s->tr[0] = 0;
- s->tr[1] = -info->a[6] * info->x;
- s->tr[2] = info->a[0];
- s->tr[3] = -info->a[2] / info->a[0];
- s->tr[4] = info->a[6] * info->y;
- s->tr[5] = 0;
- s->tr[6] = info->a[4];
- s->tr[7] = -info->a[5] / info->a[4];
- } else {
- s->tr[0] = info->a[6] * info->y;
- s->tr[1] = 0;
- s->tr[2] = info->a[1];
- s->tr[3] = -info->a[2] / info->a[1];
- s->tr[4] = 0;
- s->tr[5] = -info->a[6] * info->x;
- s->tr[6] = info->a[3];
- s->tr[7] = -info->a[5] / info->a[3];
- }
-
- s->tr[0] >>= 11;
- s->tr[1] >>= 11;
- s->tr[3] <<= 4;
- s->tr[4] >>= 11;
- s->tr[5] >>= 11;
- s->tr[7] <<= 4;
-}
diff --git a/qemu/hw/input/tsc210x.c b/qemu/hw/input/tsc210x.c
deleted file mode 100644
index 93ca374fc..000000000
--- a/qemu/hw/input/tsc210x.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
- * TI TSC2301 (touchscreen/sensors/keypad).
- *
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "audio/audio.h"
-#include "qemu/timer.h"
-#include "ui/console.h"
-#include "hw/arm/omap.h" /* For I2SCodec and uWireSlave */
-#include "hw/devices.h"
-
-#define TSC_DATA_REGISTERS_PAGE 0x0
-#define TSC_CONTROL_REGISTERS_PAGE 0x1
-#define TSC_AUDIO_REGISTERS_PAGE 0x2
-
-#define TSC_VERBOSE
-
-#define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - resolution[p]))
-
-typedef struct {
- qemu_irq pint;
- qemu_irq kbint;
- qemu_irq davint;
- QEMUTimer *timer;
- QEMUSoundCard card;
- uWireSlave chip;
- I2SCodec codec;
- uint8_t in_fifo[16384];
- uint8_t out_fifo[16384];
- uint16_t model;
-
- int x, y;
- int pressure;
-
- int state, page, offset, irq;
- uint16_t command, dav;
-
- int busy;
- int enabled;
- int host_mode;
- int function;
- int nextfunction;
- int precision;
- int nextprecision;
- int filter;
- int pin_func;
- int ref;
- int timing;
- int noise;
-
- uint16_t audio_ctrl1;
- uint16_t audio_ctrl2;
- uint16_t audio_ctrl3;
- uint16_t pll[3];
- uint16_t volume;
- int64_t volume_change;
- int softstep;
- uint16_t dac_power;
- int64_t powerdown;
- uint16_t filter_data[0x14];
-
- const char *name;
- SWVoiceIn *adc_voice[1];
- SWVoiceOut *dac_voice[1];
- int i2s_rx_rate;
- int i2s_tx_rate;
-
- int tr[8];
-
- struct {
- uint16_t down;
- uint16_t mask;
- int scan;
- int debounce;
- int mode;
- int intr;
- } kb;
-} TSC210xState;
-
-static const int resolution[4] = { 12, 8, 10, 12 };
-
-#define TSC_MODE_NO_SCAN 0x0
-#define TSC_MODE_XY_SCAN 0x1
-#define TSC_MODE_XYZ_SCAN 0x2
-#define TSC_MODE_X 0x3
-#define TSC_MODE_Y 0x4
-#define TSC_MODE_Z 0x5
-#define TSC_MODE_BAT1 0x6
-#define TSC_MODE_BAT2 0x7
-#define TSC_MODE_AUX 0x8
-#define TSC_MODE_AUX_SCAN 0x9
-#define TSC_MODE_TEMP1 0xa
-#define TSC_MODE_PORT_SCAN 0xb
-#define TSC_MODE_TEMP2 0xc
-#define TSC_MODE_XX_DRV 0xd
-#define TSC_MODE_YY_DRV 0xe
-#define TSC_MODE_YX_DRV 0xf
-
-static const uint16_t mode_regs[16] = {
- 0x0000, /* No scan */
- 0x0600, /* X, Y scan */
- 0x0780, /* X, Y, Z scan */
- 0x0400, /* X */
- 0x0200, /* Y */
- 0x0180, /* Z */
- 0x0040, /* BAT1 */
- 0x0030, /* BAT2 */
- 0x0010, /* AUX */
- 0x0010, /* AUX scan */
- 0x0004, /* TEMP1 */
- 0x0070, /* Port scan */
- 0x0002, /* TEMP2 */
- 0x0000, /* X+, X- drivers */
- 0x0000, /* Y+, Y- drivers */
- 0x0000, /* Y+, X- drivers */
-};
-
-#define X_TRANSFORM(s) \
- ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
-#define Y_TRANSFORM(s) \
- ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
-#define Z1_TRANSFORM(s) \
- ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
-#define Z2_TRANSFORM(s) \
- ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
-
-#define BAT1_VAL 0x8660
-#define BAT2_VAL 0x0000
-#define AUX1_VAL 0x35c0
-#define AUX2_VAL 0xffff
-#define TEMP1_VAL 0x8c70
-#define TEMP2_VAL 0xa5b0
-
-#define TSC_POWEROFF_DELAY 50
-#define TSC_SOFTSTEP_DELAY 50
-
-static void tsc210x_reset(TSC210xState *s)
-{
- s->state = 0;
- s->pin_func = 2;
- s->enabled = 0;
- s->busy = 0;
- s->nextfunction = 0;
- s->ref = 0;
- s->timing = 0;
- s->irq = 0;
- s->dav = 0;
-
- s->audio_ctrl1 = 0x0000;
- s->audio_ctrl2 = 0x4410;
- s->audio_ctrl3 = 0x0000;
- s->pll[0] = 0x1004;
- s->pll[1] = 0x0000;
- s->pll[2] = 0x1fff;
- s->volume = 0xffff;
- s->dac_power = 0x8540;
- s->softstep = 1;
- s->volume_change = 0;
- s->powerdown = 0;
- s->filter_data[0x00] = 0x6be3;
- s->filter_data[0x01] = 0x9666;
- s->filter_data[0x02] = 0x675d;
- s->filter_data[0x03] = 0x6be3;
- s->filter_data[0x04] = 0x9666;
- s->filter_data[0x05] = 0x675d;
- s->filter_data[0x06] = 0x7d83;
- s->filter_data[0x07] = 0x84ee;
- s->filter_data[0x08] = 0x7d83;
- s->filter_data[0x09] = 0x84ee;
- s->filter_data[0x0a] = 0x6be3;
- s->filter_data[0x0b] = 0x9666;
- s->filter_data[0x0c] = 0x675d;
- s->filter_data[0x0d] = 0x6be3;
- s->filter_data[0x0e] = 0x9666;
- s->filter_data[0x0f] = 0x675d;
- s->filter_data[0x10] = 0x7d83;
- s->filter_data[0x11] = 0x84ee;
- s->filter_data[0x12] = 0x7d83;
- s->filter_data[0x13] = 0x84ee;
-
- s->i2s_tx_rate = 0;
- s->i2s_rx_rate = 0;
-
- s->kb.scan = 1;
- s->kb.debounce = 0;
- s->kb.mask = 0x0000;
- s->kb.mode = 3;
- s->kb.intr = 0;
-
- qemu_set_irq(s->pint, !s->irq);
- qemu_set_irq(s->davint, !s->dav);
- qemu_irq_raise(s->kbint);
-}
-
-typedef struct {
- int rate;
- int dsor;
- int fsref;
-} TSC210xRateInfo;
-
-/* { rate, dsor, fsref } */
-static const TSC210xRateInfo tsc2102_rates[] = {
- /* Fsref / 6.0 */
- { 7350, 63, 1 },
- { 8000, 63, 0 },
- /* Fsref / 6.0 */
- { 7350, 54, 1 },
- { 8000, 54, 0 },
- /* Fsref / 5.0 */
- { 8820, 45, 1 },
- { 9600, 45, 0 },
- /* Fsref / 4.0 */
- { 11025, 36, 1 },
- { 12000, 36, 0 },
- /* Fsref / 3.0 */
- { 14700, 27, 1 },
- { 16000, 27, 0 },
- /* Fsref / 2.0 */
- { 22050, 18, 1 },
- { 24000, 18, 0 },
- /* Fsref / 1.5 */
- { 29400, 9, 1 },
- { 32000, 9, 0 },
- /* Fsref */
- { 44100, 0, 1 },
- { 48000, 0, 0 },
-
- { 0, 0, 0 },
-};
-
-static inline void tsc210x_out_flush(TSC210xState *s, int len)
-{
- uint8_t *data = s->codec.out.fifo + s->codec.out.start;
- uint8_t *end = data + len;
-
- while (data < end)
- data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
-
- s->codec.out.len -= len;
- if (s->codec.out.len)
- memmove(s->codec.out.fifo, end, s->codec.out.len);
- s->codec.out.start = 0;
-}
-
-static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
-{
- if (s->codec.out.len >= free_b) {
- tsc210x_out_flush(s, free_b);
- return;
- }
-
- s->codec.out.size = MIN(free_b, 16384);
- qemu_irq_raise(s->codec.tx_start);
-}
-
-static void tsc2102_audio_rate_update(TSC210xState *s)
-{
- const TSC210xRateInfo *rate;
-
- s->codec.tx_rate = 0;
- s->codec.rx_rate = 0;
- if (s->dac_power & (1 << 15)) /* PWDNC */
- return;
-
- for (rate = tsc2102_rates; rate->rate; rate ++)
- if (rate->dsor == (s->audio_ctrl1 & 0x3f) && /* DACFS */
- rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
- break;
- if (!rate->rate) {
- printf("%s: unknown sampling rate configured\n", __FUNCTION__);
- return;
- }
-
- s->codec.tx_rate = rate->rate;
-}
-
-static void tsc2102_audio_output_update(TSC210xState *s)
-{
- int enable;
- struct audsettings fmt;
-
- if (s->dac_voice[0]) {
- tsc210x_out_flush(s, s->codec.out.len);
- s->codec.out.size = 0;
- AUD_set_active_out(s->dac_voice[0], 0);
- AUD_close_out(&s->card, s->dac_voice[0]);
- s->dac_voice[0] = NULL;
- }
- s->codec.cts = 0;
-
- enable =
- (~s->dac_power & (1 << 15)) && /* PWDNC */
- (~s->dac_power & (1 << 10)); /* DAPWDN */
- if (!enable || !s->codec.tx_rate)
- return;
-
- /* Force our own sampling rate even in slave DAC mode */
- fmt.endianness = 0;
- fmt.nchannels = 2;
- fmt.freq = s->codec.tx_rate;
- fmt.fmt = AUD_FMT_S16;
-
- s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
- "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
- if (s->dac_voice[0]) {
- s->codec.cts = 1;
- AUD_set_active_out(s->dac_voice[0], 1);
- }
-}
-
-static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
-{
- switch (reg) {
- case 0x00: /* X */
- s->dav &= 0xfbff;
- return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
- (s->noise & 3);
-
- case 0x01: /* Y */
- s->noise ++;
- s->dav &= 0xfdff;
- return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
- (s->noise & 3);
-
- case 0x02: /* Z1 */
- s->dav &= 0xfeff;
- return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
- (s->noise & 3);
-
- case 0x03: /* Z2 */
- s->dav &= 0xff7f;
- return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
- (s->noise & 3);
-
- case 0x04: /* KPData */
- if ((s->model & 0xff00) == 0x2300) {
- if (s->kb.intr && (s->kb.mode & 2)) {
- s->kb.intr = 0;
- qemu_irq_raise(s->kbint);
- }
- return s->kb.down;
- }
-
- return 0xffff;
-
- case 0x05: /* BAT1 */
- s->dav &= 0xffbf;
- return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision) +
- (s->noise & 6);
-
- case 0x06: /* BAT2 */
- s->dav &= 0xffdf;
- return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
-
- case 0x07: /* AUX1 */
- s->dav &= 0xffef;
- return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
-
- case 0x08: /* AUX2 */
- s->dav &= 0xfff7;
- return 0xffff;
-
- case 0x09: /* TEMP1 */
- s->dav &= 0xfffb;
- return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
- (s->noise & 5);
-
- case 0x0a: /* TEMP2 */
- s->dav &= 0xfffd;
- return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
- (s->noise & 3);
-
- case 0x0b: /* DAC */
- s->dav &= 0xfffe;
- return 0xffff;
-
- default:
-#ifdef TSC_VERBOSE
- fprintf(stderr, "tsc2102_data_register_read: "
- "no such register: 0x%02x\n", reg);
-#endif
- return 0xffff;
- }
-}
-
-static uint16_t tsc2102_control_register_read(
- TSC210xState *s, int reg)
-{
- switch (reg) {
- case 0x00: /* TSC ADC */
- return (s->pressure << 15) | ((!s->busy) << 14) |
- (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter;
-
- case 0x01: /* Status / Keypad Control */
- if ((s->model & 0xff00) == 0x2100)
- return (s->pin_func << 14) | ((!s->enabled) << 13) |
- (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
- else
- return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) |
- (s->kb.debounce << 11);
-
- case 0x02: /* DAC Control */
- if ((s->model & 0xff00) == 0x2300)
- return s->dac_power & 0x8000;
- else
- goto bad_reg;
-
- case 0x03: /* Reference */
- return s->ref;
-
- case 0x04: /* Reset */
- return 0xffff;
-
- case 0x05: /* Configuration */
- return s->timing;
-
- case 0x06: /* Secondary configuration */
- if ((s->model & 0xff00) == 0x2100)
- goto bad_reg;
- return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2];
-
- case 0x10: /* Keypad Mask */
- if ((s->model & 0xff00) == 0x2100)
- goto bad_reg;
- return s->kb.mask;
-
- default:
- bad_reg:
-#ifdef TSC_VERBOSE
- fprintf(stderr, "tsc2102_control_register_read: "
- "no such register: 0x%02x\n", reg);
-#endif
- return 0xffff;
- }
-}
-
-static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
-{
- int l_ch, r_ch;
- uint16_t val;
-
- switch (reg) {
- case 0x00: /* Audio Control 1 */
- return s->audio_ctrl1;
-
- case 0x01:
- return 0xff00;
-
- case 0x02: /* DAC Volume Control */
- return s->volume;
-
- case 0x03:
- return 0x8b00;
-
- case 0x04: /* Audio Control 2 */
- l_ch = 1;
- r_ch = 1;
- if (s->softstep && !(s->dac_power & (1 << 10))) {
- l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
- s->volume_change + TSC_SOFTSTEP_DELAY);
- r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
- s->volume_change + TSC_SOFTSTEP_DELAY);
- }
-
- return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
-
- case 0x05: /* Stereo DAC Power Control */
- return 0x2aa0 | s->dac_power |
- (((s->dac_power & (1 << 10)) &&
- (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
- s->powerdown + TSC_POWEROFF_DELAY)) << 6);
-
- case 0x06: /* Audio Control 3 */
- val = s->audio_ctrl3 | 0x0001;
- s->audio_ctrl3 &= 0xff3f;
- return val;
-
- case 0x07: /* LCH_BASS_BOOST_N0 */
- case 0x08: /* LCH_BASS_BOOST_N1 */
- case 0x09: /* LCH_BASS_BOOST_N2 */
- case 0x0a: /* LCH_BASS_BOOST_N3 */
- case 0x0b: /* LCH_BASS_BOOST_N4 */
- case 0x0c: /* LCH_BASS_BOOST_N5 */
- case 0x0d: /* LCH_BASS_BOOST_D1 */
- case 0x0e: /* LCH_BASS_BOOST_D2 */
- case 0x0f: /* LCH_BASS_BOOST_D4 */
- case 0x10: /* LCH_BASS_BOOST_D5 */
- case 0x11: /* RCH_BASS_BOOST_N0 */
- case 0x12: /* RCH_BASS_BOOST_N1 */
- case 0x13: /* RCH_BASS_BOOST_N2 */
- case 0x14: /* RCH_BASS_BOOST_N3 */
- case 0x15: /* RCH_BASS_BOOST_N4 */
- case 0x16: /* RCH_BASS_BOOST_N5 */
- case 0x17: /* RCH_BASS_BOOST_D1 */
- case 0x18: /* RCH_BASS_BOOST_D2 */
- case 0x19: /* RCH_BASS_BOOST_D4 */
- case 0x1a: /* RCH_BASS_BOOST_D5 */
- return s->filter_data[reg - 0x07];
-
- case 0x1b: /* PLL Programmability 1 */
- return s->pll[0];
-
- case 0x1c: /* PLL Programmability 2 */
- return s->pll[1];
-
- case 0x1d: /* Audio Control 4 */
- return (!s->softstep) << 14;
-
- default:
-#ifdef TSC_VERBOSE
- fprintf(stderr, "tsc2102_audio_register_read: "
- "no such register: 0x%02x\n", reg);
-#endif
- return 0xffff;
- }
-}
-
-static void tsc2102_data_register_write(
- TSC210xState *s, int reg, uint16_t value)
-{
- switch (reg) {
- case 0x00: /* X */
- case 0x01: /* Y */
- case 0x02: /* Z1 */
- case 0x03: /* Z2 */
- case 0x05: /* BAT1 */
- case 0x06: /* BAT2 */
- case 0x07: /* AUX1 */
- case 0x08: /* AUX2 */
- case 0x09: /* TEMP1 */
- case 0x0a: /* TEMP2 */
- return;
-
- default:
-#ifdef TSC_VERBOSE
- fprintf(stderr, "tsc2102_data_register_write: "
- "no such register: 0x%02x\n", reg);
-#endif
- }
-}
-
-static void tsc2102_control_register_write(
- TSC210xState *s, int reg, uint16_t value)
-{
- switch (reg) {
- case 0x00: /* TSC ADC */
- s->host_mode = value >> 15;
- s->enabled = !(value & 0x4000);
- if (s->busy && !s->enabled)
- timer_del(s->timer);
- s->busy &= s->enabled;
- s->nextfunction = (value >> 10) & 0xf;
- s->nextprecision = (value >> 8) & 3;
- s->filter = value & 0xff;
- return;
-
- case 0x01: /* Status / Keypad Control */
- if ((s->model & 0xff00) == 0x2100)
- s->pin_func = value >> 14;
- else {
- s->kb.scan = (value >> 14) & 1;
- s->kb.debounce = (value >> 11) & 7;
- if (s->kb.intr && s->kb.scan) {
- s->kb.intr = 0;
- qemu_irq_raise(s->kbint);
- }
- }
- return;
-
- case 0x02: /* DAC Control */
- if ((s->model & 0xff00) == 0x2300) {
- s->dac_power &= 0x7fff;
- s->dac_power |= 0x8000 & value;
- } else
- goto bad_reg;
- break;
-
- case 0x03: /* Reference */
- s->ref = value & 0x1f;
- return;
-
- case 0x04: /* Reset */
- if (value == 0xbb00) {
- if (s->busy)
- timer_del(s->timer);
- tsc210x_reset(s);
-#ifdef TSC_VERBOSE
- } else {
- fprintf(stderr, "tsc2102_control_register_write: "
- "wrong value written into RESET\n");
-#endif
- }
- return;
-
- case 0x05: /* Configuration */
- s->timing = value & 0x3f;
-#ifdef TSC_VERBOSE
- if (value & ~0x3f)
- fprintf(stderr, "tsc2102_control_register_write: "
- "wrong value written into CONFIG\n");
-#endif
- return;
-
- case 0x06: /* Secondary configuration */
- if ((s->model & 0xff00) == 0x2100)
- goto bad_reg;
- s->kb.mode = value >> 14;
- s->pll[2] = value & 0x3ffff;
- return;
-
- case 0x10: /* Keypad Mask */
- if ((s->model & 0xff00) == 0x2100)
- goto bad_reg;
- s->kb.mask = value;
- return;
-
- default:
- bad_reg:
-#ifdef TSC_VERBOSE
- fprintf(stderr, "tsc2102_control_register_write: "
- "no such register: 0x%02x\n", reg);
-#endif
- }
-}
-
-static void tsc2102_audio_register_write(
- TSC210xState *s, int reg, uint16_t value)
-{
- switch (reg) {
- case 0x00: /* Audio Control 1 */
- s->audio_ctrl1 = value & 0x0f3f;
-#ifdef TSC_VERBOSE
- if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into Audio 1\n");
-#endif
- tsc2102_audio_rate_update(s);
- tsc2102_audio_output_update(s);
- return;
-
- case 0x01:
-#ifdef TSC_VERBOSE
- if (value != 0xff00)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into reg 0x01\n");
-#endif
- return;
-
- case 0x02: /* DAC Volume Control */
- s->volume = value;
- s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- return;
-
- case 0x03:
-#ifdef TSC_VERBOSE
- if (value != 0x8b00)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into reg 0x03\n");
-#endif
- return;
-
- case 0x04: /* Audio Control 2 */
- s->audio_ctrl2 = value & 0xf7f2;
-#ifdef TSC_VERBOSE
- if (value & ~0xf7fd)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into Audio 2\n");
-#endif
- return;
-
- case 0x05: /* Stereo DAC Power Control */
- if ((value & ~s->dac_power) & (1 << 10))
- s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
- s->dac_power = value & 0x9543;
-#ifdef TSC_VERBOSE
- if ((value & ~0x9543) != 0x2aa0)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into Power\n");
-#endif
- tsc2102_audio_rate_update(s);
- tsc2102_audio_output_update(s);
- return;
-
- case 0x06: /* Audio Control 3 */
- s->audio_ctrl3 &= 0x00c0;
- s->audio_ctrl3 |= value & 0xf800;
-#ifdef TSC_VERBOSE
- if (value & ~0xf8c7)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into Audio 3\n");
-#endif
- tsc2102_audio_output_update(s);
- return;
-
- case 0x07: /* LCH_BASS_BOOST_N0 */
- case 0x08: /* LCH_BASS_BOOST_N1 */
- case 0x09: /* LCH_BASS_BOOST_N2 */
- case 0x0a: /* LCH_BASS_BOOST_N3 */
- case 0x0b: /* LCH_BASS_BOOST_N4 */
- case 0x0c: /* LCH_BASS_BOOST_N5 */
- case 0x0d: /* LCH_BASS_BOOST_D1 */
- case 0x0e: /* LCH_BASS_BOOST_D2 */
- case 0x0f: /* LCH_BASS_BOOST_D4 */
- case 0x10: /* LCH_BASS_BOOST_D5 */
- case 0x11: /* RCH_BASS_BOOST_N0 */
- case 0x12: /* RCH_BASS_BOOST_N1 */
- case 0x13: /* RCH_BASS_BOOST_N2 */
- case 0x14: /* RCH_BASS_BOOST_N3 */
- case 0x15: /* RCH_BASS_BOOST_N4 */
- case 0x16: /* RCH_BASS_BOOST_N5 */
- case 0x17: /* RCH_BASS_BOOST_D1 */
- case 0x18: /* RCH_BASS_BOOST_D2 */
- case 0x19: /* RCH_BASS_BOOST_D4 */
- case 0x1a: /* RCH_BASS_BOOST_D5 */
- s->filter_data[reg - 0x07] = value;
- return;
-
- case 0x1b: /* PLL Programmability 1 */
- s->pll[0] = value & 0xfffc;
-#ifdef TSC_VERBOSE
- if (value & ~0xfffc)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into PLL 1\n");
-#endif
- return;
-
- case 0x1c: /* PLL Programmability 2 */
- s->pll[1] = value & 0xfffc;
-#ifdef TSC_VERBOSE
- if (value & ~0xfffc)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into PLL 2\n");
-#endif
- return;
-
- case 0x1d: /* Audio Control 4 */
- s->softstep = !(value & 0x4000);
-#ifdef TSC_VERBOSE
- if (value & ~0x4000)
- fprintf(stderr, "tsc2102_audio_register_write: "
- "wrong value written into Audio 4\n");
-#endif
- return;
-
- default:
-#ifdef TSC_VERBOSE
- fprintf(stderr, "tsc2102_audio_register_write: "
- "no such register: 0x%02x\n", reg);
-#endif
- }
-}
-
-/* This handles most of the chip logic. */
-static void tsc210x_pin_update(TSC210xState *s)
-{
- int64_t expires;
- int pin_state;
-
- switch (s->pin_func) {
- case 0:
- pin_state = s->pressure;
- break;
- case 1:
- pin_state = !!s->dav;
- break;
- case 2:
- default:
- pin_state = s->pressure && !s->dav;
- }
-
- if (!s->enabled)
- pin_state = 0;
-
- if (pin_state != s->irq) {
- s->irq = pin_state;
- qemu_set_irq(s->pint, !s->irq);
- }
-
- switch (s->nextfunction) {
- case TSC_MODE_XY_SCAN:
- case TSC_MODE_XYZ_SCAN:
- if (!s->pressure)
- return;
- break;
-
- case TSC_MODE_X:
- case TSC_MODE_Y:
- case TSC_MODE_Z:
- if (!s->pressure)
- return;
- /* Fall through */
- case TSC_MODE_BAT1:
- case TSC_MODE_BAT2:
- case TSC_MODE_AUX:
- case TSC_MODE_TEMP1:
- case TSC_MODE_TEMP2:
- if (s->dav)
- s->enabled = 0;
- break;
-
- case TSC_MODE_AUX_SCAN:
- case TSC_MODE_PORT_SCAN:
- break;
-
- case TSC_MODE_NO_SCAN:
- case TSC_MODE_XX_DRV:
- case TSC_MODE_YY_DRV:
- case TSC_MODE_YX_DRV:
- default:
- return;
- }
-
- if (!s->enabled || s->busy || s->dav)
- return;
-
- s->busy = 1;
- s->precision = s->nextprecision;
- s->function = s->nextfunction;
- expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND >> 10);
- timer_mod(s->timer, expires);
-}
-
-static uint16_t tsc210x_read(TSC210xState *s)
-{
- uint16_t ret = 0x0000;
-
- if (!s->command)
- fprintf(stderr, "tsc210x_read: SPI underrun!\n");
-
- switch (s->page) {
- case TSC_DATA_REGISTERS_PAGE:
- ret = tsc2102_data_register_read(s, s->offset);
- if (!s->dav)
- qemu_irq_raise(s->davint);
- break;
- case TSC_CONTROL_REGISTERS_PAGE:
- ret = tsc2102_control_register_read(s, s->offset);
- break;
- case TSC_AUDIO_REGISTERS_PAGE:
- ret = tsc2102_audio_register_read(s, s->offset);
- break;
- default:
- hw_error("tsc210x_read: wrong memory page\n");
- }
-
- tsc210x_pin_update(s);
-
- /* Allow sequential reads. */
- s->offset ++;
- s->state = 0;
- return ret;
-}
-
-static void tsc210x_write(TSC210xState *s, uint16_t value)
-{
- /*
- * This is a two-state state machine for reading
- * command and data every second time.
- */
- if (!s->state) {
- s->command = value >> 15;
- s->page = (value >> 11) & 0x0f;
- s->offset = (value >> 5) & 0x3f;
- s->state = 1;
- } else {
- if (s->command)
- fprintf(stderr, "tsc210x_write: SPI overrun!\n");
- else
- switch (s->page) {
- case TSC_DATA_REGISTERS_PAGE:
- tsc2102_data_register_write(s, s->offset, value);
- break;
- case TSC_CONTROL_REGISTERS_PAGE:
- tsc2102_control_register_write(s, s->offset, value);
- break;
- case TSC_AUDIO_REGISTERS_PAGE:
- tsc2102_audio_register_write(s, s->offset, value);
- break;
- default:
- hw_error("tsc210x_write: wrong memory page\n");
- }
-
- tsc210x_pin_update(s);
- s->state = 0;
- }
-}
-
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
-{
- TSC210xState *s = opaque;
- uint32_t ret = 0;
-
- if (len != 16)
- hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
-
- /* TODO: sequential reads etc - how do we make sure the host doesn't
- * unintentionally read out a conversion result from a register while
- * transmitting the command word of the next command? */
- if (!value || (s->state && s->command))
- ret = tsc210x_read(s);
- if (value || (s->state && !s->command))
- tsc210x_write(s, value);
-
- return ret;
-}
-
-static void tsc210x_timer_tick(void *opaque)
-{
- TSC210xState *s = opaque;
-
- /* Timer ticked -- a set of conversions has been finished. */
-
- if (!s->busy)
- return;
-
- s->busy = 0;
- s->dav |= mode_regs[s->function];
- tsc210x_pin_update(s);
- qemu_irq_lower(s->davint);
-}
-
-static void tsc210x_touchscreen_event(void *opaque,
- int x, int y, int z, int buttons_state)
-{
- TSC210xState *s = opaque;
- int p = s->pressure;
-
- if (buttons_state) {
- s->x = x;
- s->y = y;
- }
- s->pressure = !!buttons_state;
-
- /*
- * Note: We would get better responsiveness in the guest by
- * signaling TS events immediately, but for now we simulate
- * the first conversion delay for sake of correctness.
- */
- if (p != s->pressure)
- tsc210x_pin_update(s);
-}
-
-static void tsc210x_i2s_swallow(TSC210xState *s)
-{
- if (s->dac_voice[0])
- tsc210x_out_flush(s, s->codec.out.len);
- else
- s->codec.out.len = 0;
-}
-
-static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
-{
- s->i2s_tx_rate = out;
- s->i2s_rx_rate = in;
-}
-
-static void tsc210x_save(QEMUFile *f, void *opaque)
-{
- TSC210xState *s = (TSC210xState *) opaque;
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int i;
-
- qemu_put_be16(f, s->x);
- qemu_put_be16(f, s->y);
- qemu_put_byte(f, s->pressure);
-
- qemu_put_byte(f, s->state);
- qemu_put_byte(f, s->page);
- qemu_put_byte(f, s->offset);
- qemu_put_byte(f, s->command);
-
- qemu_put_byte(f, s->irq);
- qemu_put_be16s(f, &s->dav);
-
- timer_put(f, s->timer);
- qemu_put_byte(f, s->enabled);
- qemu_put_byte(f, s->host_mode);
- qemu_put_byte(f, s->function);
- qemu_put_byte(f, s->nextfunction);
- qemu_put_byte(f, s->precision);
- qemu_put_byte(f, s->nextprecision);
- qemu_put_byte(f, s->filter);
- qemu_put_byte(f, s->pin_func);
- qemu_put_byte(f, s->ref);
- qemu_put_byte(f, s->timing);
- qemu_put_be32(f, s->noise);
-
- qemu_put_be16s(f, &s->audio_ctrl1);
- qemu_put_be16s(f, &s->audio_ctrl2);
- qemu_put_be16s(f, &s->audio_ctrl3);
- qemu_put_be16s(f, &s->pll[0]);
- qemu_put_be16s(f, &s->pll[1]);
- qemu_put_be16s(f, &s->volume);
- qemu_put_sbe64(f, (s->volume_change - now));
- qemu_put_sbe64(f, (s->powerdown - now));
- qemu_put_byte(f, s->softstep);
- qemu_put_be16s(f, &s->dac_power);
-
- for (i = 0; i < 0x14; i ++)
- qemu_put_be16s(f, &s->filter_data[i]);
-}
-
-static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
-{
- TSC210xState *s = (TSC210xState *) opaque;
- int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- int i;
-
- s->x = qemu_get_be16(f);
- s->y = qemu_get_be16(f);
- s->pressure = qemu_get_byte(f);
-
- s->state = qemu_get_byte(f);
- s->page = qemu_get_byte(f);
- s->offset = qemu_get_byte(f);
- s->command = qemu_get_byte(f);
-
- s->irq = qemu_get_byte(f);
- qemu_get_be16s(f, &s->dav);
-
- timer_get(f, s->timer);
- s->enabled = qemu_get_byte(f);
- s->host_mode = qemu_get_byte(f);
- s->function = qemu_get_byte(f);
- if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) {
- return -EINVAL;
- }
- s->nextfunction = qemu_get_byte(f);
- if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) {
- return -EINVAL;
- }
- s->precision = qemu_get_byte(f);
- if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) {
- return -EINVAL;
- }
- s->nextprecision = qemu_get_byte(f);
- if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) {
- return -EINVAL;
- }
- s->filter = qemu_get_byte(f);
- s->pin_func = qemu_get_byte(f);
- s->ref = qemu_get_byte(f);
- s->timing = qemu_get_byte(f);
- s->noise = qemu_get_be32(f);
-
- qemu_get_be16s(f, &s->audio_ctrl1);
- qemu_get_be16s(f, &s->audio_ctrl2);
- qemu_get_be16s(f, &s->audio_ctrl3);
- qemu_get_be16s(f, &s->pll[0]);
- qemu_get_be16s(f, &s->pll[1]);
- qemu_get_be16s(f, &s->volume);
- s->volume_change = qemu_get_sbe64(f) + now;
- s->powerdown = qemu_get_sbe64(f) + now;
- s->softstep = qemu_get_byte(f);
- qemu_get_be16s(f, &s->dac_power);
-
- for (i = 0; i < 0x14; i ++)
- qemu_get_be16s(f, &s->filter_data[i]);
-
- s->busy = timer_pending(s->timer);
- qemu_set_irq(s->pint, !s->irq);
- qemu_set_irq(s->davint, !s->dav);
-
- return 0;
-}
-
-uWireSlave *tsc2102_init(qemu_irq pint)
-{
- TSC210xState *s;
-
- s = g_new0(TSC210xState, 1);
- s->x = 160;
- s->y = 160;
- s->pressure = 0;
- s->precision = s->nextprecision = 0;
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
- s->pint = pint;
- s->model = 0x2102;
- s->name = "tsc2102";
-
- s->tr[0] = 0;
- s->tr[1] = 1;
- s->tr[2] = 1;
- s->tr[3] = 0;
- s->tr[4] = 1;
- s->tr[5] = 0;
- s->tr[6] = 1;
- s->tr[7] = 0;
-
- s->chip.opaque = s;
- s->chip.send = (void *) tsc210x_write;
- s->chip.receive = (void *) tsc210x_read;
-
- s->codec.opaque = s;
- s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
- s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
- s->codec.in.fifo = s->in_fifo;
- s->codec.out.fifo = s->out_fifo;
-
- tsc210x_reset(s);
-
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
- "QEMU TSC2102-driven Touchscreen");
-
- AUD_register_card(s->name, &s->card);
-
- qemu_register_reset((void *) tsc210x_reset, s);
- register_savevm(NULL, s->name, -1, 0,
- tsc210x_save, tsc210x_load, s);
-
- return &s->chip;
-}
-
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
-{
- TSC210xState *s;
-
- s = g_new0(TSC210xState, 1);
- s->x = 400;
- s->y = 240;
- s->pressure = 0;
- s->precision = s->nextprecision = 0;
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
- s->pint = penirq;
- s->kbint = kbirq;
- s->davint = dav;
- s->model = 0x2301;
- s->name = "tsc2301";
-
- s->tr[0] = 0;
- s->tr[1] = 1;
- s->tr[2] = 1;
- s->tr[3] = 0;
- s->tr[4] = 1;
- s->tr[5] = 0;
- s->tr[6] = 1;
- s->tr[7] = 0;
-
- s->chip.opaque = s;
- s->chip.send = (void *) tsc210x_write;
- s->chip.receive = (void *) tsc210x_read;
-
- s->codec.opaque = s;
- s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
- s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
- s->codec.in.fifo = s->in_fifo;
- s->codec.out.fifo = s->out_fifo;
-
- tsc210x_reset(s);
-
- qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
- "QEMU TSC2301-driven Touchscreen");
-
- AUD_register_card(s->name, &s->card);
-
- qemu_register_reset((void *) tsc210x_reset, s);
- register_savevm(NULL, s->name, -1, 0, tsc210x_save, tsc210x_load, s);
-
- return &s->chip;
-}
-
-I2SCodec *tsc210x_codec(uWireSlave *chip)
-{
- TSC210xState *s = (TSC210xState *) chip->opaque;
-
- return &s->codec;
-}
-
-/*
- * Use tslib generated calibration data to generate ADC input values
- * from the touchscreen. Assuming 12-bit precision was used during
- * tslib calibration.
- */
-void tsc210x_set_transform(uWireSlave *chip,
- MouseTransformInfo *info)
-{
- TSC210xState *s = (TSC210xState *) chip->opaque;
-#if 0
- int64_t ltr[8];
-
- ltr[0] = (int64_t) info->a[1] * info->y;
- ltr[1] = (int64_t) info->a[4] * info->x;
- ltr[2] = (int64_t) info->a[1] * info->a[3] -
- (int64_t) info->a[4] * info->a[0];
- ltr[3] = (int64_t) info->a[2] * info->a[4] -
- (int64_t) info->a[5] * info->a[1];
- ltr[4] = (int64_t) info->a[0] * info->y;
- ltr[5] = (int64_t) info->a[3] * info->x;
- ltr[6] = (int64_t) info->a[4] * info->a[0] -
- (int64_t) info->a[1] * info->a[3];
- ltr[7] = (int64_t) info->a[2] * info->a[3] -
- (int64_t) info->a[5] * info->a[0];
-
- /* Avoid integer overflow */
- s->tr[0] = ltr[0] >> 11;
- s->tr[1] = ltr[1] >> 11;
- s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
- s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
- s->tr[4] = ltr[4] >> 11;
- s->tr[5] = ltr[5] >> 11;
- s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
- s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
-#else
-
- /* This version assumes touchscreen X & Y axis are parallel or
- * perpendicular to LCD's X & Y axis in some way. */
- if (abs(info->a[0]) > abs(info->a[1])) {
- s->tr[0] = 0;
- s->tr[1] = -info->a[6] * info->x;
- s->tr[2] = info->a[0];
- s->tr[3] = -info->a[2] / info->a[0];
- s->tr[4] = info->a[6] * info->y;
- s->tr[5] = 0;
- s->tr[6] = info->a[4];
- s->tr[7] = -info->a[5] / info->a[4];
- } else {
- s->tr[0] = info->a[6] * info->y;
- s->tr[1] = 0;
- s->tr[2] = info->a[1];
- s->tr[3] = -info->a[2] / info->a[1];
- s->tr[4] = 0;
- s->tr[5] = -info->a[6] * info->x;
- s->tr[6] = info->a[3];
- s->tr[7] = -info->a[5] / info->a[3];
- }
-
- s->tr[0] >>= 11;
- s->tr[1] >>= 11;
- s->tr[3] <<= 4;
- s->tr[4] >>= 11;
- s->tr[5] >>= 11;
- s->tr[7] <<= 4;
-#endif
-}
-
-void tsc210x_key_event(uWireSlave *chip, int key, int down)
-{
- TSC210xState *s = (TSC210xState *) chip->opaque;
-
- if (down)
- s->kb.down |= 1 << key;
- else
- s->kb.down &= ~(1 << key);
-
- if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
- s->kb.intr = 1;
- qemu_irq_lower(s->kbint);
- } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
- !(s->kb.mode & 1)) {
- s->kb.intr = 0;
- qemu_irq_raise(s->kbint);
- }
-}
diff --git a/qemu/hw/input/virtio-input-hid.c b/qemu/hw/input/virtio-input-hid.c
deleted file mode 100644
index 3ee0c1814..000000000
--- a/qemu/hw/input/virtio-input-hid.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * (at your option) any later version. See the COPYING file in the
- * top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/iov.h"
-
-#include "hw/qdev.h"
-#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-input.h"
-
-#undef CONFIG_CURSES
-#include "ui/console.h"
-
-#include "standard-headers/linux/input.h"
-
-#define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
-#define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
-#define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
-
-/* ----------------------------------------------------------------- */
-
-static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = {
- [Q_KEY_CODE_ESC] = KEY_ESC,
- [Q_KEY_CODE_1] = KEY_1,
- [Q_KEY_CODE_2] = KEY_2,
- [Q_KEY_CODE_3] = KEY_3,
- [Q_KEY_CODE_4] = KEY_4,
- [Q_KEY_CODE_5] = KEY_5,
- [Q_KEY_CODE_6] = KEY_6,
- [Q_KEY_CODE_7] = KEY_7,
- [Q_KEY_CODE_8] = KEY_8,
- [Q_KEY_CODE_9] = KEY_9,
- [Q_KEY_CODE_0] = KEY_0,
- [Q_KEY_CODE_MINUS] = KEY_MINUS,
- [Q_KEY_CODE_EQUAL] = KEY_EQUAL,
- [Q_KEY_CODE_BACKSPACE] = KEY_BACKSPACE,
-
- [Q_KEY_CODE_TAB] = KEY_TAB,
- [Q_KEY_CODE_Q] = KEY_Q,
- [Q_KEY_CODE_W] = KEY_W,
- [Q_KEY_CODE_E] = KEY_E,
- [Q_KEY_CODE_R] = KEY_R,
- [Q_KEY_CODE_T] = KEY_T,
- [Q_KEY_CODE_Y] = KEY_Y,
- [Q_KEY_CODE_U] = KEY_U,
- [Q_KEY_CODE_I] = KEY_I,
- [Q_KEY_CODE_O] = KEY_O,
- [Q_KEY_CODE_P] = KEY_P,
- [Q_KEY_CODE_BRACKET_LEFT] = KEY_LEFTBRACE,
- [Q_KEY_CODE_BRACKET_RIGHT] = KEY_RIGHTBRACE,
- [Q_KEY_CODE_RET] = KEY_ENTER,
-
- [Q_KEY_CODE_CTRL] = KEY_LEFTCTRL,
- [Q_KEY_CODE_A] = KEY_A,
- [Q_KEY_CODE_S] = KEY_S,
- [Q_KEY_CODE_D] = KEY_D,
- [Q_KEY_CODE_F] = KEY_F,
- [Q_KEY_CODE_G] = KEY_G,
- [Q_KEY_CODE_H] = KEY_H,
- [Q_KEY_CODE_J] = KEY_J,
- [Q_KEY_CODE_K] = KEY_K,
- [Q_KEY_CODE_L] = KEY_L,
- [Q_KEY_CODE_SEMICOLON] = KEY_SEMICOLON,
- [Q_KEY_CODE_APOSTROPHE] = KEY_APOSTROPHE,
- [Q_KEY_CODE_GRAVE_ACCENT] = KEY_GRAVE,
-
- [Q_KEY_CODE_SHIFT] = KEY_LEFTSHIFT,
- [Q_KEY_CODE_BACKSLASH] = KEY_BACKSLASH,
- [Q_KEY_CODE_LESS] = KEY_102ND,
- [Q_KEY_CODE_Z] = KEY_Z,
- [Q_KEY_CODE_X] = KEY_X,
- [Q_KEY_CODE_C] = KEY_C,
- [Q_KEY_CODE_V] = KEY_V,
- [Q_KEY_CODE_B] = KEY_B,
- [Q_KEY_CODE_N] = KEY_N,
- [Q_KEY_CODE_M] = KEY_M,
- [Q_KEY_CODE_COMMA] = KEY_COMMA,
- [Q_KEY_CODE_DOT] = KEY_DOT,
- [Q_KEY_CODE_SLASH] = KEY_SLASH,
- [Q_KEY_CODE_SHIFT_R] = KEY_RIGHTSHIFT,
-
- [Q_KEY_CODE_ALT] = KEY_LEFTALT,
- [Q_KEY_CODE_SPC] = KEY_SPACE,
- [Q_KEY_CODE_CAPS_LOCK] = KEY_CAPSLOCK,
-
- [Q_KEY_CODE_F1] = KEY_F1,
- [Q_KEY_CODE_F2] = KEY_F2,
- [Q_KEY_CODE_F3] = KEY_F3,
- [Q_KEY_CODE_F4] = KEY_F4,
- [Q_KEY_CODE_F5] = KEY_F5,
- [Q_KEY_CODE_F6] = KEY_F6,
- [Q_KEY_CODE_F7] = KEY_F7,
- [Q_KEY_CODE_F8] = KEY_F8,
- [Q_KEY_CODE_F9] = KEY_F9,
- [Q_KEY_CODE_F10] = KEY_F10,
- [Q_KEY_CODE_NUM_LOCK] = KEY_NUMLOCK,
- [Q_KEY_CODE_SCROLL_LOCK] = KEY_SCROLLLOCK,
-
- [Q_KEY_CODE_KP_0] = KEY_KP0,
- [Q_KEY_CODE_KP_1] = KEY_KP1,
- [Q_KEY_CODE_KP_2] = KEY_KP2,
- [Q_KEY_CODE_KP_3] = KEY_KP3,
- [Q_KEY_CODE_KP_4] = KEY_KP4,
- [Q_KEY_CODE_KP_5] = KEY_KP5,
- [Q_KEY_CODE_KP_6] = KEY_KP6,
- [Q_KEY_CODE_KP_7] = KEY_KP7,
- [Q_KEY_CODE_KP_8] = KEY_KP8,
- [Q_KEY_CODE_KP_9] = KEY_KP9,
- [Q_KEY_CODE_KP_SUBTRACT] = KEY_KPMINUS,
- [Q_KEY_CODE_KP_ADD] = KEY_KPPLUS,
- [Q_KEY_CODE_KP_DECIMAL] = KEY_KPDOT,
- [Q_KEY_CODE_KP_ENTER] = KEY_KPENTER,
- [Q_KEY_CODE_KP_DIVIDE] = KEY_KPSLASH,
- [Q_KEY_CODE_KP_MULTIPLY] = KEY_KPASTERISK,
-
- [Q_KEY_CODE_F11] = KEY_F11,
- [Q_KEY_CODE_F12] = KEY_F12,
-
- [Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL,
- [Q_KEY_CODE_SYSRQ] = KEY_SYSRQ,
- [Q_KEY_CODE_PRINT] = KEY_SYSRQ,
- [Q_KEY_CODE_PAUSE] = KEY_PAUSE,
- [Q_KEY_CODE_ALT_R] = KEY_RIGHTALT,
-
- [Q_KEY_CODE_HOME] = KEY_HOME,
- [Q_KEY_CODE_UP] = KEY_UP,
- [Q_KEY_CODE_PGUP] = KEY_PAGEUP,
- [Q_KEY_CODE_LEFT] = KEY_LEFT,
- [Q_KEY_CODE_RIGHT] = KEY_RIGHT,
- [Q_KEY_CODE_END] = KEY_END,
- [Q_KEY_CODE_DOWN] = KEY_DOWN,
- [Q_KEY_CODE_PGDN] = KEY_PAGEDOWN,
- [Q_KEY_CODE_INSERT] = KEY_INSERT,
- [Q_KEY_CODE_DELETE] = KEY_DELETE,
-
- [Q_KEY_CODE_META_L] = KEY_LEFTMETA,
- [Q_KEY_CODE_META_R] = KEY_RIGHTMETA,
- [Q_KEY_CODE_MENU] = KEY_MENU,
-};
-
-static const unsigned int keymap_button[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = BTN_LEFT,
- [INPUT_BUTTON_RIGHT] = BTN_RIGHT,
- [INPUT_BUTTON_MIDDLE] = BTN_MIDDLE,
- [INPUT_BUTTON_WHEEL_UP] = BTN_GEAR_UP,
- [INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN,
-};
-
-static const unsigned int axismap_rel[INPUT_AXIS__MAX] = {
- [INPUT_AXIS_X] = REL_X,
- [INPUT_AXIS_Y] = REL_Y,
-};
-
-static const unsigned int axismap_abs[INPUT_AXIS__MAX] = {
- [INPUT_AXIS_X] = ABS_X,
- [INPUT_AXIS_Y] = ABS_Y,
-};
-
-/* ----------------------------------------------------------------- */
-
-static void virtio_input_key_config(VirtIOInput *vinput,
- const unsigned int *keymap,
- size_t mapsize)
-{
- virtio_input_config keys;
- int i, bit, byte, bmax = 0;
-
- memset(&keys, 0, sizeof(keys));
- for (i = 0; i < mapsize; i++) {
- bit = keymap[i];
- if (!bit) {
- continue;
- }
- byte = bit / 8;
- bit = bit % 8;
- keys.u.bitmap[byte] |= (1 << bit);
- if (bmax < byte+1) {
- bmax = byte+1;
- }
- }
- keys.select = VIRTIO_INPUT_CFG_EV_BITS;
- keys.subsel = EV_KEY;
- keys.size = bmax;
- virtio_input_add_config(vinput, &keys);
-}
-
-static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- VirtIOInput *vinput = VIRTIO_INPUT(dev);
- virtio_input_event event;
- int qcode;
- InputKeyEvent *key;
- InputMoveEvent *move;
- InputBtnEvent *btn;
-
- switch (evt->type) {
- case INPUT_EVENT_KIND_KEY:
- key = evt->u.key.data;
- qcode = qemu_input_key_value_to_qcode(key->key);
- if (qcode && keymap_qcode[qcode]) {
- event.type = cpu_to_le16(EV_KEY);
- event.code = cpu_to_le16(keymap_qcode[qcode]);
- event.value = cpu_to_le32(key->down ? 1 : 0);
- virtio_input_send(vinput, &event);
- } else {
- if (key->down) {
- fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,
- qcode, QKeyCode_lookup[qcode]);
- }
- }
- break;
- case INPUT_EVENT_KIND_BTN:
- btn = evt->u.btn.data;
- if (keymap_button[btn->button]) {
- event.type = cpu_to_le16(EV_KEY);
- event.code = cpu_to_le16(keymap_button[btn->button]);
- event.value = cpu_to_le32(btn->down ? 1 : 0);
- virtio_input_send(vinput, &event);
- } else {
- if (btn->down) {
- fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,
- btn->button,
- InputButton_lookup[btn->button]);
- }
- }
- break;
- case INPUT_EVENT_KIND_REL:
- move = evt->u.rel.data;
- event.type = cpu_to_le16(EV_REL);
- event.code = cpu_to_le16(axismap_rel[move->axis]);
- event.value = cpu_to_le32(move->value);
- virtio_input_send(vinput, &event);
- break;
- case INPUT_EVENT_KIND_ABS:
- move = evt->u.abs.data;
- event.type = cpu_to_le16(EV_ABS);
- event.code = cpu_to_le16(axismap_abs[move->axis]);
- event.value = cpu_to_le32(move->value);
- virtio_input_send(vinput, &event);
- break;
- default:
- /* keep gcc happy */
- break;
- }
-}
-
-static void virtio_input_handle_sync(DeviceState *dev)
-{
- VirtIOInput *vinput = VIRTIO_INPUT(dev);
- virtio_input_event event = {
- .type = cpu_to_le16(EV_SYN),
- .code = cpu_to_le16(SYN_REPORT),
- .value = 0,
- };
-
- virtio_input_send(vinput, &event);
-}
-
-static void virtio_input_hid_realize(DeviceState *dev, Error **errp)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
-
- vhid->hs = qemu_input_handler_register(dev, vhid->handler);
- if (vhid->display && vhid->hs) {
- qemu_input_handler_bind(vhid->hs, vhid->display, vhid->head, NULL);
- }
-}
-
-static void virtio_input_hid_unrealize(DeviceState *dev, Error **errp)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
- qemu_input_handler_unregister(vhid->hs);
-}
-
-static void virtio_input_hid_change_active(VirtIOInput *vinput)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
-
- if (vinput->active) {
- qemu_input_handler_activate(vhid->hs);
- } else {
- qemu_input_handler_deactivate(vhid->hs);
- }
-}
-
-static void virtio_input_hid_handle_status(VirtIOInput *vinput,
- virtio_input_event *event)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
- int ledbit = 0;
-
- switch (le16_to_cpu(event->type)) {
- case EV_LED:
- if (event->code == LED_NUML) {
- ledbit = QEMU_NUM_LOCK_LED;
- } else if (event->code == LED_CAPSL) {
- ledbit = QEMU_CAPS_LOCK_LED;
- } else if (event->code == LED_SCROLLL) {
- ledbit = QEMU_SCROLL_LOCK_LED;
- }
- if (event->value) {
- vhid->ledstate |= ledbit;
- } else {
- vhid->ledstate &= ~ledbit;
- }
- kbd_put_ledstate(vhid->ledstate);
- break;
- default:
- fprintf(stderr, "%s: unknown type %d\n", __func__,
- le16_to_cpu(event->type));
- break;
- }
-}
-
-static Property virtio_input_hid_properties[] = {
- DEFINE_PROP_STRING("display", VirtIOInputHID, display),
- DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_input_hid_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
-
- dc->props = virtio_input_hid_properties;
- vic->realize = virtio_input_hid_realize;
- vic->unrealize = virtio_input_hid_unrealize;
- vic->change_active = virtio_input_hid_change_active;
- vic->handle_status = virtio_input_hid_handle_status;
-}
-
-static const TypeInfo virtio_input_hid_info = {
- .name = TYPE_VIRTIO_INPUT_HID,
- .parent = TYPE_VIRTIO_INPUT,
- .instance_size = sizeof(VirtIOInputHID),
- .class_init = virtio_input_hid_class_init,
- .abstract = true,
-};
-
-/* ----------------------------------------------------------------- */
-
-static QemuInputHandler virtio_keyboard_handler = {
- .name = VIRTIO_ID_NAME_KEYBOARD,
- .mask = INPUT_EVENT_MASK_KEY,
- .event = virtio_input_handle_event,
- .sync = virtio_input_handle_sync,
-};
-
-static struct virtio_input_config virtio_keyboard_config[] = {
- {
- .select = VIRTIO_INPUT_CFG_ID_NAME,
- .size = sizeof(VIRTIO_ID_NAME_KEYBOARD),
- .u.string = VIRTIO_ID_NAME_KEYBOARD,
- },{
- .select = VIRTIO_INPUT_CFG_ID_DEVIDS,
- .size = sizeof(struct virtio_input_devids),
- .u.ids = {
- .bustype = const_le16(BUS_VIRTUAL),
- .vendor = const_le16(0x0627), /* same we use for usb hid devices */
- .product = const_le16(0x0001),
- .version = const_le16(0x0001),
- },
- },{
- .select = VIRTIO_INPUT_CFG_EV_BITS,
- .subsel = EV_REP,
- .size = 1,
- },{
- .select = VIRTIO_INPUT_CFG_EV_BITS,
- .subsel = EV_LED,
- .size = 1,
- .u.bitmap = {
- (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL),
- },
- },
- { /* end of list */ },
-};
-
-static void virtio_keyboard_init(Object *obj)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
- VirtIOInput *vinput = VIRTIO_INPUT(obj);
-
- vhid->handler = &virtio_keyboard_handler;
- virtio_input_init_config(vinput, virtio_keyboard_config);
- virtio_input_key_config(vinput, keymap_qcode,
- ARRAY_SIZE(keymap_qcode));
-}
-
-static const TypeInfo virtio_keyboard_info = {
- .name = TYPE_VIRTIO_KEYBOARD,
- .parent = TYPE_VIRTIO_INPUT_HID,
- .instance_size = sizeof(VirtIOInputHID),
- .instance_init = virtio_keyboard_init,
-};
-
-/* ----------------------------------------------------------------- */
-
-static QemuInputHandler virtio_mouse_handler = {
- .name = VIRTIO_ID_NAME_MOUSE,
- .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
- .event = virtio_input_handle_event,
- .sync = virtio_input_handle_sync,
-};
-
-static struct virtio_input_config virtio_mouse_config[] = {
- {
- .select = VIRTIO_INPUT_CFG_ID_NAME,
- .size = sizeof(VIRTIO_ID_NAME_MOUSE),
- .u.string = VIRTIO_ID_NAME_MOUSE,
- },{
- .select = VIRTIO_INPUT_CFG_ID_DEVIDS,
- .size = sizeof(struct virtio_input_devids),
- .u.ids = {
- .bustype = const_le16(BUS_VIRTUAL),
- .vendor = const_le16(0x0627), /* same we use for usb hid devices */
- .product = const_le16(0x0002),
- .version = const_le16(0x0001),
- },
- },{
- .select = VIRTIO_INPUT_CFG_EV_BITS,
- .subsel = EV_REL,
- .size = 1,
- .u.bitmap = {
- (1 << REL_X) | (1 << REL_Y),
- },
- },
- { /* end of list */ },
-};
-
-static void virtio_mouse_init(Object *obj)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
- VirtIOInput *vinput = VIRTIO_INPUT(obj);
-
- vhid->handler = &virtio_mouse_handler;
- virtio_input_init_config(vinput, virtio_mouse_config);
- virtio_input_key_config(vinput, keymap_button,
- ARRAY_SIZE(keymap_button));
-}
-
-static const TypeInfo virtio_mouse_info = {
- .name = TYPE_VIRTIO_MOUSE,
- .parent = TYPE_VIRTIO_INPUT_HID,
- .instance_size = sizeof(VirtIOInputHID),
- .instance_init = virtio_mouse_init,
-};
-
-/* ----------------------------------------------------------------- */
-
-static QemuInputHandler virtio_tablet_handler = {
- .name = VIRTIO_ID_NAME_TABLET,
- .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
- .event = virtio_input_handle_event,
- .sync = virtio_input_handle_sync,
-};
-
-static struct virtio_input_config virtio_tablet_config[] = {
- {
- .select = VIRTIO_INPUT_CFG_ID_NAME,
- .size = sizeof(VIRTIO_ID_NAME_TABLET),
- .u.string = VIRTIO_ID_NAME_TABLET,
- },{
- .select = VIRTIO_INPUT_CFG_ID_DEVIDS,
- .size = sizeof(struct virtio_input_devids),
- .u.ids = {
- .bustype = const_le16(BUS_VIRTUAL),
- .vendor = const_le16(0x0627), /* same we use for usb hid devices */
- .product = const_le16(0x0003),
- .version = const_le16(0x0001),
- },
- },{
- .select = VIRTIO_INPUT_CFG_EV_BITS,
- .subsel = EV_ABS,
- .size = 1,
- .u.bitmap = {
- (1 << ABS_X) | (1 << ABS_Y),
- },
- },{
- .select = VIRTIO_INPUT_CFG_ABS_INFO,
- .subsel = ABS_X,
- .size = sizeof(virtio_input_absinfo),
- .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
- },{
- .select = VIRTIO_INPUT_CFG_ABS_INFO,
- .subsel = ABS_Y,
- .size = sizeof(virtio_input_absinfo),
- .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
- },
- { /* end of list */ },
-};
-
-static void virtio_tablet_init(Object *obj)
-{
- VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
- VirtIOInput *vinput = VIRTIO_INPUT(obj);
-
- vhid->handler = &virtio_tablet_handler;
- virtio_input_init_config(vinput, virtio_tablet_config);
- virtio_input_key_config(vinput, keymap_button,
- ARRAY_SIZE(keymap_button));
-}
-
-static const TypeInfo virtio_tablet_info = {
- .name = TYPE_VIRTIO_TABLET,
- .parent = TYPE_VIRTIO_INPUT_HID,
- .instance_size = sizeof(VirtIOInputHID),
- .instance_init = virtio_tablet_init,
-};
-
-/* ----------------------------------------------------------------- */
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_input_hid_info);
- type_register_static(&virtio_keyboard_info);
- type_register_static(&virtio_mouse_info);
- type_register_static(&virtio_tablet_info);
-}
-
-type_init(virtio_register_types)
diff --git a/qemu/hw/input/virtio-input-host.c b/qemu/hw/input/virtio-input-host.c
deleted file mode 100644
index cb79e8002..000000000
--- a/qemu/hw/input/virtio-input-host.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * (at your option) any later version. See the COPYING file in the
- * top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "qemu/sockets.h"
-
-#include "hw/qdev.h"
-#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-input.h"
-
-#include <sys/ioctl.h>
-#include "standard-headers/linux/input.h"
-
-/* ----------------------------------------------------------------- */
-
-static struct virtio_input_config virtio_input_host_config[] = {
- { /* empty list */ },
-};
-
-static void virtio_input_host_event(void *opaque)
-{
- VirtIOInputHost *vih = opaque;
- VirtIOInput *vinput = VIRTIO_INPUT(vih);
- struct virtio_input_event virtio;
- struct input_event evdev;
- int rc;
-
- for (;;) {
- rc = read(vih->fd, &evdev, sizeof(evdev));
- if (rc != sizeof(evdev)) {
- break;
- }
-
- virtio.type = cpu_to_le16(evdev.type);
- virtio.code = cpu_to_le16(evdev.code);
- virtio.value = cpu_to_le32(evdev.value);
- virtio_input_send(vinput, &virtio);
- }
-}
-
-static void virtio_input_bits_config(VirtIOInputHost *vih,
- int type, int count)
-{
- virtio_input_config bits;
- int rc, i, size = 0;
-
- memset(&bits, 0, sizeof(bits));
- rc = ioctl(vih->fd, EVIOCGBIT(type, count/8), bits.u.bitmap);
- if (rc < 0) {
- return;
- }
-
- for (i = 0; i < count/8; i++) {
- if (bits.u.bitmap[i]) {
- size = i+1;
- }
- }
- if (size == 0) {
- return;
- }
-
- bits.select = VIRTIO_INPUT_CFG_EV_BITS;
- bits.subsel = type;
- bits.size = size;
- virtio_input_add_config(VIRTIO_INPUT(vih), &bits);
-}
-
-static void virtio_input_abs_config(VirtIOInputHost *vih, int axis)
-{
- virtio_input_config config;
- struct input_absinfo absinfo;
- int rc;
-
- rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo);
- if (rc < 0) {
- return;
- }
-
- memset(&config, 0, sizeof(config));
- config.select = VIRTIO_INPUT_CFG_ABS_INFO;
- config.subsel = axis;
- config.size = sizeof(virtio_input_absinfo);
-
- config.u.abs.min = cpu_to_le32(absinfo.minimum);
- config.u.abs.max = cpu_to_le32(absinfo.maximum);
- config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz);
- config.u.abs.flat = cpu_to_le32(absinfo.flat);
- config.u.abs.res = cpu_to_le32(absinfo.resolution);
-
- virtio_input_add_config(VIRTIO_INPUT(vih), &config);
-}
-
-static void virtio_input_host_realize(DeviceState *dev, Error **errp)
-{
- VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
- VirtIOInput *vinput = VIRTIO_INPUT(dev);
- virtio_input_config id, *abs;
- struct input_id ids;
- int rc, ver, i, axis;
- uint8_t byte;
-
- if (!vih->evdev) {
- error_setg(errp, "evdev property is required");
- return;
- }
-
- vih->fd = open(vih->evdev, O_RDWR);
- if (vih->fd < 0) {
- error_setg_file_open(errp, errno, vih->evdev);
- return;
- }
- qemu_set_nonblock(vih->fd);
-
- rc = ioctl(vih->fd, EVIOCGVERSION, &ver);
- if (rc < 0) {
- error_setg(errp, "%s: is not an evdev device", vih->evdev);
- goto err_close;
- }
-
- rc = ioctl(vih->fd, EVIOCGRAB, 1);
- if (rc < 0) {
- error_setg_errno(errp, errno, "%s: failed to get exclusive access",
- vih->evdev);
- goto err_close;
- }
-
- memset(&id, 0, sizeof(id));
- ioctl(vih->fd, EVIOCGNAME(sizeof(id.u.string)-1), id.u.string);
- id.select = VIRTIO_INPUT_CFG_ID_NAME;
- id.size = strlen(id.u.string);
- virtio_input_add_config(vinput, &id);
-
- if (ioctl(vih->fd, EVIOCGID, &ids) == 0) {
- memset(&id, 0, sizeof(id));
- id.select = VIRTIO_INPUT_CFG_ID_DEVIDS;
- id.size = sizeof(struct virtio_input_devids);
- id.u.ids.bustype = cpu_to_le16(ids.bustype);
- id.u.ids.vendor = cpu_to_le16(ids.vendor);
- id.u.ids.product = cpu_to_le16(ids.product);
- id.u.ids.version = cpu_to_le16(ids.version);
- virtio_input_add_config(vinput, &id);
- }
-
- virtio_input_bits_config(vih, EV_KEY, KEY_CNT);
- virtio_input_bits_config(vih, EV_REL, REL_CNT);
- virtio_input_bits_config(vih, EV_ABS, ABS_CNT);
- virtio_input_bits_config(vih, EV_MSC, MSC_CNT);
- virtio_input_bits_config(vih, EV_SW, SW_CNT);
- virtio_input_bits_config(vih, EV_LED, LED_CNT);
-
- abs = virtio_input_find_config(VIRTIO_INPUT(vih),
- VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
- if (abs) {
- for (i = 0; i < abs->size; i++) {
- byte = abs->u.bitmap[i];
- axis = 8 * i;
- while (byte) {
- if (byte & 1) {
- virtio_input_abs_config(vih, axis);
- }
- axis++;
- byte >>= 1;
- }
- }
- }
-
- qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih);
- return;
-
-err_close:
- close(vih->fd);
- vih->fd = -1;
- return;
-}
-
-static void virtio_input_host_unrealize(DeviceState *dev, Error **errp)
-{
- VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
-
- if (vih->fd > 0) {
- qemu_set_fd_handler(vih->fd, NULL, NULL, NULL);
- close(vih->fd);
- }
-}
-
-static void virtio_input_host_handle_status(VirtIOInput *vinput,
- virtio_input_event *event)
-{
- VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput);
- struct input_event evdev;
- int rc;
-
- if (gettimeofday(&evdev.time, NULL)) {
- perror("virtio_input_host_handle_status: gettimeofday");
- return;
- }
-
- evdev.type = le16_to_cpu(event->type);
- evdev.code = le16_to_cpu(event->code);
- evdev.value = le32_to_cpu(event->value);
-
- rc = write(vih->fd, &evdev, sizeof(evdev));
- if (rc == -1) {
- perror("virtio_input_host_handle_status: write");
- }
-}
-
-static const VMStateDescription vmstate_virtio_input_host = {
- .name = "virtio-input-host",
- .unmigratable = 1,
-};
-
-static Property virtio_input_host_properties[] = {
- DEFINE_PROP_STRING("evdev", VirtIOInputHost, evdev),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_input_host_class_init(ObjectClass *klass, void *data)
-{
- VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->vmsd = &vmstate_virtio_input_host;
- dc->props = virtio_input_host_properties;
- vic->realize = virtio_input_host_realize;
- vic->unrealize = virtio_input_host_unrealize;
- vic->handle_status = virtio_input_host_handle_status;
-}
-
-static void virtio_input_host_init(Object *obj)
-{
- VirtIOInput *vinput = VIRTIO_INPUT(obj);
-
- virtio_input_init_config(vinput, virtio_input_host_config);
-}
-
-static const TypeInfo virtio_input_host_info = {
- .name = TYPE_VIRTIO_INPUT_HOST,
- .parent = TYPE_VIRTIO_INPUT,
- .instance_size = sizeof(VirtIOInputHost),
- .instance_init = virtio_input_host_init,
- .class_init = virtio_input_host_class_init,
-};
-
-/* ----------------------------------------------------------------- */
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_input_host_info);
-}
-
-type_init(virtio_register_types)
diff --git a/qemu/hw/input/virtio-input.c b/qemu/hw/input/virtio-input.c
deleted file mode 100644
index f59749a94..000000000
--- a/qemu/hw/input/virtio-input.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * (at your option) any later version. See the COPYING file in the
- * top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/iov.h"
-
-#include "hw/qdev.h"
-#include "hw/virtio/virtio.h"
-#include "hw/virtio/virtio-input.h"
-
-#include "standard-headers/linux/input.h"
-
-#define VIRTIO_INPUT_VM_VERSION 1
-
-/* ----------------------------------------------------------------- */
-
-void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
-{
- VirtQueueElement *elem;
- unsigned have, need;
- int i, len;
-
- if (!vinput->active) {
- return;
- }
-
- /* queue up events ... */
- if (vinput->qindex == vinput->qsize) {
- vinput->qsize++;
- vinput->queue = realloc(vinput->queue, vinput->qsize *
- sizeof(virtio_input_event));
- }
- vinput->queue[vinput->qindex++] = *event;
-
- /* ... until we see a report sync ... */
- if (event->type != cpu_to_le16(EV_SYN) ||
- event->code != cpu_to_le16(SYN_REPORT)) {
- return;
- }
-
- /* ... then check available space ... */
- need = sizeof(virtio_input_event) * vinput->qindex;
- virtqueue_get_avail_bytes(vinput->evt, &have, NULL, need, 0);
- if (have < need) {
- vinput->qindex = 0;
- fprintf(stderr, "%s: ENOSPC in vq, dropping events\n", __func__);
- return;
- }
-
- /* ... and finally pass them to the guest */
- for (i = 0; i < vinput->qindex; i++) {
- elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement));
- if (!elem) {
- /* should not happen, we've checked for space beforehand */
- fprintf(stderr, "%s: Huh? No vq elem available ...\n", __func__);
- return;
- }
- len = iov_from_buf(elem->in_sg, elem->in_num,
- 0, vinput->queue+i, sizeof(virtio_input_event));
- virtqueue_push(vinput->evt, elem, len);
- g_free(elem);
- }
- virtio_notify(VIRTIO_DEVICE(vinput), vinput->evt);
- vinput->qindex = 0;
-}
-
-static void virtio_input_handle_evt(VirtIODevice *vdev, VirtQueue *vq)
-{
- /* nothing */
-}
-
-static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
-{
- VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
- VirtIOInput *vinput = VIRTIO_INPUT(vdev);
- virtio_input_event event;
- VirtQueueElement *elem;
- int len;
-
- for (;;) {
- elem = virtqueue_pop(vinput->sts, sizeof(VirtQueueElement));
- if (!elem) {
- break;
- }
-
- memset(&event, 0, sizeof(event));
- len = iov_to_buf(elem->out_sg, elem->out_num,
- 0, &event, sizeof(event));
- if (vic->handle_status) {
- vic->handle_status(vinput, &event);
- }
- virtqueue_push(vinput->sts, elem, len);
- g_free(elem);
- }
- virtio_notify(vdev, vinput->sts);
-}
-
-virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
- uint8_t select,
- uint8_t subsel)
-{
- VirtIOInputConfig *cfg;
-
- QTAILQ_FOREACH(cfg, &vinput->cfg_list, node) {
- if (select == cfg->config.select &&
- subsel == cfg->config.subsel) {
- return &cfg->config;
- }
- }
- return NULL;
-}
-
-void virtio_input_add_config(VirtIOInput *vinput,
- virtio_input_config *config)
-{
- VirtIOInputConfig *cfg;
-
- if (virtio_input_find_config(vinput, config->select, config->subsel)) {
- /* should not happen */
- fprintf(stderr, "%s: duplicate config: %d/%d\n",
- __func__, config->select, config->subsel);
- abort();
- }
-
- cfg = g_new0(VirtIOInputConfig, 1);
- cfg->config = *config;
- QTAILQ_INSERT_TAIL(&vinput->cfg_list, cfg, node);
-}
-
-void virtio_input_init_config(VirtIOInput *vinput,
- virtio_input_config *config)
-{
- int i = 0;
-
- QTAILQ_INIT(&vinput->cfg_list);
- while (config[i].select) {
- virtio_input_add_config(vinput, config + i);
- i++;
- }
-}
-
-void virtio_input_idstr_config(VirtIOInput *vinput,
- uint8_t select, const char *string)
-{
- virtio_input_config id;
-
- if (!string) {
- return;
- }
- memset(&id, 0, sizeof(id));
- id.select = select;
- id.size = snprintf(id.u.string, sizeof(id.u.string), "%s", string);
- virtio_input_add_config(vinput, &id);
-}
-
-static void virtio_input_get_config(VirtIODevice *vdev, uint8_t *config_data)
-{
- VirtIOInput *vinput = VIRTIO_INPUT(vdev);
- virtio_input_config *config;
-
- config = virtio_input_find_config(vinput, vinput->cfg_select,
- vinput->cfg_subsel);
- if (config) {
- memcpy(config_data, config, vinput->cfg_size);
- } else {
- memset(config_data, 0, vinput->cfg_size);
- }
-}
-
-static void virtio_input_set_config(VirtIODevice *vdev,
- const uint8_t *config_data)
-{
- VirtIOInput *vinput = VIRTIO_INPUT(vdev);
- virtio_input_config *config = (virtio_input_config *)config_data;
-
- vinput->cfg_select = config->select;
- vinput->cfg_subsel = config->subsel;
- virtio_notify_config(vdev);
-}
-
-static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f,
- Error **errp)
-{
- return f;
-}
-
-static void virtio_input_set_status(VirtIODevice *vdev, uint8_t val)
-{
- VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
- VirtIOInput *vinput = VIRTIO_INPUT(vdev);
-
- if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
- if (!vinput->active) {
- vinput->active = true;
- if (vic->change_active) {
- vic->change_active(vinput);
- }
- }
- }
-}
-
-static void virtio_input_reset(VirtIODevice *vdev)
-{
- VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
- VirtIOInput *vinput = VIRTIO_INPUT(vdev);
-
- if (vinput->active) {
- vinput->active = false;
- if (vic->change_active) {
- vic->change_active(vinput);
- }
- }
-}
-
-static void virtio_input_save(QEMUFile *f, void *opaque)
-{
- VirtIOInput *vinput = opaque;
- VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
-
- virtio_save(vdev, f);
-}
-
-static int virtio_input_load(QEMUFile *f, void *opaque, int version_id)
-{
- VirtIOInput *vinput = opaque;
- VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput);
- VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
- int ret;
-
- if (version_id != VIRTIO_INPUT_VM_VERSION) {
- return -EINVAL;
- }
-
- ret = virtio_load(vdev, f, version_id);
- if (ret) {
- return ret;
- }
-
- /* post_load() */
- vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK;
- if (vic->change_active) {
- vic->change_active(vinput);
- }
- return 0;
-}
-
-static void virtio_input_device_realize(DeviceState *dev, Error **errp)
-{
- VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- VirtIOInput *vinput = VIRTIO_INPUT(dev);
- VirtIOInputConfig *cfg;
- Error *local_err = NULL;
-
- if (vic->realize) {
- vic->realize(dev, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-
- virtio_input_idstr_config(vinput, VIRTIO_INPUT_CFG_ID_SERIAL,
- vinput->serial);
-
- QTAILQ_FOREACH(cfg, &vinput->cfg_list, node) {
- if (vinput->cfg_size < cfg->config.size) {
- vinput->cfg_size = cfg->config.size;
- }
- }
- vinput->cfg_size += 8;
- assert(vinput->cfg_size <= sizeof(virtio_input_config));
-
- virtio_init(vdev, "virtio-input", VIRTIO_ID_INPUT,
- vinput->cfg_size);
- vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt);
- vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
-
- register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION,
- virtio_input_save, virtio_input_load, vinput);
-}
-
-static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
-{
- VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- VirtIOInput *vinput = VIRTIO_INPUT(dev);
- Error *local_err = NULL;
-
- unregister_savevm(dev, "virtio-input", vinput);
-
- if (vic->unrealize) {
- vic->unrealize(dev, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
- virtio_cleanup(vdev);
-}
-
-static Property virtio_input_properties[] = {
- DEFINE_PROP_STRING("serial", VirtIOInput, serial),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_input_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-
- dc->props = virtio_input_properties;
- set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
- vdc->realize = virtio_input_device_realize;
- vdc->unrealize = virtio_input_device_unrealize;
- vdc->get_config = virtio_input_get_config;
- vdc->set_config = virtio_input_set_config;
- vdc->get_features = virtio_input_get_features;
- vdc->set_status = virtio_input_set_status;
- vdc->reset = virtio_input_reset;
-}
-
-static const TypeInfo virtio_input_info = {
- .name = TYPE_VIRTIO_INPUT,
- .parent = TYPE_VIRTIO_DEVICE,
- .instance_size = sizeof(VirtIOInput),
- .class_size = sizeof(VirtIOInputClass),
- .class_init = virtio_input_class_init,
- .abstract = true,
-};
-
-/* ----------------------------------------------------------------- */
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_input_info);
-}
-
-type_init(virtio_register_types)
diff --git a/qemu/hw/input/vmmouse.c b/qemu/hw/input/vmmouse.c
deleted file mode 100644
index 6d15a887c..000000000
--- a/qemu/hw/input/vmmouse.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * QEMU VMMouse emulation
- *
- * Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "hw/input/ps2.h"
-#include "hw/i386/pc.h"
-#include "hw/qdev.h"
-
-/* debug only vmmouse */
-//#define DEBUG_VMMOUSE
-
-/* VMMouse Commands */
-#define VMMOUSE_GETVERSION 10
-#define VMMOUSE_DATA 39
-#define VMMOUSE_STATUS 40
-#define VMMOUSE_COMMAND 41
-
-#define VMMOUSE_READ_ID 0x45414552
-#define VMMOUSE_DISABLE 0x000000f5
-#define VMMOUSE_REQUEST_RELATIVE 0x4c455252
-#define VMMOUSE_REQUEST_ABSOLUTE 0x53424152
-
-#define VMMOUSE_QUEUE_SIZE 1024
-
-#define VMMOUSE_VERSION 0x3442554a
-
-#ifdef DEBUG_VMMOUSE
-#define DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do { } while (0)
-#endif
-
-#define TYPE_VMMOUSE "vmmouse"
-#define VMMOUSE(obj) OBJECT_CHECK(VMMouseState, (obj), TYPE_VMMOUSE)
-
-typedef struct VMMouseState
-{
- ISADevice parent_obj;
-
- uint32_t queue[VMMOUSE_QUEUE_SIZE];
- int32_t queue_size;
- uint16_t nb_queue;
- uint16_t status;
- uint8_t absolute;
- QEMUPutMouseEntry *entry;
- void *ps2_mouse;
-} VMMouseState;
-
-static uint32_t vmmouse_get_status(VMMouseState *s)
-{
- DPRINTF("vmmouse_get_status()\n");
- return (s->status << 16) | s->nb_queue;
-}
-
-static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_state)
-{
- VMMouseState *s = opaque;
- int buttons = 0;
-
- if (s->nb_queue > (VMMOUSE_QUEUE_SIZE - 4))
- return;
-
- DPRINTF("vmmouse_mouse_event(%d, %d, %d, %d)\n",
- x, y, dz, buttons_state);
-
- if ((buttons_state & MOUSE_EVENT_LBUTTON))
- buttons |= 0x20;
- if ((buttons_state & MOUSE_EVENT_RBUTTON))
- buttons |= 0x10;
- if ((buttons_state & MOUSE_EVENT_MBUTTON))
- buttons |= 0x08;
-
- if (s->absolute) {
- x <<= 1;
- y <<= 1;
- }
-
- s->queue[s->nb_queue++] = buttons;
- s->queue[s->nb_queue++] = x;
- s->queue[s->nb_queue++] = y;
- s->queue[s->nb_queue++] = dz;
-
- /* need to still generate PS2 events to notify driver to
- read from queue */
- i8042_isa_mouse_fake_event(s->ps2_mouse);
-}
-
-static void vmmouse_remove_handler(VMMouseState *s)
-{
- if (s->entry) {
- qemu_remove_mouse_event_handler(s->entry);
- s->entry = NULL;
- }
-}
-
-static void vmmouse_update_handler(VMMouseState *s, int absolute)
-{
- if (s->status != 0) {
- return;
- }
- if (s->absolute != absolute) {
- s->absolute = absolute;
- vmmouse_remove_handler(s);
- }
- if (s->entry == NULL) {
- s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event,
- s, s->absolute,
- "vmmouse");
- qemu_activate_mouse_event_handler(s->entry);
- }
-}
-
-static void vmmouse_read_id(VMMouseState *s)
-{
- DPRINTF("vmmouse_read_id()\n");
-
- if (s->nb_queue == VMMOUSE_QUEUE_SIZE)
- return;
-
- s->queue[s->nb_queue++] = VMMOUSE_VERSION;
- s->status = 0;
-}
-
-static void vmmouse_request_relative(VMMouseState *s)
-{
- DPRINTF("vmmouse_request_relative()\n");
- vmmouse_update_handler(s, 0);
-}
-
-static void vmmouse_request_absolute(VMMouseState *s)
-{
- DPRINTF("vmmouse_request_absolute()\n");
- vmmouse_update_handler(s, 1);
-}
-
-static void vmmouse_disable(VMMouseState *s)
-{
- DPRINTF("vmmouse_disable()\n");
- s->status = 0xffff;
- vmmouse_remove_handler(s);
-}
-
-static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size)
-{
- int i;
-
- DPRINTF("vmmouse_data(%d)\n", size);
-
- if (size == 0 || size > 6 || size > s->nb_queue) {
- printf("vmmouse: driver requested too much data %d\n", size);
- s->status = 0xffff;
- vmmouse_remove_handler(s);
- return;
- }
-
- for (i = 0; i < size; i++)
- data[i] = s->queue[i];
-
- s->nb_queue -= size;
- if (s->nb_queue)
- memmove(s->queue, &s->queue[size], sizeof(s->queue[0]) * s->nb_queue);
-}
-
-static uint32_t vmmouse_ioport_read(void *opaque, uint32_t addr)
-{
- VMMouseState *s = opaque;
- uint32_t data[6];
- uint16_t command;
-
- vmmouse_get_data(data);
-
- command = data[2] & 0xFFFF;
-
- switch (command) {
- case VMMOUSE_STATUS:
- data[0] = vmmouse_get_status(s);
- break;
- case VMMOUSE_COMMAND:
- switch (data[1]) {
- case VMMOUSE_DISABLE:
- vmmouse_disable(s);
- break;
- case VMMOUSE_READ_ID:
- vmmouse_read_id(s);
- break;
- case VMMOUSE_REQUEST_RELATIVE:
- vmmouse_request_relative(s);
- break;
- case VMMOUSE_REQUEST_ABSOLUTE:
- vmmouse_request_absolute(s);
- break;
- default:
- printf("vmmouse: unknown command %x\n", data[1]);
- break;
- }
- break;
- case VMMOUSE_DATA:
- vmmouse_data(s, data, data[1]);
- break;
- default:
- printf("vmmouse: unknown command %x\n", command);
- break;
- }
-
- vmmouse_set_data(data);
- return data[0];
-}
-
-static int vmmouse_post_load(void *opaque, int version_id)
-{
- VMMouseState *s = opaque;
-
- vmmouse_remove_handler(s);
- vmmouse_update_handler(s, s->absolute);
- return 0;
-}
-
-static const VMStateDescription vmstate_vmmouse = {
- .name = "vmmouse",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = vmmouse_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(queue_size, VMMouseState),
- VMSTATE_UINT32_ARRAY(queue, VMMouseState, VMMOUSE_QUEUE_SIZE),
- VMSTATE_UINT16(nb_queue, VMMouseState),
- VMSTATE_UINT16(status, VMMouseState),
- VMSTATE_UINT8(absolute, VMMouseState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void vmmouse_reset(DeviceState *d)
-{
- VMMouseState *s = VMMOUSE(d);
-
- s->queue_size = VMMOUSE_QUEUE_SIZE;
-
- vmmouse_disable(s);
-}
-
-static void vmmouse_realizefn(DeviceState *dev, Error **errp)
-{
- VMMouseState *s = VMMOUSE(dev);
-
- DPRINTF("vmmouse_init\n");
-
- vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s);
- vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s);
- vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s);
-}
-
-static Property vmmouse_properties[] = {
- DEFINE_PROP_PTR("ps2_mouse", VMMouseState, ps2_mouse),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void vmmouse_class_initfn(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = vmmouse_realizefn;
- dc->reset = vmmouse_reset;
- dc->vmsd = &vmstate_vmmouse;
- dc->props = vmmouse_properties;
- /* Reason: pointer property "ps2_mouse" */
- dc->cannot_instantiate_with_device_add_yet = true;
-}
-
-static const TypeInfo vmmouse_info = {
- .name = TYPE_VMMOUSE,
- .parent = TYPE_ISA_DEVICE,
- .instance_size = sizeof(VMMouseState),
- .class_init = vmmouse_class_initfn,
-};
-
-static void vmmouse_register_types(void)
-{
- type_register_static(&vmmouse_info);
-}
-
-type_init(vmmouse_register_types)