summary refs log tree commit diff stats
path: root/hw/input
diff options
context:
space:
mode:
Diffstat (limited to 'hw/input')
-rw-r--r--hw/input/Kconfig13
-rw-r--r--hw/input/ads7846.c186
-rw-r--r--hw/input/lm832x.c528
-rw-r--r--hw/input/meson.build5
-rw-r--r--hw/input/pxa2xx_keypad.c331
-rw-r--r--hw/input/trace-events3
-rw-r--r--hw/input/tsc2005.c571
-rw-r--r--hw/input/tsc210x.c1241
8 files changed, 0 insertions, 2878 deletions
diff --git a/hw/input/Kconfig b/hw/input/Kconfig
index f86e98c829..a116cb82df 100644
--- a/hw/input/Kconfig
+++ b/hw/input/Kconfig
@@ -1,13 +1,6 @@
 config ADB
     bool
 
-config ADS7846
-    bool
-
-config LM832X
-    bool
-    depends on I2C
-
 config PCKBD
     bool
     select PS2
@@ -23,9 +16,6 @@ config PS2
 config STELLARIS_GAMEPAD
     bool
 
-config TSC2005
-    bool
-
 config VIRTIO_INPUT
     bool
     default y
@@ -41,8 +31,5 @@ config VHOST_USER_INPUT
     default y
     depends on VIRTIO_INPUT && VHOST_USER
 
-config TSC210X
-    bool
-
 config LASIPS2
     select PS2
