cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

tsc210x.c (34138B)


      1/*
      2 * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
      3 * TI TSC2301 (touchscreen/sensors/keypad).
      4 *
      5 * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
      6 * Copyright (C) 2008 Nokia Corporation
      7 *
      8 * This program is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU General Public License as
     10 * published by the Free Software Foundation; either version 2 or
     11 * (at your option) version 3 of the License.
     12 *
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License along
     19 * with this program; if not, see <http://www.gnu.org/licenses/>.
     20 */
     21
     22#include "qemu/osdep.h"
     23#include "hw/hw.h"
     24#include "audio/audio.h"
     25#include "qemu/timer.h"
     26#include "sysemu/reset.h"
     27#include "ui/console.h"
     28#include "hw/arm/omap.h"            /* For I2SCodec */
     29#include "hw/input/tsc2xxx.h"
     30#include "hw/irq.h"
     31#include "migration/vmstate.h"
     32
     33#define TSC_DATA_REGISTERS_PAGE		0x0
     34#define TSC_CONTROL_REGISTERS_PAGE	0x1
     35#define TSC_AUDIO_REGISTERS_PAGE	0x2
     36
     37#define TSC_VERBOSE
     38
     39#define TSC_CUT_RESOLUTION(value, p)	((value) >> (16 - resolution[p]))
     40
     41typedef struct {
     42    qemu_irq pint;
     43    qemu_irq kbint;
     44    qemu_irq davint;
     45    QEMUTimer *timer;
     46    QEMUSoundCard card;
     47    uWireSlave chip;
     48    I2SCodec codec;
     49    uint8_t in_fifo[16384];
     50    uint8_t out_fifo[16384];
     51    uint16_t model;
     52
     53    int32_t x, y;
     54    bool pressure;
     55
     56    uint8_t page, offset;
     57    uint16_t dav;
     58
     59    bool state;
     60    bool irq;
     61    bool command;
     62    bool busy;
     63    bool enabled;
     64    bool host_mode;
     65    uint8_t function, nextfunction;
     66    uint8_t precision, nextprecision;
     67    uint8_t filter;
     68    uint8_t pin_func;
     69    uint8_t ref;
     70    uint8_t timing;
     71    uint8_t noise;
     72
     73    uint16_t audio_ctrl1;
     74    uint16_t audio_ctrl2;
     75    uint16_t audio_ctrl3;
     76    uint16_t pll[3];
     77    uint16_t volume;
     78    int64_t volume_change;
     79    bool softstep;
     80    uint16_t dac_power;
     81    int64_t powerdown;
     82    uint16_t filter_data[0x14];
     83
     84    const char *name;
     85    SWVoiceIn *adc_voice[1];
     86    SWVoiceOut *dac_voice[1];
     87    int i2s_rx_rate;
     88    int i2s_tx_rate;
     89
     90    int tr[8];
     91
     92    struct {
     93        uint16_t down;
     94        uint16_t mask;
     95        int scan;
     96        int debounce;
     97        int mode;
     98        int intr;
     99    } kb;
    100    int64_t now; /* Time at migration */
    101} TSC210xState;
    102
    103static const int resolution[4] = { 12, 8, 10, 12 };
    104
    105#define TSC_MODE_NO_SCAN	0x0
    106#define TSC_MODE_XY_SCAN	0x1
    107#define TSC_MODE_XYZ_SCAN	0x2
    108#define TSC_MODE_X		0x3
    109#define TSC_MODE_Y		0x4
    110#define TSC_MODE_Z		0x5
    111#define TSC_MODE_BAT1		0x6
    112#define TSC_MODE_BAT2		0x7
    113#define TSC_MODE_AUX		0x8
    114#define TSC_MODE_AUX_SCAN	0x9
    115#define TSC_MODE_TEMP1		0xa
    116#define TSC_MODE_PORT_SCAN	0xb
    117#define TSC_MODE_TEMP2		0xc
    118#define TSC_MODE_XX_DRV		0xd
    119#define TSC_MODE_YY_DRV		0xe
    120#define TSC_MODE_YX_DRV		0xf
    121
    122static const uint16_t mode_regs[16] = {
    123    0x0000,	/* No scan */
    124    0x0600,	/* X, Y scan */
    125    0x0780,	/* X, Y, Z scan */
    126    0x0400,	/* X */
    127    0x0200,	/* Y */
    128    0x0180,	/* Z */
    129    0x0040,	/* BAT1 */
    130    0x0030,	/* BAT2 */
    131    0x0010,	/* AUX */
    132    0x0010,	/* AUX scan */
    133    0x0004,	/* TEMP1 */
    134    0x0070,	/* Port scan */
    135    0x0002,	/* TEMP2 */
    136    0x0000,	/* X+, X- drivers */
    137    0x0000,	/* Y+, Y- drivers */
    138    0x0000,	/* Y+, X- drivers */
    139};
    140
    141#define X_TRANSFORM(s)			\
    142    ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
    143#define Y_TRANSFORM(s)			\
    144    ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
    145#define Z1_TRANSFORM(s)			\
    146    ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
    147#define Z2_TRANSFORM(s)			\
    148    ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
    149
    150#define BAT1_VAL			0x8660
    151#define BAT2_VAL			0x0000
    152#define AUX1_VAL			0x35c0
    153#define AUX2_VAL			0xffff
    154#define TEMP1_VAL			0x8c70
    155#define TEMP2_VAL			0xa5b0
    156
    157#define TSC_POWEROFF_DELAY		50
    158#define TSC_SOFTSTEP_DELAY		50
    159
    160static void tsc210x_reset(TSC210xState *s)
    161{
    162    s->state = false;
    163    s->pin_func = 2;
    164    s->enabled = false;
    165    s->busy = false;
    166    s->nextfunction = 0;
    167    s->ref = 0;
    168    s->timing = 0;
    169    s->irq = false;
    170    s->dav = 0;
    171
    172    s->audio_ctrl1 = 0x0000;
    173    s->audio_ctrl2 = 0x4410;
    174    s->audio_ctrl3 = 0x0000;
    175    s->pll[0] = 0x1004;
    176    s->pll[1] = 0x0000;
    177    s->pll[2] = 0x1fff;
    178    s->volume = 0xffff;
    179    s->dac_power = 0x8540;
    180    s->softstep = true;
    181    s->volume_change = 0;
    182    s->powerdown = 0;
    183    s->filter_data[0x00] = 0x6be3;
    184    s->filter_data[0x01] = 0x9666;
    185    s->filter_data[0x02] = 0x675d;
    186    s->filter_data[0x03] = 0x6be3;
    187    s->filter_data[0x04] = 0x9666;
    188    s->filter_data[0x05] = 0x675d;
    189    s->filter_data[0x06] = 0x7d83;
    190    s->filter_data[0x07] = 0x84ee;
    191    s->filter_data[0x08] = 0x7d83;
    192    s->filter_data[0x09] = 0x84ee;
    193    s->filter_data[0x0a] = 0x6be3;
    194    s->filter_data[0x0b] = 0x9666;
    195    s->filter_data[0x0c] = 0x675d;
    196    s->filter_data[0x0d] = 0x6be3;
    197    s->filter_data[0x0e] = 0x9666;
    198    s->filter_data[0x0f] = 0x675d;
    199    s->filter_data[0x10] = 0x7d83;
    200    s->filter_data[0x11] = 0x84ee;
    201    s->filter_data[0x12] = 0x7d83;
    202    s->filter_data[0x13] = 0x84ee;
    203
    204    s->i2s_tx_rate = 0;
    205    s->i2s_rx_rate = 0;
    206
    207    s->kb.scan = 1;
    208    s->kb.debounce = 0;
    209    s->kb.mask = 0x0000;
    210    s->kb.mode = 3;
    211    s->kb.intr = 0;
    212
    213    qemu_set_irq(s->pint, !s->irq);
    214    qemu_set_irq(s->davint, !s->dav);
    215    qemu_irq_raise(s->kbint);
    216}
    217
    218typedef struct {
    219    int rate;
    220    int dsor;
    221    int fsref;
    222} TSC210xRateInfo;
    223
    224/*  { rate,   dsor, fsref }	*/
    225static const TSC210xRateInfo tsc2102_rates[] = {
    226    /* Fsref / 6.0 */
    227    { 7350,	63,	1 },
    228    { 8000,	63,	0 },
    229    /* Fsref / 6.0 */
    230    { 7350,	54,	1 },
    231    { 8000,	54,	0 },
    232    /* Fsref / 5.0 */
    233    { 8820,	45,	1 },
    234    { 9600,	45,	0 },
    235    /* Fsref / 4.0 */
    236    { 11025,	36,	1 },
    237    { 12000,	36,	0 },
    238    /* Fsref / 3.0 */
    239    { 14700,	27,	1 },
    240    { 16000,	27,	0 },
    241    /* Fsref / 2.0 */
    242    { 22050,	18,	1 },
    243    { 24000,	18,	0 },
    244    /* Fsref / 1.5 */
    245    { 29400,	9,	1 },
    246    { 32000,	9,	0 },
    247    /* Fsref */
    248    { 44100,	0,	1 },
    249    { 48000,	0,	0 },
    250
    251    { 0,	0, 	0 },
    252};
    253
    254static inline void tsc210x_out_flush(TSC210xState *s, int len)
    255{
    256    uint8_t *data = s->codec.out.fifo + s->codec.out.start;
    257    uint8_t *end = data + len;
    258
    259    while (data < end)
    260        data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
    261
    262    s->codec.out.len -= len;
    263    if (s->codec.out.len)
    264        memmove(s->codec.out.fifo, end, s->codec.out.len);
    265    s->codec.out.start = 0;
    266}
    267
    268static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
    269{
    270    if (s->codec.out.len >= free_b) {
    271        tsc210x_out_flush(s, free_b);
    272        return;
    273    }
    274
    275    s->codec.out.size = MIN(free_b, 16384);
    276    qemu_irq_raise(s->codec.tx_start);
    277}
    278
    279static void tsc2102_audio_rate_update(TSC210xState *s)
    280{
    281    const TSC210xRateInfo *rate;
    282
    283    s->codec.tx_rate = 0;
    284    s->codec.rx_rate = 0;
    285    if (s->dac_power & (1 << 15))				/* PWDNC */
    286        return;
    287
    288    for (rate = tsc2102_rates; rate->rate; rate ++)
    289        if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&		/* DACFS */
    290                        rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
    291            break;
    292    if (!rate->rate) {
    293        printf("%s: unknown sampling rate configured\n", __func__);
    294        return;
    295    }
    296
    297    s->codec.tx_rate = rate->rate;
    298}
    299
    300static void tsc2102_audio_output_update(TSC210xState *s)
    301{
    302    int enable;
    303    struct audsettings fmt;
    304
    305    if (s->dac_voice[0]) {
    306        tsc210x_out_flush(s, s->codec.out.len);
    307        s->codec.out.size = 0;
    308        AUD_set_active_out(s->dac_voice[0], 0);
    309        AUD_close_out(&s->card, s->dac_voice[0]);
    310        s->dac_voice[0] = NULL;
    311    }
    312    s->codec.cts = 0;
    313
    314    enable =
    315            (~s->dac_power & (1 << 15)) &&			/* PWDNC */
    316            (~s->dac_power & (1 << 10));			/* DAPWDN */
    317    if (!enable || !s->codec.tx_rate)
    318        return;
    319
    320    /* Force our own sampling rate even in slave DAC mode */
    321    fmt.endianness = 0;
    322    fmt.nchannels = 2;
    323    fmt.freq = s->codec.tx_rate;
    324    fmt.fmt = AUDIO_FORMAT_S16;
    325
    326    s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
    327                    "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
    328    if (s->dac_voice[0]) {
    329        s->codec.cts = 1;
    330        AUD_set_active_out(s->dac_voice[0], 1);
    331    }
    332}
    333
    334static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
    335{
    336    switch (reg) {
    337    case 0x00:	/* X */
    338        s->dav &= 0xfbff;
    339        return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
    340                (s->noise & 3);
    341
    342    case 0x01:	/* Y */
    343        s->noise ++;
    344        s->dav &= 0xfdff;
    345        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
    346                (s->noise & 3);
    347
    348    case 0x02:	/* Z1 */
    349        s->dav &= 0xfeff;
    350        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
    351                (s->noise & 3);
    352
    353    case 0x03:	/* Z2 */
    354        s->dav &= 0xff7f;
    355        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
    356                (s->noise & 3);
    357
    358    case 0x04:	/* KPData */
    359        if ((s->model & 0xff00) == 0x2300) {
    360            if (s->kb.intr && (s->kb.mode & 2)) {
    361                s->kb.intr = 0;
    362                qemu_irq_raise(s->kbint);
    363            }
    364            return s->kb.down;
    365        }
    366
    367        return 0xffff;
    368
    369    case 0x05:	/* BAT1 */
    370        s->dav &= 0xffbf;
    371        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision) +
    372                (s->noise & 6);
    373
    374    case 0x06:	/* BAT2 */
    375        s->dav &= 0xffdf;
    376        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
    377
    378    case 0x07:	/* AUX1 */
    379        s->dav &= 0xffef;
    380        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
    381
    382    case 0x08:	/* AUX2 */
    383        s->dav &= 0xfff7;
    384        return 0xffff;
    385
    386    case 0x09:	/* TEMP1 */
    387        s->dav &= 0xfffb;
    388        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
    389                (s->noise & 5);
    390
    391    case 0x0a:	/* TEMP2 */
    392        s->dav &= 0xfffd;
    393        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
    394                (s->noise & 3);
    395
    396    case 0x0b:	/* DAC */
    397        s->dav &= 0xfffe;
    398        return 0xffff;
    399
    400    default:
    401#ifdef TSC_VERBOSE
    402        fprintf(stderr, "tsc2102_data_register_read: "
    403                        "no such register: 0x%02x\n", reg);
    404#endif
    405        return 0xffff;
    406    }
    407}
    408
    409static uint16_t tsc2102_control_register_read(
    410                TSC210xState *s, int reg)
    411{
    412    switch (reg) {
    413    case 0x00:	/* TSC ADC */
    414        return (s->pressure << 15) | ((!s->busy) << 14) |
    415                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
    416
    417    case 0x01:	/* Status / Keypad Control */
    418        if ((s->model & 0xff00) == 0x2100)
    419            return (s->pin_func << 14) | ((!s->enabled) << 13) |
    420                    (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
    421        else
    422            return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) |
    423                    (s->kb.debounce << 11);
    424
    425    case 0x02:	/* DAC Control */
    426        if ((s->model & 0xff00) == 0x2300)
    427            return s->dac_power & 0x8000;
    428        else
    429            goto bad_reg;
    430
    431    case 0x03:	/* Reference */
    432        return s->ref;
    433
    434    case 0x04:	/* Reset */
    435        return 0xffff;
    436
    437    case 0x05:	/* Configuration */
    438        return s->timing;
    439
    440    case 0x06:	/* Secondary configuration */
    441        if ((s->model & 0xff00) == 0x2100)
    442            goto bad_reg;
    443        return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2];
    444
    445    case 0x10:	/* Keypad Mask */
    446        if ((s->model & 0xff00) == 0x2100)
    447            goto bad_reg;
    448        return s->kb.mask;
    449
    450    default:
    451    bad_reg:
    452#ifdef TSC_VERBOSE
    453        fprintf(stderr, "tsc2102_control_register_read: "
    454                        "no such register: 0x%02x\n", reg);
    455#endif
    456        return 0xffff;
    457    }
    458}
    459
    460static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
    461{
    462    int l_ch, r_ch;
    463    uint16_t val;
    464
    465    switch (reg) {
    466    case 0x00:	/* Audio Control 1 */
    467        return s->audio_ctrl1;
    468
    469    case 0x01:
    470        return 0xff00;
    471
    472    case 0x02:	/* DAC Volume Control */
    473        return s->volume;
    474
    475    case 0x03:
    476        return 0x8b00;
    477
    478    case 0x04:	/* Audio Control 2 */
    479        l_ch = 1;
    480        r_ch = 1;
    481        if (s->softstep && !(s->dac_power & (1 << 10))) {
    482            l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
    483                            s->volume_change + TSC_SOFTSTEP_DELAY);
    484            r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
    485                            s->volume_change + TSC_SOFTSTEP_DELAY);
    486        }
    487
    488        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
    489
    490    case 0x05:	/* Stereo DAC Power Control */
    491        return 0x2aa0 | s->dac_power |
    492                (((s->dac_power & (1 << 10)) &&
    493                  (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
    494                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
    495
    496    case 0x06:	/* Audio Control 3 */
    497        val = s->audio_ctrl3 | 0x0001;
    498        s->audio_ctrl3 &= 0xff3f;
    499        return val;
    500
    501    case 0x07:	/* LCH_BASS_BOOST_N0 */
    502    case 0x08:	/* LCH_BASS_BOOST_N1 */
    503    case 0x09:	/* LCH_BASS_BOOST_N2 */
    504    case 0x0a:	/* LCH_BASS_BOOST_N3 */
    505    case 0x0b:	/* LCH_BASS_BOOST_N4 */
    506    case 0x0c:	/* LCH_BASS_BOOST_N5 */
    507    case 0x0d:	/* LCH_BASS_BOOST_D1 */
    508    case 0x0e:	/* LCH_BASS_BOOST_D2 */
    509    case 0x0f:	/* LCH_BASS_BOOST_D4 */
    510    case 0x10:	/* LCH_BASS_BOOST_D5 */
    511    case 0x11:	/* RCH_BASS_BOOST_N0 */
    512    case 0x12:	/* RCH_BASS_BOOST_N1 */
    513    case 0x13:	/* RCH_BASS_BOOST_N2 */
    514    case 0x14:	/* RCH_BASS_BOOST_N3 */
    515    case 0x15:	/* RCH_BASS_BOOST_N4 */
    516    case 0x16:	/* RCH_BASS_BOOST_N5 */
    517    case 0x17:	/* RCH_BASS_BOOST_D1 */
    518    case 0x18:	/* RCH_BASS_BOOST_D2 */
    519    case 0x19:	/* RCH_BASS_BOOST_D4 */
    520    case 0x1a:	/* RCH_BASS_BOOST_D5 */
    521        return s->filter_data[reg - 0x07];
    522
    523    case 0x1b:	/* PLL Programmability 1 */
    524        return s->pll[0];
    525
    526    case 0x1c:	/* PLL Programmability 2 */
    527        return s->pll[1];
    528
    529    case 0x1d:	/* Audio Control 4 */
    530        return (!s->softstep) << 14;
    531
    532    default:
    533#ifdef TSC_VERBOSE
    534        fprintf(stderr, "tsc2102_audio_register_read: "
    535                        "no such register: 0x%02x\n", reg);
    536#endif
    537        return 0xffff;
    538    }
    539}
    540
    541static void tsc2102_data_register_write(
    542                TSC210xState *s, int reg, uint16_t value)
    543{
    544    switch (reg) {
    545    case 0x00:	/* X */
    546    case 0x01:	/* Y */
    547    case 0x02:	/* Z1 */
    548    case 0x03:	/* Z2 */
    549    case 0x05:	/* BAT1 */
    550    case 0x06:	/* BAT2 */
    551    case 0x07:	/* AUX1 */
    552    case 0x08:	/* AUX2 */
    553    case 0x09:	/* TEMP1 */
    554    case 0x0a:	/* TEMP2 */
    555        return;
    556
    557    default:
    558        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_data_register_write: "
    559                                       "no such register: 0x%02x\n", reg);
    560    }
    561}
    562
    563static void tsc2102_control_register_write(
    564                TSC210xState *s, int reg, uint16_t value)
    565{
    566    switch (reg) {
    567    case 0x00:	/* TSC ADC */
    568        s->host_mode = value >> 15;
    569        s->enabled = !(value & 0x4000);
    570        if (s->busy && !s->enabled)
    571            timer_del(s->timer);
    572        s->busy = s->busy && s->enabled;
    573        s->nextfunction = (value >> 10) & 0xf;
    574        s->nextprecision = (value >> 8) & 3;
    575        s->filter = value & 0xff;
    576        return;
    577
    578    case 0x01:	/* Status / Keypad Control */
    579        if ((s->model & 0xff00) == 0x2100)
    580            s->pin_func = value >> 14;
    581        else {
    582            s->kb.scan = (value >> 14) & 1;
    583            s->kb.debounce = (value >> 11) & 7;
    584            if (s->kb.intr && s->kb.scan) {
    585                s->kb.intr = 0;
    586                qemu_irq_raise(s->kbint);
    587            }
    588        }
    589        return;
    590
    591    case 0x02:	/* DAC Control */
    592        if ((s->model & 0xff00) == 0x2300) {
    593            s->dac_power &= 0x7fff;
    594            s->dac_power |= 0x8000 & value;
    595        } else
    596            goto bad_reg;
    597        break;
    598
    599    case 0x03:	/* Reference */
    600        s->ref = value & 0x1f;
    601        return;
    602
    603    case 0x04:	/* Reset */
    604        if (value == 0xbb00) {
    605            if (s->busy)
    606                timer_del(s->timer);
    607            tsc210x_reset(s);
    608#ifdef TSC_VERBOSE
    609        } else {
    610            fprintf(stderr, "tsc2102_control_register_write: "
    611                            "wrong value written into RESET\n");
    612#endif
    613        }
    614        return;
    615
    616    case 0x05:	/* Configuration */
    617        s->timing = value & 0x3f;
    618#ifdef TSC_VERBOSE
    619        if (value & ~0x3f)
    620            fprintf(stderr, "tsc2102_control_register_write: "
    621                            "wrong value written into CONFIG\n");
    622#endif
    623        return;
    624
    625    case 0x06:	/* Secondary configuration */
    626        if ((s->model & 0xff00) == 0x2100)
    627            goto bad_reg;
    628        s->kb.mode = value >> 14;
    629        s->pll[2] = value & 0x3ffff;
    630        return;
    631
    632    case 0x10:	/* Keypad Mask */
    633        if ((s->model & 0xff00) == 0x2100)
    634            goto bad_reg;
    635        s->kb.mask = value;
    636        return;
    637
    638    default:
    639    bad_reg:
    640        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_control_register_write: "
    641                                       "no such register: 0x%02x\n", reg);
    642    }
    643}
    644
    645static void tsc2102_audio_register_write(
    646                TSC210xState *s, int reg, uint16_t value)
    647{
    648    switch (reg) {
    649    case 0x00:	/* Audio Control 1 */
    650        s->audio_ctrl1 = value & 0x0f3f;
    651#ifdef TSC_VERBOSE
    652        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
    653            fprintf(stderr, "tsc2102_audio_register_write: "
    654                            "wrong value written into Audio 1\n");
    655#endif
    656        tsc2102_audio_rate_update(s);
    657        tsc2102_audio_output_update(s);
    658        return;
    659
    660    case 0x01:
    661#ifdef TSC_VERBOSE
    662        if (value != 0xff00)
    663            fprintf(stderr, "tsc2102_audio_register_write: "
    664                            "wrong value written into reg 0x01\n");
    665#endif
    666        return;
    667
    668    case 0x02:	/* DAC Volume Control */
    669        s->volume = value;
    670        s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    671        return;
    672
    673    case 0x03:
    674#ifdef TSC_VERBOSE
    675        if (value != 0x8b00)
    676            fprintf(stderr, "tsc2102_audio_register_write: "
    677                            "wrong value written into reg 0x03\n");
    678#endif
    679        return;
    680
    681    case 0x04:	/* Audio Control 2 */
    682        s->audio_ctrl2 = value & 0xf7f2;
    683#ifdef TSC_VERBOSE
    684        if (value & ~0xf7fd)
    685            fprintf(stderr, "tsc2102_audio_register_write: "
    686                            "wrong value written into Audio 2\n");
    687#endif
    688        return;
    689
    690    case 0x05:	/* Stereo DAC Power Control */
    691        if ((value & ~s->dac_power) & (1 << 10))
    692            s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    693
    694        s->dac_power = value & 0x9543;
    695#ifdef TSC_VERBOSE
    696        if ((value & ~0x9543) != 0x2aa0)
    697            fprintf(stderr, "tsc2102_audio_register_write: "
    698                            "wrong value written into Power\n");
    699#endif
    700        tsc2102_audio_rate_update(s);
    701        tsc2102_audio_output_update(s);
    702        return;
    703
    704    case 0x06:	/* Audio Control 3 */
    705        s->audio_ctrl3 &= 0x00c0;
    706        s->audio_ctrl3 |= value & 0xf800;
    707#ifdef TSC_VERBOSE
    708        if (value & ~0xf8c7)
    709            fprintf(stderr, "tsc2102_audio_register_write: "
    710                            "wrong value written into Audio 3\n");
    711#endif
    712        tsc2102_audio_output_update(s);
    713        return;
    714
    715    case 0x07:	/* LCH_BASS_BOOST_N0 */
    716    case 0x08:	/* LCH_BASS_BOOST_N1 */
    717    case 0x09:	/* LCH_BASS_BOOST_N2 */
    718    case 0x0a:	/* LCH_BASS_BOOST_N3 */
    719    case 0x0b:	/* LCH_BASS_BOOST_N4 */
    720    case 0x0c:	/* LCH_BASS_BOOST_N5 */
    721    case 0x0d:	/* LCH_BASS_BOOST_D1 */
    722    case 0x0e:	/* LCH_BASS_BOOST_D2 */
    723    case 0x0f:	/* LCH_BASS_BOOST_D4 */
    724    case 0x10:	/* LCH_BASS_BOOST_D5 */
    725    case 0x11:	/* RCH_BASS_BOOST_N0 */
    726    case 0x12:	/* RCH_BASS_BOOST_N1 */
    727    case 0x13:	/* RCH_BASS_BOOST_N2 */
    728    case 0x14:	/* RCH_BASS_BOOST_N3 */
    729    case 0x15:	/* RCH_BASS_BOOST_N4 */
    730    case 0x16:	/* RCH_BASS_BOOST_N5 */
    731    case 0x17:	/* RCH_BASS_BOOST_D1 */
    732    case 0x18:	/* RCH_BASS_BOOST_D2 */
    733    case 0x19:	/* RCH_BASS_BOOST_D4 */
    734    case 0x1a:	/* RCH_BASS_BOOST_D5 */
    735        s->filter_data[reg - 0x07] = value;
    736        return;
    737
    738    case 0x1b:	/* PLL Programmability 1 */
    739        s->pll[0] = value & 0xfffc;
    740#ifdef TSC_VERBOSE
    741        if (value & ~0xfffc)
    742            fprintf(stderr, "tsc2102_audio_register_write: "
    743                            "wrong value written into PLL 1\n");
    744#endif
    745        return;
    746
    747    case 0x1c:	/* PLL Programmability 2 */
    748        s->pll[1] = value & 0xfffc;
    749#ifdef TSC_VERBOSE
    750        if (value & ~0xfffc)
    751            fprintf(stderr, "tsc2102_audio_register_write: "
    752                            "wrong value written into PLL 2\n");
    753#endif
    754        return;
    755
    756    case 0x1d:	/* Audio Control 4 */
    757        s->softstep = !(value & 0x4000);
    758#ifdef TSC_VERBOSE
    759        if (value & ~0x4000)
    760            fprintf(stderr, "tsc2102_audio_register_write: "
    761                            "wrong value written into Audio 4\n");
    762#endif
    763        return;
    764
    765    default:
    766        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_audio_register_write: "
    767                                       "no such register: 0x%02x\n", reg);
    768    }
    769}
    770
    771/* This handles most of the chip logic.  */
    772static void tsc210x_pin_update(TSC210xState *s)
    773{
    774    int64_t expires;
    775    bool pin_state;
    776
    777    switch (s->pin_func) {
    778    case 0:
    779        pin_state = s->pressure;
    780        break;
    781    case 1:
    782        pin_state = !!s->dav;
    783        break;
    784    case 2:
    785    default:
    786        pin_state = s->pressure && !s->dav;
    787    }
    788
    789    if (!s->enabled)
    790        pin_state = false;
    791
    792    if (pin_state != s->irq) {
    793        s->irq = pin_state;
    794        qemu_set_irq(s->pint, !s->irq);
    795    }
    796
    797    switch (s->nextfunction) {
    798    case TSC_MODE_XY_SCAN:
    799    case TSC_MODE_XYZ_SCAN:
    800        if (!s->pressure)
    801            return;
    802        break;
    803
    804    case TSC_MODE_X:
    805    case TSC_MODE_Y:
    806    case TSC_MODE_Z:
    807        if (!s->pressure)
    808            return;
    809        /* Fall through */
    810    case TSC_MODE_BAT1:
    811    case TSC_MODE_BAT2:
    812    case TSC_MODE_AUX:
    813    case TSC_MODE_TEMP1:
    814    case TSC_MODE_TEMP2:
    815        if (s->dav)
    816            s->enabled = false;
    817        break;
    818
    819    case TSC_MODE_AUX_SCAN:
    820    case TSC_MODE_PORT_SCAN:
    821        break;
    822
    823    case TSC_MODE_NO_SCAN:
    824    case TSC_MODE_XX_DRV:
    825    case TSC_MODE_YY_DRV:
    826    case TSC_MODE_YX_DRV:
    827    default:
    828        return;
    829    }
    830
    831    if (!s->enabled || s->busy || s->dav)
    832        return;
    833
    834    s->busy = true;
    835    s->precision = s->nextprecision;
    836    s->function = s->nextfunction;
    837    expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
    838        (NANOSECONDS_PER_SECOND >> 10);
    839    timer_mod(s->timer, expires);
    840}
    841
    842static uint16_t tsc210x_read(TSC210xState *s)
    843{
    844    uint16_t ret = 0x0000;
    845
    846    if (!s->command)
    847        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
    848
    849    switch (s->page) {
    850    case TSC_DATA_REGISTERS_PAGE:
    851        ret = tsc2102_data_register_read(s, s->offset);
    852        if (!s->dav)
    853            qemu_irq_raise(s->davint);
    854        break;
    855    case TSC_CONTROL_REGISTERS_PAGE:
    856        ret = tsc2102_control_register_read(s, s->offset);
    857        break;
    858    case TSC_AUDIO_REGISTERS_PAGE:
    859        ret = tsc2102_audio_register_read(s, s->offset);
    860        break;
    861    default:
    862        hw_error("tsc210x_read: wrong memory page\n");
    863    }
    864
    865    tsc210x_pin_update(s);
    866
    867    /* Allow sequential reads.  */
    868    s->offset ++;
    869    s->state = false;
    870    return ret;
    871}
    872
    873static void tsc210x_write(TSC210xState *s, uint16_t value)
    874{
    875    /*
    876     * This is a two-state state machine for reading
    877     * command and data every second time.
    878     */
    879    if (!s->state) {
    880        s->command = (value >> 15) != 0;
    881        s->page = (value >> 11) & 0x0f;
    882        s->offset = (value >> 5) & 0x3f;
    883        s->state = true;
    884    } else {
    885        if (s->command)
    886            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
    887        else
    888            switch (s->page) {
    889            case TSC_DATA_REGISTERS_PAGE:
    890                tsc2102_data_register_write(s, s->offset, value);
    891                break;
    892            case TSC_CONTROL_REGISTERS_PAGE:
    893                tsc2102_control_register_write(s, s->offset, value);
    894                break;
    895            case TSC_AUDIO_REGISTERS_PAGE:
    896                tsc2102_audio_register_write(s, s->offset, value);
    897                break;
    898            default:
    899                hw_error("tsc210x_write: wrong memory page\n");
    900            }
    901
    902        tsc210x_pin_update(s);
    903        s->state = false;
    904    }
    905}
    906
    907uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
    908{
    909    TSC210xState *s = opaque;
    910    uint32_t ret = 0;
    911
    912    if (len != 16)
    913        hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
    914
    915    /* TODO: sequential reads etc - how do we make sure the host doesn't
    916     * unintentionally read out a conversion result from a register while
    917     * transmitting the command word of the next command?  */
    918    if (!value || (s->state && s->command))
    919        ret = tsc210x_read(s);
    920    if (value || (s->state && !s->command))
    921        tsc210x_write(s, value);
    922
    923    return ret;
    924}
    925
    926static void tsc210x_timer_tick(void *opaque)
    927{
    928    TSC210xState *s = opaque;
    929
    930    /* Timer ticked -- a set of conversions has been finished.  */
    931
    932    if (!s->busy)
    933        return;
    934
    935    s->busy = false;
    936    s->dav |= mode_regs[s->function];
    937    tsc210x_pin_update(s);
    938    qemu_irq_lower(s->davint);
    939}
    940
    941static void tsc210x_touchscreen_event(void *opaque,
    942                int x, int y, int z, int buttons_state)
    943{
    944    TSC210xState *s = opaque;
    945    int p = s->pressure;
    946
    947    if (buttons_state) {
    948        s->x = x;
    949        s->y = y;
    950    }
    951    s->pressure = !!buttons_state;
    952
    953    /*
    954     * Note: We would get better responsiveness in the guest by
    955     * signaling TS events immediately, but for now we simulate
    956     * the first conversion delay for sake of correctness.
    957     */
    958    if (p != s->pressure)
    959        tsc210x_pin_update(s);
    960}
    961
    962static void tsc210x_i2s_swallow(TSC210xState *s)
    963{
    964    if (s->dac_voice[0])
    965        tsc210x_out_flush(s, s->codec.out.len);
    966    else
    967        s->codec.out.len = 0;
    968}
    969
    970static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
    971{
    972    s->i2s_tx_rate = out;
    973    s->i2s_rx_rate = in;
    974}
    975
    976static int tsc210x_pre_save(void *opaque)
    977{
    978    TSC210xState *s = (TSC210xState *) opaque;
    979    s->now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    980
    981    return 0;
    982}
    983
    984static int tsc210x_post_load(void *opaque, int version_id)
    985{
    986    TSC210xState *s = (TSC210xState *) opaque;
    987    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    988
    989    if (s->function >= ARRAY_SIZE(mode_regs)) {
    990        return -EINVAL;
    991    }
    992    if (s->nextfunction >= ARRAY_SIZE(mode_regs)) {
    993        return -EINVAL;
    994    }
    995    if (s->precision >= ARRAY_SIZE(resolution)) {
    996        return -EINVAL;
    997    }
    998    if (s->nextprecision >= ARRAY_SIZE(resolution)) {
    999        return -EINVAL;
   1000    }
   1001
   1002    s->volume_change -= s->now;
   1003    s->volume_change += now;
   1004    s->powerdown -= s->now;
   1005    s->powerdown += now;
   1006
   1007    s->busy = timer_pending(s->timer);
   1008    qemu_set_irq(s->pint, !s->irq);
   1009    qemu_set_irq(s->davint, !s->dav);
   1010
   1011    return 0;
   1012}
   1013
   1014static VMStateField vmstatefields_tsc210x[] = {
   1015    VMSTATE_BOOL(enabled, TSC210xState),
   1016    VMSTATE_BOOL(host_mode, TSC210xState),
   1017    VMSTATE_BOOL(irq, TSC210xState),
   1018    VMSTATE_BOOL(command, TSC210xState),
   1019    VMSTATE_BOOL(pressure, TSC210xState),
   1020    VMSTATE_BOOL(softstep, TSC210xState),
   1021    VMSTATE_BOOL(state, TSC210xState),
   1022    VMSTATE_UINT16(dav, TSC210xState),
   1023    VMSTATE_INT32(x, TSC210xState),
   1024    VMSTATE_INT32(y, TSC210xState),
   1025    VMSTATE_UINT8(offset, TSC210xState),
   1026    VMSTATE_UINT8(page, TSC210xState),
   1027    VMSTATE_UINT8(filter, TSC210xState),
   1028    VMSTATE_UINT8(pin_func, TSC210xState),
   1029    VMSTATE_UINT8(ref, TSC210xState),
   1030    VMSTATE_UINT8(timing, TSC210xState),
   1031    VMSTATE_UINT8(noise, TSC210xState),
   1032    VMSTATE_UINT8(function, TSC210xState),
   1033    VMSTATE_UINT8(nextfunction, TSC210xState),
   1034    VMSTATE_UINT8(precision, TSC210xState),
   1035    VMSTATE_UINT8(nextprecision, TSC210xState),
   1036    VMSTATE_UINT16(audio_ctrl1, TSC210xState),
   1037    VMSTATE_UINT16(audio_ctrl2, TSC210xState),
   1038    VMSTATE_UINT16(audio_ctrl3, TSC210xState),
   1039    VMSTATE_UINT16_ARRAY(pll, TSC210xState, 3),
   1040    VMSTATE_UINT16(volume, TSC210xState),
   1041    VMSTATE_UINT16(dac_power, TSC210xState),
   1042    VMSTATE_INT64(volume_change, TSC210xState),
   1043    VMSTATE_INT64(powerdown, TSC210xState),
   1044    VMSTATE_INT64(now, TSC210xState),
   1045    VMSTATE_UINT16_ARRAY(filter_data, TSC210xState, 0x14),
   1046    VMSTATE_TIMER_PTR(timer, TSC210xState),
   1047    VMSTATE_END_OF_LIST()
   1048};
   1049
   1050static const VMStateDescription vmstate_tsc2102 = {
   1051    .name = "tsc2102",
   1052    .version_id = 1,
   1053    .minimum_version_id = 1,
   1054    .pre_save = tsc210x_pre_save,
   1055    .post_load = tsc210x_post_load,
   1056    .fields = vmstatefields_tsc210x,
   1057};
   1058
   1059static const VMStateDescription vmstate_tsc2301 = {
   1060    .name = "tsc2301",
   1061    .version_id = 1,
   1062    .minimum_version_id = 1,
   1063    .pre_save = tsc210x_pre_save,
   1064    .post_load = tsc210x_post_load,
   1065    .fields = vmstatefields_tsc210x,
   1066};
   1067
   1068uWireSlave *tsc2102_init(qemu_irq pint)
   1069{
   1070    TSC210xState *s;
   1071
   1072    s = g_new0(TSC210xState, 1);
   1073    s->x = 160;
   1074    s->y = 160;
   1075    s->pressure = 0;
   1076    s->precision = s->nextprecision = 0;
   1077    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
   1078    s->pint = pint;
   1079    s->model = 0x2102;
   1080    s->name = "tsc2102";
   1081
   1082    s->tr[0] = 0;
   1083    s->tr[1] = 1;
   1084    s->tr[2] = 1;
   1085    s->tr[3] = 0;
   1086    s->tr[4] = 1;
   1087    s->tr[5] = 0;
   1088    s->tr[6] = 1;
   1089    s->tr[7] = 0;
   1090
   1091    s->chip.opaque = s;
   1092    s->chip.send = (void *) tsc210x_write;
   1093    s->chip.receive = (void *) tsc210x_read;
   1094
   1095    s->codec.opaque = s;
   1096    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
   1097    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
   1098    s->codec.in.fifo = s->in_fifo;
   1099    s->codec.out.fifo = s->out_fifo;
   1100
   1101    tsc210x_reset(s);
   1102
   1103    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
   1104                    "QEMU TSC2102-driven Touchscreen");
   1105
   1106    AUD_register_card(s->name, &s->card);
   1107
   1108    qemu_register_reset((void *) tsc210x_reset, s);
   1109    vmstate_register(NULL, 0, &vmstate_tsc2102, s);
   1110
   1111    return &s->chip;
   1112}
   1113
   1114uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
   1115{
   1116    TSC210xState *s;
   1117
   1118    s = g_new0(TSC210xState, 1);
   1119    s->x = 400;
   1120    s->y = 240;
   1121    s->pressure = 0;
   1122    s->precision = s->nextprecision = 0;
   1123    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
   1124    s->pint = penirq;
   1125    s->kbint = kbirq;
   1126    s->davint = dav;
   1127    s->model = 0x2301;
   1128    s->name = "tsc2301";
   1129
   1130    s->tr[0] = 0;
   1131    s->tr[1] = 1;
   1132    s->tr[2] = 1;
   1133    s->tr[3] = 0;
   1134    s->tr[4] = 1;
   1135    s->tr[5] = 0;
   1136    s->tr[6] = 1;
   1137    s->tr[7] = 0;
   1138
   1139    s->chip.opaque = s;
   1140    s->chip.send = (void *) tsc210x_write;
   1141    s->chip.receive = (void *) tsc210x_read;
   1142
   1143    s->codec.opaque = s;
   1144    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
   1145    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
   1146    s->codec.in.fifo = s->in_fifo;
   1147    s->codec.out.fifo = s->out_fifo;
   1148
   1149    tsc210x_reset(s);
   1150
   1151    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
   1152                    "QEMU TSC2301-driven Touchscreen");
   1153
   1154    AUD_register_card(s->name, &s->card);
   1155
   1156    qemu_register_reset((void *) tsc210x_reset, s);
   1157    vmstate_register(NULL, 0, &vmstate_tsc2301, s);
   1158
   1159    return &s->chip;
   1160}
   1161
   1162I2SCodec *tsc210x_codec(uWireSlave *chip)
   1163{
   1164    TSC210xState *s = (TSC210xState *) chip->opaque;
   1165
   1166    return &s->codec;
   1167}
   1168
   1169/*
   1170 * Use tslib generated calibration data to generate ADC input values
   1171 * from the touchscreen.  Assuming 12-bit precision was used during
   1172 * tslib calibration.
   1173 */
   1174void tsc210x_set_transform(uWireSlave *chip,
   1175                MouseTransformInfo *info)
   1176{
   1177    TSC210xState *s = (TSC210xState *) chip->opaque;
   1178#if 0
   1179    int64_t ltr[8];
   1180
   1181    ltr[0] = (int64_t) info->a[1] * info->y;
   1182    ltr[1] = (int64_t) info->a[4] * info->x;
   1183    ltr[2] = (int64_t) info->a[1] * info->a[3] -
   1184            (int64_t) info->a[4] * info->a[0];
   1185    ltr[3] = (int64_t) info->a[2] * info->a[4] -
   1186            (int64_t) info->a[5] * info->a[1];
   1187    ltr[4] = (int64_t) info->a[0] * info->y;
   1188    ltr[5] = (int64_t) info->a[3] * info->x;
   1189    ltr[6] = (int64_t) info->a[4] * info->a[0] -
   1190            (int64_t) info->a[1] * info->a[3];
   1191    ltr[7] = (int64_t) info->a[2] * info->a[3] -
   1192            (int64_t) info->a[5] * info->a[0];
   1193
   1194    /* Avoid integer overflow */
   1195    s->tr[0] = ltr[0] >> 11;
   1196    s->tr[1] = ltr[1] >> 11;
   1197    s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
   1198    s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
   1199    s->tr[4] = ltr[4] >> 11;
   1200    s->tr[5] = ltr[5] >> 11;
   1201    s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
   1202    s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
   1203#else
   1204
   1205    /* This version assumes touchscreen X & Y axis are parallel or
   1206     * perpendicular to LCD's  X & Y axis in some way.  */
   1207    if (abs(info->a[0]) > abs(info->a[1])) {
   1208        s->tr[0] = 0;
   1209        s->tr[1] = -info->a[6] * info->x;
   1210        s->tr[2] = info->a[0];
   1211        s->tr[3] = -info->a[2] / info->a[0];
   1212        s->tr[4] = info->a[6] * info->y;
   1213        s->tr[5] = 0;
   1214        s->tr[6] = info->a[4];
   1215        s->tr[7] = -info->a[5] / info->a[4];
   1216    } else {
   1217        s->tr[0] = info->a[6] * info->y;
   1218        s->tr[1] = 0;
   1219        s->tr[2] = info->a[1];
   1220        s->tr[3] = -info->a[2] / info->a[1];
   1221        s->tr[4] = 0;
   1222        s->tr[5] = -info->a[6] * info->x;
   1223        s->tr[6] = info->a[3];
   1224        s->tr[7] = -info->a[5] / info->a[3];
   1225    }
   1226
   1227    s->tr[0] >>= 11;
   1228    s->tr[1] >>= 11;
   1229    s->tr[3] <<= 4;
   1230    s->tr[4] >>= 11;
   1231    s->tr[5] >>= 11;
   1232    s->tr[7] <<= 4;
   1233#endif
   1234}
   1235
   1236void tsc210x_key_event(uWireSlave *chip, int key, int down)
   1237{
   1238    TSC210xState *s = (TSC210xState *) chip->opaque;
   1239
   1240    if (down)
   1241        s->kb.down |= 1 << key;
   1242    else
   1243        s->kb.down &= ~(1 << key);
   1244
   1245    if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
   1246        s->kb.intr = 1;
   1247        qemu_irq_lower(s->kbint);
   1248    } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
   1249                    !(s->kb.mode & 1)) {
   1250        s->kb.intr = 0;
   1251        qemu_irq_raise(s->kbint);
   1252    }
   1253}