Statistics
| Branch: | Revision:

root / hw / tsc210x.c @ bc24a225

History | View | Annotate | Download (34.1 kB)

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, write to the Free Software Foundation, Inc.,
20
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22

    
23
#include "hw.h"
24
#include "audio/audio.h"
25
#include "qemu-timer.h"
26
#include "console.h"
27
#include "omap.h"        /* For I2SCodec and uWireSlave */
28
#include "devices.h"
29

    
30
#define TSC_DATA_REGISTERS_PAGE                0x0
31
#define TSC_CONTROL_REGISTERS_PAGE        0x1
32
#define TSC_AUDIO_REGISTERS_PAGE        0x2
33

    
34
#define TSC_VERBOSE
35

    
36
#define TSC_CUT_RESOLUTION(value, p)        ((value) >> (16 - resolution[p]))
37

    
38
typedef struct {
39
    qemu_irq pint;
40
    qemu_irq kbint;
41
    qemu_irq davint;
42
    QEMUTimer *timer;
43
    QEMUSoundCard card;
44
    uWireSlave chip;
45
    I2SCodec codec;
46
    uint8_t in_fifo[16384];
47
    uint8_t out_fifo[16384];
48
    uint16_t model;
49

    
50
    int x, y;
51
    int pressure;
52

    
53
    int state, page, offset, irq;
54
    uint16_t command, dav;
55

    
56
    int busy;
57
    int enabled;
58
    int host_mode;
59
    int function;
60
    int nextfunction;
61
    int precision;
62
    int nextprecision;
63
    int filter;
64
    int pin_func;
65
    int ref;
66
    int timing;
67
    int noise;
68

    
69
    uint16_t audio_ctrl1;
70
    uint16_t audio_ctrl2;
71
    uint16_t audio_ctrl3;
72
    uint16_t pll[3];
73
    uint16_t volume;
74
    int64_t volume_change;
75
    int softstep;
76
    uint16_t dac_power;
77
    int64_t powerdown;
78
    uint16_t filter_data[0x14];
79

    
80
    const char *name;
81
    SWVoiceIn *adc_voice[1];
82
    SWVoiceOut *dac_voice[1];
83
    int i2s_rx_rate;
84
    int i2s_tx_rate;
85
    AudioState *audio;
86

    
87
    int tr[8];
88

    
89
    struct {
90
        uint16_t down;
91
        uint16_t mask;
92
        int scan;
93
        int debounce;
94
        int mode;
95
        int intr;
96
    } kb;
97
} TSC210xState;
98

    
99
static const int resolution[4] = { 12, 8, 10, 12 };
100

    
101
#define TSC_MODE_NO_SCAN        0x0
102
#define TSC_MODE_XY_SCAN        0x1
103
#define TSC_MODE_XYZ_SCAN        0x2
104
#define TSC_MODE_X                0x3
105
#define TSC_MODE_Y                0x4
106
#define TSC_MODE_Z                0x5
107
#define TSC_MODE_BAT1                0x6
108
#define TSC_MODE_BAT2                0x7
109
#define TSC_MODE_AUX                0x8
110
#define TSC_MODE_AUX_SCAN        0x9
111
#define TSC_MODE_TEMP1                0xa
112
#define TSC_MODE_PORT_SCAN        0xb
113
#define TSC_MODE_TEMP2                0xc
114
#define TSC_MODE_XX_DRV                0xd
115
#define TSC_MODE_YY_DRV                0xe
116
#define TSC_MODE_YX_DRV                0xf
117

    
118
static const uint16_t mode_regs[16] = {
119
    0x0000,        /* No scan */
120
    0x0600,        /* X, Y scan */
121
    0x0780,        /* X, Y, Z scan */
122
    0x0400,        /* X */
123
    0x0200,        /* Y */
124
    0x0180,        /* Z */
125
    0x0040,        /* BAT1 */
126
    0x0030,        /* BAT2 */
127
    0x0010,        /* AUX */
128
    0x0010,        /* AUX scan */
129
    0x0004,        /* TEMP1 */
130
    0x0070,        /* Port scan */
131
    0x0002,        /* TEMP2 */
132
    0x0000,        /* X+, X- drivers */
133
    0x0000,        /* Y+, Y- drivers */
134
    0x0000,        /* Y+, X- drivers */
135
};
136

    
137
#define X_TRANSFORM(s)                        \
138
    ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
139
#define Y_TRANSFORM(s)                        \
140
    ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
141
#define Z1_TRANSFORM(s)                        \
142
    ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
143
#define Z2_TRANSFORM(s)                        \
144
    ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