diff --git a/hw/input/ads7846.c b/hw/input/ads7846.c
deleted file mode 100644
index cde3892216..0000000000
--- a/hw/input/ads7846.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * TI ADS7846 / TSC2046 chip emulation.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- *
- * 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/irq.h"
-#include "hw/ssi/ssi.h"
-#include "migration/vmstate.h"
-#include "qemu/module.h"
-#include "ui/console.h"
-#include "qom/object.h"
-
-struct ADS7846State {
-    SSIPeripheral ssidev;
-    qemu_irq interrupt;
-
-    int input[8];
-    int pressure;
-    int noise;
-
-    int cycle;
-    int output;
-};
-
-#define TYPE_ADS7846 "ads7846"
-OBJECT_DECLARE_SIMPLE_TYPE(ADS7846State, ADS7846)
-
-/* Control-byte bitfields */
-#define CB_PD0          (1 << 0)
-#define CB_PD1          (1 << 1)
-#define CB_SER          (1 << 2)
-#define CB_MODE         (1 << 3)
-#define CB_A0           (1 << 4)
-#define CB_A1           (1 << 5)
-#define CB_A2           (1 << 6)
-#define CB_START        (1 << 7)
-
-#define X_AXIS_DMAX     3470
-#define X_AXIS_MIN      290
-#define Y_AXIS_DMAX     3450
-#define Y_AXIS_MIN      200
-
-#define ADS_VBAT        2000
-#define ADS_VAUX        2000
-#define ADS_TEMP0       2000
-#define ADS_TEMP1       3000
-#define ADS_XPOS(x, y)  (X_AXIS_MIN + ((X_AXIS_DMAX * (x)) >> 15))
-#define ADS_YPOS(x, y)  (Y_AXIS_MIN + ((Y_AXIS_DMAX * (y)) >> 15))
-#define ADS_Z1POS(x, y) 600
-#define ADS_Z2POS(x, y) (600 + 6000 / ADS_XPOS(x, y))
-
-static void ads7846_int_update(ADS7846State *s)
-{
-    if (s->interrupt)
-        qemu_set_irq(s->interrupt, s->pressure == 0);
-}
-
-static uint32_t ads7846_transfer(SSIPeripheral *dev, uint32_t value)
-{
-    ADS7846State *s = ADS7846(dev);
-
-    switch (s->cycle ++) {
-    case 0:
-        if (!(value & CB_START)) {
-            s->cycle = 0;
-            break;
-        }
-
-        s->output = s->input[(value >> 4) & 7];
-
-        /* Imitate the ADC noise, some drivers expect this.  */
-        s->noise = (s->noise + 3) & 7;
-        switch ((value >> 4) & 7) {
-        case 1: s->output += s->noise ^ 2; break;
-        case 3: s->output += s->noise ^ 0; break;
-        case 4: s->output += s->noise ^ 7; break;
-        case 5: s->output += s->noise ^ 5; break;
-        }
-
-        if (value & CB_MODE)
-            s->output >>= 4;    /* 8 bits instead of 12 */
-
-        break;
-    case 1:
-        s->cycle = 0;
-        break;
-    }
-    return s->output;
-}
-
-static void ads7846_ts_event(void *opaque,
-                int x, int y, int z, int buttons_state)
-{
-    ADS7846State *s = opaque;
-
-    if (buttons_state) {
-        x = 0x7fff - x;
-        s->input[1] = ADS_XPOS(x, y);
-        s->input[3] = ADS_Z1POS(x, y);
-        s->input[4] = ADS_Z2POS(x, y);
-        s->input[5] = ADS_YPOS(x, y);
-    }
-
-    if (s->pressure == !buttons_state) {
-        s->pressure = !!buttons_state;
-
-        ads7846_int_update(s);
-    }
-}
-
-static int ads7856_post_load(void *opaque, int version_id)
-{
-    ADS7846State *s = opaque;
-
-    s->pressure = 0;
-    ads7846_int_update(s);
-    return 0;
-}
-
-static const VMStateDescription vmstate_ads7846 = {
-    .name = "ads7846",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .post_load = ads7856_post_load,
-    .fields = (const VMStateField[]) {
-        VMSTATE_SSI_PERIPHERAL(ssidev, ADS7846State),
-        VMSTATE_INT32_ARRAY(input, ADS7846State, 8),
-        VMSTATE_INT32(noise, ADS7846State),
-        VMSTATE_INT32(cycle, ADS7846State),
-        VMSTATE_INT32(output, ADS7846State),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void ads7846_realize(SSIPeripheral *d, Error **errp)
-{
-    DeviceState *dev = DEVICE(d);
-    ADS7846State *s = ADS7846(d);
-
-    qdev_init_gpio_out(dev, &s->interrupt, 1);
-
-    s->input[0] = ADS_TEMP0;    /* TEMP0 */
-    s->input[2] = ADS_VBAT;     /* VBAT */
-    s->input[6] = ADS_VAUX;     /* VAUX */
-    s->input[7] = ADS_TEMP1;    /* TEMP1 */
-
-    /* We want absolute coordinates */
-    qemu_add_mouse_event_handler(ads7846_ts_event, s, 1,
-                    "QEMU ADS7846-driven Touchscreen");
-
-    ads7846_int_update(s);
-
-    vmstate_register_any(NULL, &vmstate_ads7846, s);
-}
-
-static void ads7846_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
-
-    k->realize = ads7846_realize;
-    k->transfer = ads7846_transfer;
-    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
-}
-
-static const TypeInfo ads7846_info = {
-    .name          = TYPE_ADS7846,
-    .parent        = TYPE_SSI_PERIPHERAL,
-    .instance_size = sizeof(ADS7846State),
-    .class_init    = ads7846_class_init,
-};
-
-static void ads7846_register_types(void)
-{
-    type_register_static(&ads7846_info);
-}
-
-type_init(ads7846_register_types)
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
deleted file mode 100644
index ef65ad18b8..0000000000
--- a/hw/input/lm832x.c
+++ /dev/null
@@ -1,528 +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/input/lm832x.h"
-#include "hw/i2c/i2c.h"
-#include "hw/irq.h"
-#include "migration/vmstate.h"
-#include "qemu/module.h"
-#include "qemu/timer.h"
-#include "ui/console.h"
-#include "qom/object.h"
-
-OBJECT_DECLARE_SIMPLE_TYPE(LM823KbdState, LM8323)
-
-struct LM823KbdState {
-    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;
-};
-
-#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(DeviceState *dev)
-{
-    LM823KbdState *s = LM8323(dev);
-
-    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", __func__, 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(DEVICE(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",
-                            __func__);
-        }
-        /* 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", __func__, reg);
-        break;
-    }
-}
-
-static int 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;
-    }
-
-    return 0;
-}
-
-static uint8_t 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 = (const 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 void lm8323_realize(DeviceState *dev, Error **errp)
-{
-    LM823KbdState *s = LM8323(dev);
-
-    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(dev, &s->nirq, 1);
-}
-
-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);
-
-    device_class_set_legacy_reset(dc, lm_kbd_reset);
-    dc->realize = lm8323_realize;
-    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/hw/input/meson.build b/hw/input/meson.build
index 3cc8ab85f0..90a214962c 100644
--- a/hw/input/meson.build
+++ b/hw/input/meson.build
@@ -1,17 +1,12 @@
 system_ss.add(files('hid.c'))
 system_ss.add(when: 'CONFIG_ADB', if_true: files('adb.c', 'adb-mouse.c', 'adb-kbd.c'))
-system_ss.add(when: 'CONFIG_ADS7846', if_true: files('ads7846.c'))
-system_ss.add(when: 'CONFIG_LM832X', if_true: files('lm832x.c'))
 system_ss.add(when: 'CONFIG_PCKBD', if_true: files('pckbd.c'))
 system_ss.add(when: 'CONFIG_PL050', if_true: files('pl050.c'))
 system_ss.add(when: 'CONFIG_PS2', if_true: files('ps2.c'))
 system_ss.add(when: 'CONFIG_STELLARIS_GAMEPAD', if_true: files('stellaris_gamepad.c'))
-system_ss.add(when: 'CONFIG_TSC2005', if_true: files('tsc2005.c'))
 
 system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input.c'))
 system_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input-hid.c'))
 system_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: files('virtio-input-host.c'))
 
-system_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_keypad.c'))
-system_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c'))
 system_ss.add(when: 'CONFIG_LASIPS2', if_true: files('lasips2.c'))
diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
deleted file mode 100644
index 3858648d9f..0000000000
--- a/hw/input/pxa2xx_keypad.c
+++ /dev/null
@@ -1,331 +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 "qemu/log.h"
-#include "hw/irq.h"
-#include "migration/vmstate.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;
-    case KPDK:
-        return s->kpdk;
-    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;
-    case KPMK:
-        tmp = s->kpmk;
-        if(tmp & KPMK_MKP)
-            s->kpmk &= ~(KPMK_MKP);
-        return tmp;
-    case KPAS:
-        return s->kpas;
-    case KPASMKP0:
-        return s->kpasmkp[0];
-    case KPASMKP1:
-        return s->kpasmkp[1];
-    case KPASMKP2:
-        return s->kpasmkp[2];
-    case KPASMKP3:
-        return s->kpasmkp[3];
-    case KPKDI:
-        return s->kpkdi;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
-                      __func__, 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:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
-                      __func__, 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 = (const 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 = g_new0(PXA2xxKeyPadState, 1);
-    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", __func__);
-        exit(-1);
-    }
-
-    kp->map = map;
-    qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
-}
diff --git a/hw/input/trace-events b/hw/input/trace-events
index 29001a827d..1484625565 100644
--- a/hw/input/trace-events
+++ b/hw/input/trace-events
@@ -46,9 +46,6 @@ ps2_mouse_reset(void *opaque) "%p"
 hid_kbd_queue_full(void) "queue full"
 hid_kbd_queue_empty(void) "queue empty"
 
-# tsc2005.c
-tsc2005_sense(const char *state) "touchscreen sense %s"
-
 # virtio-input.c
 virtio_input_queue_full(void) "queue full"
 
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
deleted file mode 100644
index 54a15d2441..0000000000
--- a/hw/input/tsc2005.c
+++ /dev/null
@@ -1,571 +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 "qemu/log.h"
-#include "qemu/timer.h"
-#include "sysemu/reset.h"
-#include "ui/console.h"
-#include "hw/input/tsc2xxx.h"
-#include "hw/irq.h"
-#include "migration/vmstate.h"
-#include "trace.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;
-
-    int32_t x, y;
-    bool pressure;
-
-    uint8_t reg, state;
-    bool irq, command;
-    uint16_t data, dav;
-
-    bool busy;
-    bool enabled;
-    bool host_mode;
-    int8_t function;
-    int8_t nextfunction;
-    bool precision;
-    bool nextprecision;
-    uint16_t filter;
-    uint8_t pin_func;
-    uint16_t timing[2];
-    uint8_t noise;
-    bool reset;
-    bool pdst;
-    bool pnd0;
-    uint16_t temp_thr[2];
-    uint16_t aux_thr[2];
-
-    int32_t 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 = true;
-        return ret;
-
-    case 0x8: /* AUX high threshold */
-        return s->aux_thr[1];
-    case 0x9: /* AUX low threshold */
-        return s->aux_thr[0];
-
-    case 0xa: /* TEMP high threshold */
-        return s->temp_thr[1];
-    case 0xb: /* TEMP low threshold */
-        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 threshold */
-        s->aux_thr[1] = data;
-        break;
-    case 0x9:   /* AUX low threshold */
-        s->aux_thr[0] = data;
-        break;
-
-    case 0xa:   /* TEMP high threshold */
-        s->temp_thr[1] = data;
-        break;
-    case 0xb:   /* TEMP low threshold */
-        s->temp_thr[0] = data;
-        break;
-
-    case 0xc: /* CFR0 */
-        s->host_mode = (data >> 15) != 0;
-        if (s->enabled != !(data & 0x4000)) {
-            s->enabled = !(data & 0x4000);
-            trace_tsc2005_sense(s->enabled ? "enabled" : "disabled");
-            if (s->busy && !s->enabled) {
-                timer_del(s->timer);
-            }
-            s->busy = s->busy && s->enabled;
-        }
-        s->nextprecision = (data >> 13) & 1;
-        s->timing[0] = data & 0x1fff;
-        if ((s->timing[0] >> 11) == 3) {
-            qemu_log_mask(LOG_GUEST_ERROR,
-                          "tsc2005_write: illegal conversion clock setting\n");
-        }
-        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:
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: write into read-only register 0x%x\n",
-                      __func__, reg);
-    }
-}
-
-/* This handles most of the chip's logic.  */
-static void tsc2005_pin_update(TSC2005State *s)
-{
-    int64_t expires;
-    bool 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 = false;
-        }
-        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 = false;
-        }
-        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 = true;
-    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 = false;
-    s->busy = false;
-    s->nextprecision = false;
-    s->nextfunction = 0;
-    s->timing[0] = 0;
-    s->timing[1] = 0;
-    s->irq = false;
-    s->dav = 0;
-    s->reset = false;
-    s->pdst = true;
-    s->pnd0 = false;
-    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);
-                    trace_tsc2005_sense(s->enabled ? "enabled" : "disabled");
-                    if (s->busy && !s->enabled) {
-                        timer_del(s->timer);
-                    }
-                    s->busy = 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;
-    unsigned int function = s->function;
-
-    assert(function < ARRAY_SIZE(mode_regs));
-
-    /* Timer ticked -- a set of conversions has been finished.  */
-
-    if (!s->busy) {
-        return;
-    }
-
-    s->busy = false;
-    s->dav |= mode_regs[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 int tsc2005_post_load(void *opaque, int version_id)
-{
-    TSC2005State *s = (TSC2005State *) opaque;
-
-    s->busy = timer_pending(s->timer);
-    tsc2005_pin_update(s);
-
-    return 0;
-}
-
-static const VMStateDescription vmstate_tsc2005 = {
-    .name = "tsc2005",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .post_load = tsc2005_post_load,
-    .fields = (const VMStateField []) {
-        VMSTATE_BOOL(pressure, TSC2005State),
-        VMSTATE_BOOL(irq, TSC2005State),
-        VMSTATE_BOOL(command, TSC2005State),
-        VMSTATE_BOOL(enabled, TSC2005State),
-        VMSTATE_BOOL(host_mode, TSC2005State),
-        VMSTATE_BOOL(reset, TSC2005State),
-        VMSTATE_BOOL(pdst, TSC2005State),
-        VMSTATE_BOOL(pnd0, TSC2005State),
-        VMSTATE_BOOL(precision, TSC2005State),
-        VMSTATE_BOOL(nextprecision, TSC2005State),
-        VMSTATE_UINT8(reg, TSC2005State),
-        VMSTATE_UINT8(state, TSC2005State),
-        VMSTATE_UINT16(data, TSC2005State),
-        VMSTATE_UINT16(dav, TSC2005State),
-        VMSTATE_UINT16(filter, TSC2005State),
-        VMSTATE_INT8(nextfunction, TSC2005State),
-        VMSTATE_INT8(function, TSC2005State),
-        VMSTATE_INT32(x, TSC2005State),
-        VMSTATE_INT32(y, TSC2005State),
-        VMSTATE_TIMER_PTR(timer, TSC2005State),
-        VMSTATE_UINT8(pin_func, TSC2005State),
-        VMSTATE_UINT16_ARRAY(timing, TSC2005State, 2),
-        VMSTATE_UINT8(noise, TSC2005State),
-        VMSTATE_UINT16_ARRAY(temp_thr, TSC2005State, 2),
-        VMSTATE_UINT16_ARRAY(aux_thr, TSC2005State, 2),
-        VMSTATE_INT32_ARRAY(tr, TSC2005State, 8),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-void *tsc2005_init(qemu_irq pintdav)
-{
-    TSC2005State *s;
-
-    s = g_new0(TSC2005State, 1);
-    s->x = 400;
-    s->y = 240;
-    s->pressure = false;
-    s->precision = s->nextprecision = false;
-    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);
-    vmstate_register(NULL, 0, &vmstate_tsc2005, 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, const 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/hw/input/tsc210x.c b/hw/input/tsc210x.c
deleted file mode 100644
index c4e32c7a42..0000000000
--- a/hw/input/tsc210x.c
+++ /dev/null
@@ -1,1241 +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 "qemu/log.h"
-#include "sysemu/reset.h"
-#include "ui/console.h"
-#include "hw/arm/omap.h"            /* For I2SCodec */
-#include "hw/boards.h"              /* for current_machine */
-#include "hw/input/tsc2xxx.h"
-#include "hw/irq.h"
-#include "migration/vmstate.h"
-#include "qapi/error.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;
-
-    int32_t x, y;
-    bool pressure;
-
-    uint8_t page, offset;
-    uint16_t dav;
-
-    bool state;
-    bool irq;
-    bool command;
-    bool busy;
-    bool enabled;
-    bool host_mode;
-    uint8_t function, nextfunction;
-    uint8_t precision, nextprecision;
-    uint8_t filter;
-    uint8_t pin_func;
-    uint8_t ref;
-    uint8_t timing;
-    uint8_t noise;
-
-    uint16_t audio_ctrl1;
-    uint16_t audio_ctrl2;
-    uint16_t audio_ctrl3;
-    uint16_t pll[3];
-    uint16_t volume;
-    int64_t volume_change;
-    bool 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;
-    int64_t now; /* Time at migration */
-} 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 = false;
-    s->pin_func = 2;
-    s->enabled = false;
-    s->busy = false;
-    s->nextfunction = 0;
-    s->ref = 0;
-    s->timing = 0;
-    s->irq = false;
-    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 = true;
-    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", __func__);
-        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 = AUDIO_FORMAT_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:
-        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_data_register_write: "
-                                       "no such register: 0x%02x\n", reg);
-    }
-}
-
-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->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:
-        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_control_register_write: "
-                                       "no such register: 0x%02x\n", reg);
-    }
-}
-
-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:
-        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_audio_register_write: "
-                                       "no such register: 0x%02x\n", reg);
-    }
-}
-
-/* This handles most of the chip logic.  */
-static void tsc210x_pin_update(TSC210xState *s)
-{
-    int64_t expires;
-    bool 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 = false;
-
-    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 = false;
-        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 = true;
-    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 = false;
-    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) != 0;
-        s->page = (value >> 11) & 0x0f;
-        s->offset = (value >> 5) & 0x3f;
-        s->state = true;
-    } 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 = false;
-    }
-}
-
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
-{
-    TSC210xState *s = opaque;
-    uint32_t ret = 0;
-
-    if (len != 16) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "%s: bad SPI word width %i\n", __func__, len);
-        return 0;
-    }
-
-    /* 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 = false;
-    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 int tsc210x_pre_save(void *opaque)
-{
-    TSC210xState *s = (TSC210xState *) opaque;
-    s->now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-    return 0;
-}
-
-static int tsc210x_post_load(void *opaque, int version_id)
-{
-    TSC210xState *s = (TSC210xState *) opaque;
-    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-    if (s->function >= ARRAY_SIZE(mode_regs)) {
-        return -EINVAL;
-    }
-    if (s->nextfunction >= ARRAY_SIZE(mode_regs)) {
-        return -EINVAL;
-    }
-    if (s->precision >= ARRAY_SIZE(resolution)) {
-        return -EINVAL;
-    }
-    if (s->nextprecision >= ARRAY_SIZE(resolution)) {
-        return -EINVAL;
-    }
-
-    s->volume_change -= s->now;
-    s->volume_change += now;
-    s->powerdown -= s->now;
-    s->powerdown += now;
-
-    s->busy = timer_pending(s->timer);
-    qemu_set_irq(s->pint, !s->irq);
-    qemu_set_irq(s->davint, !s->dav);
-
-    return 0;
-}
-
-static const VMStateField vmstatefields_tsc210x[] = {
-    VMSTATE_BOOL(enabled, TSC210xState),
-    VMSTATE_BOOL(host_mode, TSC210xState),
-    VMSTATE_BOOL(irq, TSC210xState),
-    VMSTATE_BOOL(command, TSC210xState),
-    VMSTATE_BOOL(pressure, TSC210xState),
-    VMSTATE_BOOL(softstep, TSC210xState),
-    VMSTATE_BOOL(state, TSC210xState),
-    VMSTATE_UINT16(dav, TSC210xState),
-    VMSTATE_INT32(x, TSC210xState),
-    VMSTATE_INT32(y, TSC210xState),
-    VMSTATE_UINT8(offset, TSC210xState),
-    VMSTATE_UINT8(page, TSC210xState),
-    VMSTATE_UINT8(filter, TSC210xState),
-    VMSTATE_UINT8(pin_func, TSC210xState),
-    VMSTATE_UINT8(ref, TSC210xState),
-    VMSTATE_UINT8(timing, TSC210xState),
-    VMSTATE_UINT8(noise, TSC210xState),
-    VMSTATE_UINT8(function, TSC210xState),
-    VMSTATE_UINT8(nextfunction, TSC210xState),
-    VMSTATE_UINT8(precision, TSC210xState),
-    VMSTATE_UINT8(nextprecision, TSC210xState),
-    VMSTATE_UINT16(audio_ctrl1, TSC210xState),
-    VMSTATE_UINT16(audio_ctrl2, TSC210xState),
-    VMSTATE_UINT16(audio_ctrl3, TSC210xState),
-    VMSTATE_UINT16_ARRAY(pll, TSC210xState, 3),
-    VMSTATE_UINT16(volume, TSC210xState),
-    VMSTATE_UINT16(dac_power, TSC210xState),
-    VMSTATE_INT64(volume_change, TSC210xState),
-    VMSTATE_INT64(powerdown, TSC210xState),
-    VMSTATE_INT64(now, TSC210xState),
-    VMSTATE_UINT16_ARRAY(filter_data, TSC210xState, 0x14),
-    VMSTATE_TIMER_PTR(timer, TSC210xState),
-    VMSTATE_END_OF_LIST()
-};
-
-static const VMStateDescription vmstate_tsc2102 = {
-    .name = "tsc2102",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .pre_save = tsc210x_pre_save,
-    .post_load = tsc210x_post_load,
-    .fields = vmstatefields_tsc210x,
-};
-
-static const VMStateDescription vmstate_tsc2301 = {
-    .name = "tsc2301",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .pre_save = tsc210x_pre_save,
-    .post_load = tsc210x_post_load,
-    .fields = vmstatefields_tsc210x,
-};
-
-static void tsc210x_init(TSC210xState *s,
-                         const char *name,
-                         const VMStateDescription *vmsd)
-{
-    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, name);
-
-    if (current_machine->audiodev) {
-        s->card.name = g_strdup(current_machine->audiodev);
-        s->card.state = audio_state_by_name(s->card.name, &error_fatal);
-    }
-    AUD_register_card(s->name, &s->card, &error_fatal);
-
-    qemu_register_reset((void *) tsc210x_reset, s);
-    vmstate_register(NULL, 0, vmsd, s);
-}
-
-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";
-
-    tsc210x_init(s, "QEMU TSC2102-driven Touchscreen", &vmstate_tsc2102);
-
-    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";
-
-    tsc210x_init(s, "QEMU TSC2301-driven Touchscreen", &vmstate_tsc2301);
-
-    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, const 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);
-    }
-}