145

    
146
#define BAT1_VAL                        0x8660
147
#define BAT2_VAL                        0x0000
148
#define AUX1_VAL                        0x35c0
149
#define AUX2_VAL                        0xffff
150
#define TEMP1_VAL                        0x8c70
151
#define TEMP2_VAL                        0xa5b0
152

    
153
#define TSC_POWEROFF_DELAY                50
154
#define TSC_SOFTSTEP_DELAY                50
155

    
156
static void tsc210x_reset(TSC210xState *s)
157
{
158
    s->state = 0;
159
    s->pin_func = 2;
160
    s->enabled = 0;
161
    s->busy = 0;
162
    s->nextfunction = 0;
163
    s->ref = 0;
164
    s->timing = 0;
165
    s->irq = 0;
166
    s->dav = 0;
167

    
168
    s->audio_ctrl1 = 0x0000;
169
    s->audio_ctrl2 = 0x4410;
170
    s->audio_ctrl3 = 0x0000;
171
    s->pll[0] = 0x1004;
172
    s->pll[1] = 0x0000;
173
    s->pll[2] = 0x1fff;
174
    s->volume = 0xffff;
175
    s->dac_power = 0x8540;
176
    s->softstep = 1;
177
    s->volume_change = 0;
178
    s->powerdown = 0;
179
    s->filter_data[0x00] = 0x6be3;
180
    s->filter_data[0x01] = 0x9666;
181
    s->filter_data[0x02] = 0x675d;
182
    s->filter_data[0x03] = 0x6be3;
183
    s->filter_data[0x04] = 0x9666;
184
    s->filter_data[0x05] = 0x675d;
185
    s->filter_data[0x06] = 0x7d83;
186
    s->filter_data[0x07] = 0x84ee;
187
    s->filter_data[0x08] = 0x7d83;
188
    s->filter_data[0x09] = 0x84ee;
189
    s->filter_data[0x0a] = 0x6be3;
190
    s->filter_data[0x0b] = 0x9666;
191
    s->filter_data[0x0c] = 0x675d;
192
    s->filter_data[0x0d] = 0x6be3;
193
    s->filter_data[0x0e] = 0x9666;
194
    s->filter_data[0x0f] = 0x675d;
195
    s->filter_data[0x10] = 0x7d83;
196
    s->filter_data[0x11] = 0x84ee;
197
    s->filter_data[0x12] = 0x7d83;
198
    s->filter_data[0x13] = 0x84ee;
199

    
200
    s->i2s_tx_rate = 0;
201
    s->i2s_rx_rate = 0;
202

    
203
    s->kb.scan = 1;
204
    s->kb.debounce = 0;
205
    s->kb.mask = 0x0000;
206
    s->kb.mode = 3;
207
    s->kb.intr = 0;
208

    
209
    qemu_set_irq(s->pint, !s->irq);
210
    qemu_set_irq(s->davint, !s->dav);
211
    qemu_irq_raise(s->kbint);
212
}
213

    
214
typedef struct {
215
    int rate;
216
    int dsor;
217
    int fsref;
218
} TSC210xRateInfo;
219

    
220
/*  { rate,  dsor,  fsref } */
221
static const TSC210xRateInfo tsc2101_rates[] = {
222
    /* Fsref / 6.0 */
223
    { 7350,        7,        1 },
224
    { 8000,        7,        0 },
225
    /* Fsref / 5.5 */
226
    { 8018,        6,        1 },
227
    { 8727,        6,        0 },
228
    /* Fsref / 5.0 */
229
    { 8820,        5,        1 },
230
    { 9600,        5,        0 },
231
    /* Fsref / 4.0 */
232
    { 11025,        4,        1 },
233
    { 12000,        4,        0 },
234
    /* Fsref / 3.0 */
235
    { 14700,        3,        1 },
236
    { 16000,        3,        0 },
237
    /* Fsref / 2.0 */
238
    { 22050,        2,        1 },
239
    { 24000,        2,        0 },
240
    /* Fsref / 1.5 */
241
    { 29400,        1,        1 },
242
    { 32000,        1,        0 },
243
    /* Fsref */
244
    { 44100,        0,        1 },
245
    { 48000,        0,        0 },
246

    
247
    { 0,        0,         0 },
248
};
249

    
250
/*  { rate,   dsor, fsref }        */
251
static const TSC210xRateInfo tsc2102_rates[] = {
252
    /* Fsref / 6.0 */
253
    { 7350,        63,        1 },
254
    { 8000,        63,        0 },
255
    /* Fsref / 6.0 */
256
    { 7350,        54,        1 },
257
    { 8000,        54,        0 },
258
    /* Fsref / 5.0 */
259
    { 8820,        45,        1 },
260
    { 9600,        45,        0 },
261
    /* Fsref / 4.0 */
262
    { 11025,        36,        1 },
263
    { 12000,        36,        0 },
264
    /* Fsref / 3.0 */
265
    { 14700,        27,        1 },
266
    { 16000,        27,        0 },
267
    /* Fsref / 2.0 */
268
    { 22050,        18,        1 },
269
    { 24000,        18,        0 },
270
    /* Fsref / 1.5 */
271
    { 29400,        9,        1 },
272
    { 32000,        9,        0 },
273
    /* Fsref */
274
    { 44100,        0,        1 },
275
    { 48000,        0,        0 },
276

    
277
    { 0,        0,         0 },
278
};
279

    
280
static inline void tsc210x_out_flush(TSC210xState *s, int len)
281
{
282
    uint8_t *data = s->codec.out.fifo + s->codec.out.start;
283
    uint8_t *end = data + len;
284

    
285
    while (data < end)
286
        data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
287

    
288
    s->codec.out.len -= len;
289
    if (s->codec.out.len)
290
        memmove(s->codec.out.fifo, end, s->codec.out.len);
291
    s->codec.out.start = 0;
292
}
293

    
294
static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
295
{
296
    if (s->codec.out.len >= free_b) {
297
        tsc210x_out_flush(s, free_b);
298
        return;
299
    }
300

    
301
    s->codec.out.size = MIN(free_b, 16384);
302
    qemu_irq_raise(s->codec.tx_start);
303
}
304

    
305
static void tsc2102_audio_rate_update(TSC210xState *s)
306
{
307
    const TSC210xRateInfo *rate;
308

    
309
    s->codec.tx_rate = 0;
310
    s->codec.rx_rate = 0;
311
    if (s->dac_power & (1 << 15))                                /* PWDNC */
312
        return;
313

    
314
    for (rate = tsc2102_rates; rate->rate; rate ++)
315
        if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&                /* DACFS */
316
                        rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
317
            break;
318
    if (!rate->rate) {
319
        printf("%s: unknown sampling rate configured\n", __FUNCTION__);
320
        return;
321
    }
322

    
323
    s->codec.tx_rate = rate->rate;
324
}
325

    
326
static void tsc2102_audio_output_update(TSC210xState *s)
327
{
328
    int enable;
329
    struct audsettings fmt;
330

    
331
    if (s->dac_voice[0]) {
332
        tsc210x_out_flush(s, s->codec.out.len);
333
        s->codec.out.size = 0;
334
        AUD_set_active_out(s->dac_voice[0], 0);
335
        AUD_close_out(&s->card, s->dac_voice[0]);
336
        s->dac_voice[0] = 0;
337
    }
338
    s->codec.cts = 0;
339

    
340
    enable =
341
            (~s->dac_power & (1 << 15)) &&                        /* PWDNC */
342
            (~s->dac_power & (1 << 10));                        /* DAPWDN */
343
    if (!enable || !s->codec.tx_rate)
344
        return;
345

    
346
    /* Force our own sampling rate even in slave DAC mode */
347
    fmt.endianness = 0;
348
    fmt.nchannels = 2;
349
    fmt.freq = s->codec.tx_rate;
350
    fmt.fmt = AUD_FMT_S16;
351

    
352
    s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
353
                    "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
354
    if (s->dac_voice[0]) {
355
        s->codec.cts = 1;
356
        AUD_set_active_out(s->dac_voice[0], 1);
357
    }
358
}
359

    
360
static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
361
{
362
    switch (reg) {
363
    case 0x00:        /* X */
364
        s->dav &= 0xfbff;
365
        return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
366
                (s->noise & 3);
367

    
368
    case 0x01:        /* Y */
369
        s->noise ++;
370
        s->dav &= 0xfdff;
371
        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
372
                (s->noise & 3);
373

    
374
    case 0x02:        /* Z1 */
375
        s->dav &= 0xfeff;
376
        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
377
                (s->noise & 3);
378

    
379
    case 0x03:        /* Z2 */
380
        s->dav &= 0xff7f;
381
        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
382
                (s->noise & 3);
383

    
384
    case 0x04:        /* KPData */
385
        if ((s->model & 0xff00) == 0x2300) {
386
            if (s->kb.intr && (s->kb.mode & 2)) {
387
                s->kb.intr = 0;
388
                qemu_irq_raise(s->kbint);
389
            }
390
            return s->kb.down;
391
        }
392

    
393
        return 0xffff;
394

    
395
    case 0x05:        /* BAT1 */
396
        s->dav &= 0xffbf;
397
        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision) +
398
                (s->noise & 6);
399

    
400
    case 0x06:        /* BAT2 */
401
        s->dav &= 0xffdf;
402
        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
403

    
404
    case 0x07:        /* AUX1 */
405
        s->dav &= 0xffef;
406
        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
407

    
408
    case 0x08:        /* AUX2 */
409
        s->dav &= 0xfff7;
410
        return 0xffff;
411

    
412
    case 0x09:        /* TEMP1 */
413
        s->dav &= 0xfffb;
414
        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
415
                (s->noise & 5);
416

    
417
    case 0x0a:        /* TEMP2 */
418
        s->dav &= 0xfffd;
419
        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
420
                (s->noise & 3);
421

    
422
    case 0x0b:        /* DAC */
423
        s->dav &= 0xfffe;
424
        return 0xffff;
425

    
426
    default:
427
#ifdef TSC_VERBOSE
428
        fprintf(stderr, "tsc2102_data_register_read: "
429
                        "no such register: 0x%02x\n", reg);
430
#endif
431
        return 0xffff;
432
    }
433
}
434

    
435
static uint16_t tsc2102_control_register_read(
436
                TSC210xState *s, int reg)
437
{
438
    switch (reg) {
439
    case 0x00:        /* TSC ADC */
440
        return (s->pressure << 15) | ((!s->busy) << 14) |
441
                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
442

    
443
    case 0x01:        /* Status / Keypad Control */
444
        if ((s->model & 0xff00) == 0x2100)
445
            return (s->pin_func << 14) | ((!s->enabled) << 13) |
446
                    (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
447
        else
448
            return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) |
449
                    (s->kb.debounce << 11);
450

    
451
    case 0x02:        /* DAC Control */
452
        if ((s->model & 0xff00) == 0x2300)
453
            return s->dac_power & 0x8000;
454
        else
455
            goto bad_reg;
456

    
457
    case 0x03:        /* Reference */
458
        return s->ref;
459

    
460
    case 0x04:        /* Reset */
461
        return 0xffff;
462

    
463
    case 0x05:        /* Configuration */
464
        return s->timing;
465

    
466
    case 0x06:        /* Secondary configuration */
467
        if ((s->model & 0xff00) == 0x2100)
468
            goto bad_reg;
469
        return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2];
470

    
471
    case 0x10:        /* Keypad Mask */
472
        if ((s->model & 0xff00) == 0x2100)
473
            goto bad_reg;
474
        return s->kb.mask;
475

    
476
    default:
477
    bad_reg:
478
#ifdef TSC_VERBOSE
479
        fprintf(stderr, "tsc2102_control_register_read: "
480
                        "no such register: 0x%02x\n", reg);
481
#endif
482
        return 0xffff;
483
    }
484
}
485

    
486
static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
487
{
488
    int l_ch, r_ch;
489
    uint16_t val;
490

    
491
    switch (reg) {
492
    case 0x00:        /* Audio Control 1 */
493
        return s->audio_ctrl1;
494

    
495
    case 0x01:
496
        return 0xff00;
497

    
498
    case 0x02:        /* DAC Volume Control */
499
        return s->volume;
500

    
501
    case 0x03:
502
        return 0x8b00;
503

    
504
    case 0x04:        /* Audio Control 2 */
505
        l_ch = 1;
506
        r_ch = 1;
507
        if (s->softstep && !(s->dac_power & (1 << 10))) {
508
            l_ch = (qemu_get_clock(vm_clock) >
509
                            s->volume_change + TSC_SOFTSTEP_DELAY);
510
            r_ch = (qemu_get_clock(vm_clock) >
511
                            s->volume_change + TSC_SOFTSTEP_DELAY);
512
        }
513

    
514
        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
515

    
516
    case 0x05:        /* Stereo DAC Power Control */
517
        return 0x2aa0 | s->dac_power |
518
                (((s->dac_power & (1 << 10)) &&
519
                  (qemu_get_clock(vm_clock) >
520
                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
521

    
522
    case 0x06:        /* Audio Control 3 */
523
        val = s->audio_ctrl3 | 0x0001;
524
        s->audio_ctrl3 &= 0xff3f;
525
        return val;
526

    
527
    case 0x07:        /* LCH_BASS_BOOST_N0 */
528
    case 0x08:        /* LCH_BASS_BOOST_N1 */
529
    case 0x09:        /* LCH_BASS_BOOST_N2 */
530
    case 0x0a:        /* LCH_BASS_BOOST_N3 */
531
    case 0x0b:        /* LCH_BASS_BOOST_N4 */
532
    case 0x0c:        /* LCH_BASS_BOOST_N5 */
533
    case 0x0d:        /* LCH_BASS_BOOST_D1 */
534
    case 0x0e:        /* LCH_BASS_BOOST_D2 */
535
    case 0x0f:        /* LCH_BASS_BOOST_D4 */
536
    case 0x10:        /* LCH_BASS_BOOST_D5 */
537
    case 0x11:        /* RCH_BASS_BOOST_N0 */
538
    case 0x12:        /* RCH_BASS_BOOST_N1 */
539
    case 0x13:        /* RCH_BASS_BOOST_N2 */
540
    case 0x14:        /* RCH_BASS_BOOST_N3 */
541
    case 0x15:        /* RCH_BASS_BOOST_N4 */
542
    case 0x16:        /* RCH_BASS_BOOST_N5 */
543
    case 0x17:        /* RCH_BASS_BOOST_D1 */
544
    case 0x18:        /* RCH_BASS_BOOST_D2 */
545
    case 0x19:        /* RCH_BASS_BOOST_D4 */
546
    case 0x1a:        /* RCH_BASS_BOOST_D5 */
547
        return s->filter_data[reg - 0x07];
548

    
549
    case 0x1b:        /* PLL Programmability 1 */
550
        return s->pll[0];
551

    
552
    case 0x1c:        /* PLL Programmability 2 */
553
        return s->pll[1];
554

    
555
    case 0x1d:        /* Audio Control 4 */
556
        return (!s->softstep) << 14;
557

    
558
    default:
559
#ifdef TSC_VERBOSE
560
        fprintf(stderr, "tsc2102_audio_register_read: "
561
                        "no such register: 0x%02x\n", reg);
562
#endif
563
        return 0xffff;
564
    }
565
}
566

    
567
static void tsc2102_data_register_write(
568
                TSC210xState *s, int reg, uint16_t value)
569
{
570
    switch (reg) {
571
    case 0x00:        /* X */
572
    case 0x01:        /* Y */
573
    case 0x02:        /* Z1 */
574
    case 0x03:        /* Z2 */
575
    case 0x05:        /* BAT1 */
576
    case 0x06:        /* BAT2 */
577
    case 0x07:        /* AUX1 */
578
    case 0x08:        /* AUX2 */
579
    case 0x09:        /* TEMP1 */
580
    case 0x0a:        /* TEMP2 */
581
        return;
582

    
583
    default:
584
#ifdef TSC_VERBOSE
585
        fprintf(stderr, "tsc2102_data_register_write: "
586
                        "no such register: 0x%02x\n", reg);
587
#endif
588
    }
589
}
590

    
591
static void tsc2102_control_register_write(
592
                TSC210xState *s, int reg, uint16_t value)
593
{
594
    switch (reg) {
595
    case 0x00:        /* TSC ADC */
596
        s->host_mode = value >> 15;
597
        s->enabled = !(value & 0x4000);
598
        if (s->busy && !s->enabled)
599
            qemu_del_timer(s->timer);
600
        s->busy &= s->enabled;
601
        s->nextfunction = (value >> 10) & 0xf;
602
        s->nextprecision = (value >> 8) & 3;
603
        s->filter = value & 0xff;
604
        return;
605

    
606
    case 0x01:        /* Status / Keypad Control */
607
        if ((s->model & 0xff00) == 0x2100)
608
            s->pin_func = value >> 14;
609
        else {
610
            s->kb.scan = (value >> 14) & 1;
611
            s->kb.debounce = (value >> 11) & 7;
612
            if (s->kb.intr && s->kb.scan) {
613
                s->kb.intr = 0;
614
                qemu_irq_raise(s->kbint);
615
            }
616
        }
617
        return;
618

    
619
    case 0x02:        /* DAC Control */
620
        if ((s->model & 0xff00) == 0x2300) {
621
            s->dac_power &= 0x7fff;
622
            s->dac_power |= 0x8000 & value;
623
        } else
624
            goto bad_reg;
625
        break;
626

    
627
    case 0x03:        /* Reference */
628
        s->ref = value & 0x1f;
629
        return;
630

    
631
    case 0x04:        /* Reset */
632
        if (value == 0xbb00) {
633
            if (s->busy)
634
                qemu_del_timer(s->timer);
635
            tsc210x_reset(s);
636
#ifdef TSC_VERBOSE
637
        } else {
638
            fprintf(stderr, "tsc2102_control_register_write: "
639
                            "wrong value written into RESET\n");
640
#endif
641
        }
642
        return;
643

    
644
    case 0x05:        /* Configuration */
645
        s->timing = value & 0x3f;
646
#ifdef TSC_VERBOSE
647
        if (value & ~0x3f)
648
            fprintf(stderr, "tsc2102_control_register_write: "
649
                            "wrong value written into CONFIG\n");
650
#endif
651
        return;
652

    
653
    case 0x06:        /* Secondary configuration */
654
        if ((s->model & 0xff00) == 0x2100)
655
            goto bad_reg;
656
        s->kb.mode = value >> 14;
657
        s->pll[2] = value & 0x3ffff;
658
        return;
659

    
660
    case 0x10:        /* Keypad Mask */
661
        if ((s->model & 0xff00) == 0x2100)
662
            goto bad_reg;
663
        s->kb.mask = value;
664
        return;
665

    
666
    default:
667
    bad_reg:
668
#ifdef TSC_VERBOSE
669
        fprintf(stderr, "tsc2102_control_register_write: "
670
                        "no such register: 0x%02x\n", reg);
671
#endif
672
    }
673
}
674

    
675
static void tsc2102_audio_register_write(
676
                TSC210xState *s, int reg, uint16_t value)
677
{
678
    switch (reg) {
679
    case 0x00:        /* Audio Control 1 */
680
        s->audio_ctrl1 = value & 0x0f3f;
681
#ifdef TSC_VERBOSE
682
        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
683
            fprintf(stderr, "tsc2102_audio_register_write: "
684
                            "wrong value written into Audio 1\n");
685
#endif
686
        tsc2102_audio_rate_update(s);
687
        if (s->audio)
688
            tsc2102_audio_output_update(s);
689
        return;
690

    
691
    case 0x01:
692
#ifdef TSC_VERBOSE
693
        if (value != 0xff00)
694
            fprintf(stderr, "tsc2102_audio_register_write: "
695
                            "wrong value written into reg 0x01\n");
696
#endif
697
        return;
698

    
699
    case 0x02:        /* DAC Volume Control */
700
        s->volume = value;
701
        s->volume_change = qemu_get_clock(vm_clock);
702
        return;
703

    
704
    case 0x03:
705
#ifdef TSC_VERBOSE
706
        if (value != 0x8b00)
707
            fprintf(stderr, "tsc2102_audio_register_write: "
708
                            "wrong value written into reg 0x03\n");
709
#endif
710
        return;
711

    
712
    case 0x04:        /* Audio Control 2 */
713
        s->audio_ctrl2 = value & 0xf7f2;
714
#ifdef TSC_VERBOSE
715
        if (value & ~0xf7fd)
716
            fprintf(stderr, "tsc2102_audio_register_write: "
717
                            "wrong value written into Audio 2\n");
718
#endif
719
        return;
720

    
721
    case 0x05:        /* Stereo DAC Power Control */
722
        if ((value & ~s->dac_power) & (1 << 10))
723
            s->powerdown = qemu_get_clock(vm_clock);
724

    
725
        s->dac_power = value & 0x9543;
726
#ifdef TSC_VERBOSE
727
        if ((value & ~0x9543) != 0x2aa0)
728
            fprintf(stderr, "tsc2102_audio_register_write: "
729
                            "wrong value written into Power\n");
730
#endif
731
        tsc2102_audio_rate_update(s);
732
        if (s->audio)
733
            tsc2102_audio_output_update(s);
734
        return;
735

    
736
    case 0x06:        /* Audio Control 3 */
737
        s->audio_ctrl3 &= 0x00c0;
738
        s->audio_ctrl3 |= value & 0xf800;
739
#ifdef TSC_VERBOSE
740
        if (value & ~0xf8c7)
741
            fprintf(stderr, "tsc2102_audio_register_write: "
742
                            "wrong value written into Audio 3\n");
743
#endif
744
        if (s->audio)
745
            tsc2102_audio_output_update(s);
746
        return;
747

    
748
    case 0x07:        /* LCH_BASS_BOOST_N0 */
749
    case 0x08:        /* LCH_BASS_BOOST_N1 */
750
    case 0x09:        /* LCH_BASS_BOOST_N2 */
751
    case 0x0a:        /* LCH_BASS_BOOST_N3 */
752
    case 0x0b:        /* LCH_BASS_BOOST_N4 */
753
    case 0x0c:        /* LCH_BASS_BOOST_N5 */
754
    case 0x0d:        /* LCH_BASS_BOOST_D1 */
755
    case 0x0e:        /* LCH_BASS_BOOST_D2 */
756
    case 0x0f:        /* LCH_BASS_BOOST_D4 */
757
    case 0x10:        /* LCH_BASS_BOOST_D5 */
758
    case 0x11:        /* RCH_BASS_BOOST_N0 */
759
    case 0x12:        /* RCH_BASS_BOOST_N1 */
760
    case 0x13:        /* RCH_BASS_BOOST_N2 */
761
    case 0x14:        /* RCH_BASS_BOOST_N3 */
762
    case 0x15:        /* RCH_BASS_BOOST_N4 */
763
    case 0x16:        /* RCH_BASS_BOOST_N5 */
764
    case 0x17:        /* RCH_BASS_BOOST_D1 */
765
    case 0x18:        /* RCH_BASS_BOOST_D2 */
766
    case 0x19:        /* RCH_BASS_BOOST_D4 */
767
    case 0x1a:        /* RCH_BASS_BOOST_D5 */
768
        s->filter_data[reg - 0x07] = value;
769
        return;
770

    
771
    case 0x1b:        /* PLL Programmability 1 */
772
        s->pll[0] = value & 0xfffc;
773
#ifdef TSC_VERBOSE
774
        if (value & ~0xfffc)
775
            fprintf(stderr, "tsc2102_audio_register_write: "
776
                            "wrong value written into PLL 1\n");
777
#endif
778
        return;
779

    
780
    case 0x1c:        /* PLL Programmability 2 */
781
        s->pll[1] = value & 0xfffc;
782
#ifdef TSC_VERBOSE
783
        if (value & ~0xfffc)
784
            fprintf(stderr, "tsc2102_audio_register_write: "
785
                            "wrong value written into PLL 2\n");
786
#endif
787
        return;
788

    
789
    case 0x1d:        /* Audio Control 4 */
790
        s->softstep = !(value & 0x4000);
791
#ifdef TSC_VERBOSE
792
        if (value & ~0x4000)
793
            fprintf(stderr, "tsc2102_audio_register_write: "
794
                            "wrong value written into Audio 4\n");
795
#endif
796
        return;
797

    
798
    default:
799
#ifdef TSC_VERBOSE
800
        fprintf(stderr, "tsc2102_audio_register_write: "
801
                        "no such register: 0x%02x\n", reg);
802
#endif
803
    }
804
}
805

    
806
/* This handles most of the chip logic.  */
807
static void tsc210x_pin_update(TSC210xState *s)
808
{
809
    int64_t expires;
810
    int pin_state;
811

    
812
    switch (s->pin_func) {
813
    case 0:
814
        pin_state = s->pressure;
815
        break;
816
    case 1:
817
        pin_state = !!s->dav;
818
        break;
819
    case 2:
820
    default:
821
        pin_state = s->pressure && !s->dav;
822
    }
823

    
824
    if (!s->enabled)
825
        pin_state = 0;
826

    
827
    if (pin_state != s->irq) {
828
        s->irq = pin_state;
829
        qemu_set_irq(s->pint, !s->irq);
830
    }
831

    
832
    switch (s->nextfunction) {
833
    case TSC_MODE_XY_SCAN:
834
    case TSC_MODE_XYZ_SCAN:
835
        if (!s->pressure)
836
            return;
837
        break;
838

    
839
    case TSC_MODE_X:
840
    case TSC_MODE_Y:
841
    case TSC_MODE_Z:
842
        if (!s->pressure)
843
            return;
844
        /* Fall through */
845
    case TSC_MODE_BAT1:
846
    case TSC_MODE_BAT2:
847
    case TSC_MODE_AUX:
848
    case TSC_MODE_TEMP1:
849
    case TSC_MODE_TEMP2:
850
        if (s->dav)
851
            s->enabled = 0;
852
        break;
853

    
854
    case TSC_MODE_AUX_SCAN:
855
    case TSC_MODE_PORT_SCAN:
856
        break;
857

    
858
    case TSC_MODE_NO_SCAN:
859
    case TSC_MODE_XX_DRV:
860
    case TSC_MODE_YY_DRV:
861
    case TSC_MODE_YX_DRV:
862
    default:
863
        return;
864
    }
865

    
866
    if (!s->enabled || s->busy || s->dav)
867
        return;
868

    
869
    s->busy = 1;
870
    s->precision = s->nextprecision;
871
    s->function = s->nextfunction;
872
    expires = qemu_get_clock(vm_clock) + (ticks_per_sec >> 10);
873
    qemu_mod_timer(s->timer, expires);
874
}
875

    
876
static uint16_t tsc210x_read(TSC210xState *s)
877
{
878
    uint16_t ret = 0x0000;
879

    
880
    if (!s->command)
881
        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
882

    
883
    switch (s->page) {
884
    case TSC_DATA_REGISTERS_PAGE:
885
        ret = tsc2102_data_register_read(s, s->offset);
886
        if (!s->dav)
887
            qemu_irq_raise(s->davint);
888
        break;
889
    case TSC_CONTROL_REGISTERS_PAGE:
890
        ret = tsc2102_control_register_read(s, s->offset);
891
        break;
892
    case TSC_AUDIO_REGISTERS_PAGE:
893
        ret = tsc2102_audio_register_read(s, s->offset);
894
        break;
895
    default:
896
        hw_error("tsc210x_read: wrong memory page\n");
897
    }
898

    
899
    tsc210x_pin_update(s);
900

    
901
    /* Allow sequential reads.  */
902
    s->offset ++;
903
    s->state = 0;
904
    return ret;
905
}
906

    
907
static void tsc210x_write(TSC210xState *s, uint16_t value)
908
{
909
    /*
910
     * This is a two-state state machine for reading
911
     * command and data every second time.
912
     */
913
    if (!s->state) {
914
        s->command = value >> 15;
915
        s->page = (value >> 11) & 0x0f;
916
        s->offset = (value >> 5) & 0x3f;
917
        s->state = 1;
918
    } else {
919
        if (s->command)
920
            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
921
        else
922
            switch (s->page) {
923
            case TSC_DATA_REGISTERS_PAGE:
924
                tsc2102_data_register_write(s, s->offset, value);
925
                break;
926
            case TSC_CONTROL_REGISTERS_PAGE:
927
                tsc2102_control_register_write(s, s->offset, value);
928
                break;
929
            case TSC_AUDIO_REGISTERS_PAGE:
930
                tsc2102_audio_register_write(s, s->offset, value);
931
                break;
932
            default:
933
                hw_error("tsc210x_write: wrong memory page\n");
934
            }
935

    
936
        tsc210x_pin_update(s);
937
        s->state = 0;
938
    }
939
}
940

    
941
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
942
{
943
    TSC210xState *s = opaque;
944
    uint32_t ret = 0;
945

    
946
    if (len != 16)
947
        hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
948

    
949
    /* TODO: sequential reads etc - how do we make sure the host doesn't
950
     * unintentionally read out a conversion result from a register while
951
     * transmitting the command word of the next command?  */
952
    if (!value || (s->state && s->command))
953
        ret = tsc210x_read(s);
954
    if (value || (s->state && !s->command))
955
        tsc210x_write(s, value);
956

    
957
    return ret;
958
}
959

    
960
static void tsc210x_timer_tick(void *opaque)
961
{
962
    TSC210xState *s = opaque;
963

    
964
    /* Timer ticked -- a set of conversions has been finished.  */
965

    
966
    if (!s->busy)
967
        return;
968

    
969
    s->busy = 0;
970
    s->dav |= mode_regs[s->function];
971
    tsc210x_pin_update(s);
972
    qemu_irq_lower(s->davint);
973
}
974

    
975
static void tsc210x_touchscreen_event(void *opaque,
976
                int x, int y, int z, int buttons_state)
977
{
978
    TSC210xState *s = opaque;
979
    int p = s->pressure;
980

    
981
    if (buttons_state) {
982
        s->x = x;
983
        s->y = y;
984
    }
985
    s->pressure = !!buttons_state;
986

    
987
    /*
988
     * Note: We would get better responsiveness in the guest by
989
     * signaling TS events immediately, but for now we simulate
990
     * the first conversion delay for sake of correctness.
991
     */
992
    if (p != s->pressure)
993
        tsc210x_pin_update(s);
994
}
995

    
996
static void tsc210x_i2s_swallow(TSC210xState *s)
997
{
998
    if (s->dac_voice[0])
999
        tsc210x_out_flush(s, s->codec.out.len);
1000
    else
1001
        s->codec.out.len = 0;
1002
}
1003

    
1004
static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
1005
{
1006
    s->i2s_tx_rate = out;
1007
    s->i2s_rx_rate = in;
1008
}
1009

    
1010
static void tsc210x_save(QEMUFile *f, void *opaque)
1011
{
1012
    TSC210xState *s = (TSC210xState *) opaque;
1013
    int64_t now = qemu_get_clock(vm_clock);
1014
    int i;
1015

    
1016
    qemu_put_be16(f, s->x);
1017
    qemu_put_be16(f, s->y);
1018
    qemu_put_byte(f, s->pressure);
1019

    
1020
    qemu_put_byte(f, s->state);
1021
    qemu_put_byte(f, s->page);
1022
    qemu_put_byte(f, s->offset);
1023
    qemu_put_byte(f, s->command);
1024

    
1025
    qemu_put_byte(f, s->irq);
1026
    qemu_put_be16s(f, &s->dav);
1027

    
1028
    qemu_put_timer(f, s->timer);
1029
    qemu_put_byte(f, s->enabled);
1030
    qemu_put_byte(f, s->host_mode);
1031
    qemu_put_byte(f, s->function);
1032
    qemu_put_byte(f, s->nextfunction);
1033
    qemu_put_byte(f, s->precision);
1034
    qemu_put_byte(f, s->nextprecision);
1035
    qemu_put_byte(f, s->filter);
1036
    qemu_put_byte(f, s->pin_func);
1037
    qemu_put_byte(f, s->ref);
1038
    qemu_put_byte(f, s->timing);
1039
    qemu_put_be32(f, s->noise);
1040

    
1041
    qemu_put_be16s(f, &s->audio_ctrl1);
1042
    qemu_put_be16s(f, &s->audio_ctrl2);
1043
    qemu_put_be16s(f, &s->audio_ctrl3);
1044
    qemu_put_be16s(f, &s->pll[0]);
1045
    qemu_put_be16s(f, &s->pll[1]);
1046
    qemu_put_be16s(f, &s->volume);
1047
    qemu_put_sbe64(f, (s->volume_change - now));
1048
    qemu_put_sbe64(f, (s->powerdown - now));
1049
    qemu_put_byte(f, s->softstep);
1050
    qemu_put_be16s(f, &s->dac_power);
1051

    
1052
    for (i = 0; i < 0x14; i ++)
1053
        qemu_put_be16s(f, &s->filter_data[i]);
1054
}
1055

    
1056
static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
1057
{
1058
    TSC210xState *s = (TSC210xState *) opaque;
1059
    int64_t now = qemu_get_clock(vm_clock);
1060
    int i;
1061

    
1062
    s->x = qemu_get_be16(f);
1063
    s->y = qemu_get_be16(f);
1064
    s->pressure = qemu_get_byte(f);
1065

    
1066
    s->state = qemu_get_byte(f);
1067
    s->page = qemu_get_byte(f);
1068
    s->offset = qemu_get_byte(f);
1069
    s->command = qemu_get_byte(f);
1070

    
1071
    s->irq = qemu_get_byte(f);
1072
    qemu_get_be16s(f, &s->dav);
1073

    
1074
    qemu_get_timer(f, s->timer);
1075
    s->enabled = qemu_get_byte(f);
1076
    s->host_mode = qemu_get_byte(f);
1077
    s->function = qemu_get_byte(f);
1078
    s->nextfunction = qemu_get_byte(f);
1079
    s->precision = qemu_get_byte(f);
1080
    s->nextprecision = qemu_get_byte(f);
1081
    s->filter = qemu_get_byte(f);
1082
    s->pin_func = qemu_get_byte(f);
1083
    s->ref = qemu_get_byte(f);
1084
    s->timing = qemu_get_byte(f);
1085
    s->noise = qemu_get_be32(f);
1086

    
1087
    qemu_get_be16s(f, &s->audio_ctrl1);
1088
    qemu_get_be16s(f, &s->audio_ctrl2);
1089
    qemu_get_be16s(f, &s->audio_ctrl3);
1090
    qemu_get_be16s(f, &s->pll[0]);
1091
    qemu_get_be16s(f, &s->pll[1]);
1092
    qemu_get_be16s(f, &s->volume);
1093
    s->volume_change = qemu_get_sbe64(f) + now;
1094
    s->powerdown = qemu_get_sbe64(f) + now;
1095
    s->softstep = qemu_get_byte(f);
1096
    qemu_get_be16s(f, &s->dac_power);
1097

    
1098
    for (i = 0; i < 0x14; i ++)
1099
        qemu_get_be16s(f, &s->filter_data[i]);
1100

    
1101
    s->busy = qemu_timer_pending(s->timer);
1102
    qemu_set_irq(s->pint, !s->irq);
1103
    qemu_set_irq(s->davint, !s->dav);
1104

    
1105
    return 0;
1106
}
1107

    
1108
uWireSlave *tsc2102_init(qemu_irq pint, AudioState *audio)
1109
{
1110
    TSC210xState *s;
1111

    
1112
    s = (TSC210xState *)
1113
            qemu_mallocz(sizeof(TSC210xState));
1114
    memset(s, 0, sizeof(TSC210xState));
1115
    s->x = 160;
1116
    s->y = 160;
1117
    s->pressure = 0;
1118
    s->precision = s->nextprecision = 0;
1119
    s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);
1120
    s->pint = pint;
1121
    s->model = 0x2102;
1122
    s->name = "tsc2102";
1123
    s->audio = audio;
1124

    
1125
    s->tr[0] = 0;
1126
    s->tr[1] = 1;
1127
    s->tr[2] = 1;
1128
    s->tr[3] = 0;
1129
    s->tr[4] = 1;
1130
    s->tr[5] = 0;
1131
    s->tr[6] = 1;
1132
    s->tr[7] = 0;
1133

    
1134
    s->chip.opaque = s;
1135
    s->chip.send = (void *) tsc210x_write;
1136
    s->chip.receive = (void *) tsc210x_read;
1137

    
1138
    s->codec.opaque = s;
1139
    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1140
    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1141
    s->codec.in.fifo = s->in_fifo;
1142
    s->codec.out.fifo = s->out_fifo;
1143

    
1144
    tsc210x_reset(s);
1145

    
1146
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1147
                    "QEMU TSC2102-driven Touchscreen");
1148

    
1149
    if (s->audio)
1150
        AUD_register_card(s->audio, s->name, &s->card);
1151

    
1152
    qemu_register_reset((void *) tsc210x_reset, s);
1153
    register_savevm(s->name, -1, 0,
1154
                    tsc210x_save, tsc210x_load, s);
1155

    
1156
    return &s->chip;
1157
}
1158

    
1159
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq,
1160
                qemu_irq dav, AudioState *audio)
1161
{
1162
    TSC210xState *s;
1163

    
1164
    s = (TSC210xState *)
1165
            qemu_mallocz(sizeof(TSC210xState));
1166
    memset(s, 0, sizeof(TSC210xState));
1167
    s->x = 400;
1168
    s->y = 240;
1169
    s->pressure = 0;
1170
    s->precision = s->nextprecision = 0;
1171
    s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);
1172
    s->pint = penirq;
1173
    s->kbint = kbirq;
1174
    s->davint = dav;
1175
    s->model = 0x2301;
1176
    s->name = "tsc2301";
1177
    s->audio = audio;
1178

    
1179
    s->tr[0] = 0;
1180
    s->tr[1] = 1;
1181
    s->tr[2] = 1;
1182
    s->tr[3] = 0;
1183
    s->tr[4] = 1;
1184
    s->tr[5] = 0;
1185
    s->tr[6] = 1;
1186
    s->tr[7] = 0;
1187

    
1188
    s->chip.opaque = s;
1189
    s->chip.send = (void *) tsc210x_write;
1190
    s->chip.receive = (void *) tsc210x_read;
1191

    
1192
    s->codec.opaque = s;
1193
    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1194
    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1195
    s->codec.in.fifo = s->in_fifo;
1196
    s->codec.out.fifo = s->out_fifo;
1197

    
1198
    tsc210x_reset(s);
1199

    
1200
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1201
                    "QEMU TSC2301-driven Touchscreen");
1202

    
1203
    if (s->audio)
1204
        AUD_register_card(s->audio, s->name, &s->card);
1205

    
1206
    qemu_register_reset((void *) tsc210x_reset, s);
1207
    register_savevm(s->name, -1, 0, tsc210x_save, tsc210x_load, s);
1208

    
1209
    return &s->chip;
1210
}
1211

    
1212
I2SCodec *tsc210x_codec(uWireSlave *chip)
1213
{
1214
    TSC210xState *s = (TSC210xState *) chip->opaque;
1215

    
1216
    return &s->codec;
1217
}
1218

    
1219
/*
1220
 * Use tslib generated calibration data to generate ADC input values
1221
 * from the touchscreen.  Assuming 12-bit precision was used during
1222
 * tslib calibration.
1223
 */
1224
void tsc210x_set_transform(uWireSlave *chip,
1225
                MouseTransformInfo *info)
1226
{
1227
    TSC210xState *s = (TSC210xState *) chip->opaque;
1228
#if 0
1229
    int64_t ltr[8];
1230

1231
    ltr[0] = (int64_t) info->a[1] * info->y;
1232
    ltr[1] = (int64_t) info->a[4] * info->x;
1233
    ltr[2] = (int64_t) info->a[1] * info->a[3] -
1234
            (int64_t) info->a[4] * info->a[0];
1235
    ltr[3] = (int64_t) info->a[2] * info->a[4] -
1236
            (int64_t) info->a[5] * info->a[1];
1237
    ltr[4] = (int64_t) info->a[0] * info->y;
1238
    ltr[5] = (int64_t) info->a[3] * info->x;
1239
    ltr[6] = (int64_t) info->a[4] * info->a[0] -
1240
            (int64_t) info->a[1] * info->a[3];
1241
    ltr[7] = (int64_t) info->a[2] * info->a[3] -
1242
            (int64_t) info->a[5] * info->a[0];
1243

1244
    /* Avoid integer overflow */
1245
    s->tr[0] = ltr[0] >> 11;
1246
    s->tr[1] = ltr[1] >> 11;
1247
    s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
1248
    s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
1249
    s->tr[4] = ltr[4] >> 11;
1250
    s->tr[5] = ltr[5] >> 11;
1251
    s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
1252
    s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
1253
#else
1254

    
1255
    /* This version assumes touchscreen X & Y axis are parallel or
1256
     * perpendicular to LCD's  X & Y axis in some way.  */
1257
    if (abs(info->a[0]) > abs(info->a[1])) {
1258
        s->tr[0] = 0;
1259
        s->tr[1] = -info->a[6] * info->x;
1260
        s->tr[2] = info->a[0];
1261
        s->tr[3] = -info->a[2] / info->a[0];
1262
        s->tr[4] = info->a[6] * info->y;
1263
        s->tr[5] = 0;
1264
        s->tr[6] = info->a[4];
1265
        s->tr[7] = -info->a[5] / info->a[4];
1266
    } else {
1267
        s->tr[0] = info->a[6] * info->y;
1268
        s->tr[1] = 0;
1269
        s->tr[2] = info->a[1];
1270
        s->tr[3] = -info->a[2] / info->a[1];
1271
        s->tr[4] = 0;
1272
        s->tr[5] = -info->a[6] * info->x;
1273
        s->tr[6] = info->a[3];
1274
        s->tr[7] = -info->a[5] / info->a[3];
1275
    }
1276

    
1277
    s->tr[0] >>= 11;
1278
    s->tr[1] >>= 11;
1279
    s->tr[3] <<= 4;
1280
    s->tr[4] >>= 11;
1281
    s->tr[5] >>= 11;
1282
    s->tr[7] <<= 4;
1283
#endif
1284
}
1285

    
1286
void tsc210x_key_event(uWireSlave *chip, int key, int down)
1287
{
1288
    TSC210xState *s = (TSC210xState *) chip->opaque;
1289

    
1290
    if (down)
1291
        s->kb.down |= 1 << key;
1292
    else
1293
        s->kb.down &= ~(1 << key);
1294

    
1295
    if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
1296
        s->kb.intr = 1;
1297
        qemu_irq_lower(s->kbint);
1298
    } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
1299
                    !(s->kb.mode & 1)) {
1300
        s->kb.intr = 0;
1301
        qemu_irq_raise(s->kbint);
1302
    }
1303
}