Statistics
| Branch: | Revision:

root / hw / tsc210x.c @ d8f699cb

History | View | Annotate | Download (27.2 kB)

1
/*
2
 * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
3
 *
4
 * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
 * MA 02111-1307 USA
20
 */
21

    
22
#include "vl.h"
23

    
24
#define TSC_DATA_REGISTERS_PAGE                0x0
25
#define TSC_CONTROL_REGISTERS_PAGE        0x1
26
#define TSC_AUDIO_REGISTERS_PAGE        0x2
27

    
28
#define TSC_VERBOSE
29

    
30
#define TSC_CUT_RESOLUTION(value, p)        ((value) >> (16 - resolution[p]))
31

    
32
struct tsc210x_state_s {
33
    qemu_irq pint;
34
    QEMUTimer *timer;
35
    QEMUSoundCard card;
36
    struct uwire_slave_s chip;
37
    struct i2s_codec_s codec;
38
    uint8_t in_fifo[16384];
39
    uint8_t out_fifo[16384];
40

    
41
    int x, y;
42
    int pressure;
43

    
44
    int state, page, offset, irq;
45
    uint16_t command, dav;
46

    
47
    int busy;
48
    int enabled;
49
    int host_mode;
50
    int function;
51
    int nextfunction;
52
    int precision;
53
    int nextprecision;
54
    int filter;
55
    int pin_func;
56
    int ref;
57
    int timing;
58
    int noise;
59

    
60
    uint16_t audio_ctrl1;
61
    uint16_t audio_ctrl2;
62
    uint16_t audio_ctrl3;
63
    uint16_t pll[2];
64
    uint16_t volume;
65
    int64_t volume_change;
66
    int softstep;
67
    uint16_t dac_power;
68
    int64_t powerdown;
69
    uint16_t filter_data[0x14];
70

    
71
    const char *name;
72
    SWVoiceIn *adc_voice[1];
73
    SWVoiceOut *dac_voice[1];
74
    int i2s_rx_rate;
75
    int i2s_tx_rate;
76
    AudioState *audio;
77
};
78

    
79
static const int resolution[4] = { 12, 8, 10, 12 };
80

    
81
#define TSC_MODE_NO_SCAN        0x0
82
#define TSC_MODE_XY_SCAN        0x1
83
#define TSC_MODE_XYZ_SCAN        0x2
84
#define TSC_MODE_X                0x3
85
#define TSC_MODE_Y                0x4
86
#define TSC_MODE_Z                0x5
87
#define TSC_MODE_BAT1                0x6
88
#define TSC_MODE_BAT2                0x7
89
#define TSC_MODE_AUX                0x8
90
#define TSC_MODE_AUX_SCAN        0x9
91
#define TSC_MODE_TEMP1                0xa
92
#define TSC_MODE_PORT_SCAN        0xb
93
#define TSC_MODE_TEMP2                0xc
94
#define TSC_MODE_XX_DRV                0xd
95
#define TSC_MODE_YY_DRV                0xe
96
#define TSC_MODE_YX_DRV                0xf
97

    
98
static const uint16_t mode_regs[16] = {
99
    0x0000,        /* No scan */
100
    0x0600,        /* X, Y scan */
101
    0x0780,        /* X, Y, Z scan */
102
    0x0400,        /* X */
103
    0x0200,        /* Y */
104
    0x0180,        /* Z */
105
    0x0040,        /* BAT1 */
106
    0x0030,        /* BAT2 */
107
    0x0010,        /* AUX */
108
    0x0010,        /* AUX scan */
109
    0x0004,        /* TEMP1 */
110
    0x0070,        /* Port scan */
111
    0x0002,        /* TEMP2 */
112
    0x0000,        /* X+, X- drivers */
113
    0x0000,        /* Y+, Y- drivers */
114
    0x0000,        /* Y+, X- drivers */
115
};
116

    
117
/*
118
 * Convert screen coordinates to arbitrary values that the
119
 * touchscreen in my Palm Tungsten E device returns.
120
 * This shouldn't really matter (because the guest system
121
 * should calibrate the touchscreen anyway), but let's
122
 * imitate some real hardware.
123
 */
124
#define X_TRANSFORM(value)                \
125
    ((3850 - ((int) (value) * (3850 - 250) / 32768)) << 4)
126
#define Y_TRANSFORM(value)                \
127
    ((150 + ((int) (value) * (3037 - 150) / 32768)) << 4)
128
#define Z1_TRANSFORM(s)                        \
129
    ((400 - (s)->x + ((s)->pressure << 9)) << 4)
130
#define Z2_TRANSFORM(s)                        \
131
    ((4000 + (s)->y - ((s)->pressure << 10)) << 4)
132
#define BAT1_VAL                        0x8660
133
#define BAT2_VAL                        0x0000
134
#define AUX1_VAL                        0x35c0
135
#define AUX2_VAL                        0xffff
136
#define TEMP1_VAL                        0x8c70
137
#define TEMP2_VAL                        0xa5b0
138

    
139
#define TSC_POWEROFF_DELAY                50
140
#define TSC_SOFTSTEP_DELAY                50
141

    
142
static void tsc210x_reset(struct tsc210x_state_s *s)
143
{
144
    s->state = 0;
145
    s->pin_func = 2;
146
    s->enabled = 0;
147
    s->busy = 0;
148
    s->nextfunction = 0;
149
    s->ref = 0;
150
    s->timing = 0;
151
    s->irq = 0;
152
    s->dav = 0;
153

    
154
    s->audio_ctrl1 = 0x0000;
155
    s->audio_ctrl2 = 0x4410;
156
    s->audio_ctrl3 = 0x0000;
157
    s->pll[0] = 0x1004;
158
    s->pll[1] = 0x0000;
159
    s->volume = 0xffff;
160
    s->dac_power = 0x8540;
161
    s->softstep = 1;
162
    s->volume_change = 0;
163
    s->powerdown = 0;
164
    s->filter_data[0x00] = 0x6be3;
165
    s->filter_data[0x01] = 0x9666;
166
    s->filter_data[0x02] = 0x675d;
167
    s->filter_data[0x03] = 0x6be3;
168
    s->filter_data[0x04] = 0x9666;
169
    s->filter_data[0x05] = 0x675d;
170
    s->filter_data[0x06] = 0x7d83;
171
    s->filter_data[0x07] = 0x84ee;
172
    s->filter_data[0x08] = 0x7d83;
173
    s->filter_data[0x09] = 0x84ee;
174
    s->filter_data[0x0a] = 0x6be3;
175
    s->filter_data[0x0b] = 0x9666;
176
    s->filter_data[0x0c] = 0x675d;
177
    s->filter_data[0x0d] = 0x6be3;
178
    s->filter_data[0x0e] = 0x9666;
179
    s->filter_data[0x0f] = 0x675d;
180
    s->filter_data[0x10] = 0x7d83;
181
    s->filter_data[0x11] = 0x84ee;
182
    s->filter_data[0x12] = 0x7d83;
183
    s->filter_data[0x13] = 0x84ee;
184

    
185
    s->i2s_tx_rate = 0;
186
    s->i2s_rx_rate = 0;
187

    
188
    qemu_set_irq(s->pint, !s->irq);
189
}
190

    
191
struct tsc210x_rate_info_s {
192
    int rate;
193
    int dsor;
194
    int fsref;
195
};
196

    
197
/*  { rate,  dsor,  fsref } */
198
static const struct tsc210x_rate_info_s tsc2101_rates[] = {
199
    /* Fsref / 6.0 */
200
    { 7350,        7,        1 },
201
    { 8000,        7,        0 },
202
    /* Fsref / 5.5 */
203
    { 8018,        6,        1 },
204
    { 8727,        6,        0 },
205
    /* Fsref / 5.0 */
206
    { 8820,        5,        1 },
207
    { 9600,        5,        0 },
208
    /* Fsref / 4.0 */
209
    { 11025,        4,        1 },
210
    { 12000,        4,        0 },
211
    /* Fsref / 3.0 */
212
    { 14700,        3,        1 },
213
    { 16000,        3,        0 },
214
    /* Fsref / 2.0 */
215
    { 22050,        2,        1 },
216
    { 24000,        2,        0 },
217
    /* Fsref / 1.5 */
218
    { 29400,        1,        1 },
219
    { 32000,        1,        0 },
220
    /* Fsref */
221
    { 44100,        0,        1 },
222
    { 48000,        0,        0 },
223

    
224
    { 0,        0,         0 },
225
};
226

    
227
/*  { rate,   dsor, fsref }        */
228
static const struct tsc210x_rate_info_s tsc2102_rates[] = {
229
    /* Fsref / 6.0 */
230
    { 7350,        63,        1 },
231
    { 8000,        63,        0 },
232
    /* Fsref / 6.0 */
233
    { 7350,        54,        1 },
234
    { 8000,        54,        0 },
235
    /* Fsref / 5.0 */
236
    { 8820,        45,        1 },
237
    { 9600,        45,        0 },
238
    /* Fsref / 4.0 */
239
    { 11025,        36,        1 },
240
    { 12000,        36,        0 },
241
    /* Fsref / 3.0 */
242
    { 14700,        27,        1 },
243
    { 16000,        27,        0 },
244
    /* Fsref / 2.0 */
245
    { 22050,        18,        1 },
246
    { 24000,        18,        0 },
247
    /* Fsref / 1.5 */
248
    { 29400,        9,        1 },
249
    { 32000,        9,        0 },
250
    /* Fsref */
251
    { 44100,        0,        1 },
252
    { 48000,        0,        0 },
253

    
254
    { 0,        0,         0 },
255
};
256

    
257
static inline void tsc210x_out_flush(struct tsc210x_state_s *s, int len)
258
{
259
    uint8_t *data = s->codec.out.fifo + s->codec.out.start;
260
    uint8_t *end = data + len;
261

    
262
    while (data < end)
263
        data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
264

    
265
    s->codec.out.len -= len;
266
    if (s->codec.out.len)
267
        memmove(s->codec.out.fifo, end, s->codec.out.len);
268
    s->codec.out.start = 0;
269
}
270

    
271
static void tsc210x_audio_out_cb(struct tsc210x_state_s *s, int free_b)
272
{
273
    if (s->codec.out.len >= free_b) {
274
        tsc210x_out_flush(s, free_b);
275
        return;
276
    }
277

    
278
    s->codec.out.size = MIN(free_b, 16384);
279
    qemu_irq_raise(s->codec.tx_start);
280
}
281

    
282
static void tsc2102_audio_set_format(struct tsc210x_state_s *s)
283
{
284
    int enable;
285
    const struct tsc210x_rate_info_s *rate;
286
    audsettings_t fmt;
287

    
288
    if (s->dac_voice[0]) {
289
        tsc210x_out_flush(s, s->codec.out.len);
290
        s->codec.out.size = 0;
291
        AUD_set_active_out(s->dac_voice[0], 0);
292
        AUD_close_out(&s->card, s->dac_voice[0]);
293
        s->dac_voice[0] = 0;
294
    }
295

    
296
    enable =
297
            (~s->dac_power & (1 << 15)) &&                        /* PWDNC */
298
            (~s->dac_power & (1 << 10));                        /* DAPWDN */
299
    if (!enable)
300
        return;
301

    
302
    for (rate = tsc2102_rates; rate->rate; rate ++)
303
        if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&                /* DACFS */
304
                        rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
305
            break;
306
    if (!rate->rate) {
307
        printf("%s: unknown sampling rate configured\n", __FUNCTION__);
308
        return;
309
    }
310

    
311
    /* Force our own sampling rate even in slave DAC mode */
312
    fmt.endianness = 0;
313
    fmt.nchannels = 2;
314
    fmt.freq = rate->rate;
315
    fmt.fmt = AUD_FMT_S16;
316

    
317
    s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
318
                    "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
319
    if (s->dac_voice[0])
320
        AUD_set_active_out(s->dac_voice[0], 1);
321
}
322

    
323
static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
324
{
325
    switch (reg) {
326
    case 0x00:        /* X */
327
        s->dav &= 0xfbff;
328
        return TSC_CUT_RESOLUTION(X_TRANSFORM(s->x), s->precision) +
329
                (s->noise & 3);
330

    
331
    case 0x01:        /* Y */
332
        s->noise ++;
333
        s->dav &= 0xfdff;
334
        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s->y), s->precision) ^
335
                (s->noise & 3);
336

    
337
    case 0x02:        /* Z1 */
338
        s->dav &= 0xfeff;
339
        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
340
                (s->noise & 3);
341

    
342
    case 0x03:        /* Z2 */
343
        s->dav &= 0xff7f;
344
        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
345
                (s->noise & 3);
346

    
347
    case 0x04:        /* KPData */
348
        return 0xffff;
349

    
350
    case 0x05:        /* BAT1 */
351
        s->dav &= 0xffbf;
352
        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision);
353

    
354
    case 0x06:        /* BAT2 */
355
        s->dav &= 0xffdf;
356
        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
357

    
358
    case 0x07:        /* AUX1 */
359
        s->dav &= 0xffef;
360
        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
361

    
362
    case 0x08:        /* AUX2 */
363
        s->dav &= 0xfff7;
364
        return 0xffff;
365

    
366
    case 0x09:        /* TEMP1 */
367
        s->dav &= 0xfffb;
368
        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision);
369

    
370
    case 0x0a:        /* TEMP2 */
371
        s->dav &= 0xfffd;
372
        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision);
373

    
374
    case 0x0b:        /* DAC */
375
        s->dav &= 0xfffe;
376
        return 0xffff;
377

    
378
    default:
379
#ifdef TSC_VERBOSE
380
        fprintf(stderr, "tsc2102_data_register_read: "
381
                        "no such register: 0x%02x\n", reg);
382
#endif
383
        return 0xffff;
384
    }
385
}
386

    
387
static uint16_t tsc2102_control_register_read(
388
                struct tsc210x_state_s *s, int reg)
389
{
390
    switch (reg) {
391
    case 0x00:        /* TSC ADC */
392
        return (s->pressure << 15) | ((!s->busy) << 14) |
393
                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
394

    
395
    case 0x01:        /* Status */
396
        return (s->pin_func << 14) | ((!s->enabled) << 13) |
397
                (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
398

    
399
    case 0x03:        /* Reference */
400
        return s->ref;
401

    
402
    case 0x04:        /* Reset */
403
        return 0xffff;
404

    
405
    case 0x05:        /* Configuration */
406
        return s->timing;
407

    
408
    default:
409
#ifdef TSC_VERBOSE
410
        fprintf(stderr, "tsc2102_control_register_read: "
411
                        "no such register: 0x%02x\n", reg);
412
#endif
413
        return 0xffff;
414
    }
415
}
416

    
417
static uint16_t tsc2102_audio_register_read(struct tsc210x_state_s *s, int reg)
418
{
419
    int l_ch, r_ch;
420
    uint16_t val;
421

    
422
    switch (reg) {
423
    case 0x00:        /* Audio Control 1 */
424
        return s->audio_ctrl1;
425

    
426
    case 0x01:
427
        return 0xff00;
428

    
429
    case 0x02:        /* DAC Volume Control */
430
        return s->volume;
431

    
432
    case 0x03:
433
        return 0x8b00;
434

    
435
    case 0x04:        /* Audio Control 2 */
436
        l_ch = 1;
437
        r_ch = 1;
438
        if (s->softstep && !(s->dac_power & (1 << 10))) {
439
            l_ch = (qemu_get_clock(vm_clock) >
440
                            s->volume_change + TSC_SOFTSTEP_DELAY);
441
            r_ch = (qemu_get_clock(vm_clock) >
442
                            s->volume_change + TSC_SOFTSTEP_DELAY);
443
        }
444

    
445
        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
446

    
447
    case 0x05:        /* Stereo DAC Power Control */
448
        return 0x2aa0 | s->dac_power |
449
                (((s->dac_power & (1 << 10)) &&
450
                  (qemu_get_clock(vm_clock) >
451
                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
452

    
453
    case 0x06:        /* Audio Control 3 */
454
        val = s->audio_ctrl3 | 0x0001;
455
        s->audio_ctrl3 &= 0xff3f;
456
        return val;
457

    
458
    case 0x07:        /* LCH_BASS_BOOST_N0 */
459
    case 0x08:        /* LCH_BASS_BOOST_N1 */
460
    case 0x09:        /* LCH_BASS_BOOST_N2 */
461
    case 0x0a:        /* LCH_BASS_BOOST_N3 */
462
    case 0x0b:        /* LCH_BASS_BOOST_N4 */
463
    case 0x0c:        /* LCH_BASS_BOOST_N5 */
464
    case 0x0d:        /* LCH_BASS_BOOST_D1 */
465
    case 0x0e:        /* LCH_BASS_BOOST_D2 */
466
    case 0x0f:        /* LCH_BASS_BOOST_D4 */
467
    case 0x10:        /* LCH_BASS_BOOST_D5 */
468
    case 0x11:        /* RCH_BASS_BOOST_N0 */
469
    case 0x12:        /* RCH_BASS_BOOST_N1 */
470
    case 0x13:        /* RCH_BASS_BOOST_N2 */
471
    case 0x14:        /* RCH_BASS_BOOST_N3 */
472
    case 0x15:        /* RCH_BASS_BOOST_N4 */
473
    case 0x16:        /* RCH_BASS_BOOST_N5 */
474
    case 0x17:        /* RCH_BASS_BOOST_D1 */
475
    case 0x18:        /* RCH_BASS_BOOST_D2 */
476
    case 0x19:        /* RCH_BASS_BOOST_D4 */
477
    case 0x1a:        /* RCH_BASS_BOOST_D5 */
478
        return s->filter_data[reg - 0x07];
479

    
480
    case 0x1b:        /* PLL Programmability 1 */
481
        return s->pll[0];
482

    
483
    case 0x1c:        /* PLL Programmability 2 */
484
        return s->pll[1];
485

    
486
    case 0x1d:        /* Audio Control 4 */
487
        return (!s->softstep) << 14;
488

    
489
    default:
490
#ifdef TSC_VERBOSE
491
        fprintf(stderr, "tsc2102_audio_register_read: "
492
                        "no such register: 0x%02x\n", reg);
493
#endif
494
        return 0xffff;
495
    }
496
}
497

    
498
static void tsc2102_data_register_write(
499
                struct tsc210x_state_s *s, int reg, uint16_t value)
500
{
501
    switch (reg) {
502
    case 0x00:        /* X */
503
    case 0x01:        /* Y */
504
    case 0x02:        /* Z1 */
505
    case 0x03:        /* Z2 */
506
    case 0x05:        /* BAT1 */
507
    case 0x06:        /* BAT2 */
508
    case 0x07:        /* AUX1 */
509
    case 0x08:        /* AUX2 */
510
    case 0x09:        /* TEMP1 */
511
    case 0x0a:        /* TEMP2 */
512
        return;
513

    
514
    default:
515
#ifdef TSC_VERBOSE
516
        fprintf(stderr, "tsc2102_data_register_write: "
517
                        "no such register: 0x%02x\n", reg);
518
#endif
519
    }
520
}
521

    
522
static void tsc2102_control_register_write(
523
                struct tsc210x_state_s *s, int reg, uint16_t value)
524
{
525
    switch (reg) {
526
    case 0x00:        /* TSC ADC */
527
        s->host_mode = value >> 15;
528
        s->enabled = !(value & 0x4000);
529
        if (s->busy && !s->enabled)
530
            qemu_del_timer(s->timer);
531
        s->busy &= s->enabled;
532
        s->nextfunction = (value >> 10) & 0xf;
533
        s->nextprecision = (value >> 8) & 3;
534
        s->filter = value & 0xff;
535
        return;
536

    
537
    case 0x01:        /* Status */
538
        s->pin_func = value >> 14;
539
        return;
540

    
541
    case 0x03:        /* Reference */
542
        s->ref = value & 0x1f;
543
        return;
544

    
545
    case 0x04:        /* Reset */
546
        if (value == 0xbb00) {
547
            if (s->busy)
548
                qemu_del_timer(s->timer);
549
            tsc210x_reset(s);
550
#ifdef TSC_VERBOSE
551
        } else {
552
            fprintf(stderr, "tsc2102_control_register_write: "
553
                            "wrong value written into RESET\n");
554
#endif
555
        }
556
        return;
557

    
558
    case 0x05:        /* Configuration */
559
        s->timing = value & 0x3f;
560
#ifdef TSC_VERBOSE
561
        if (value & ~0x3f)
562
            fprintf(stderr, "tsc2102_control_register_write: "
563
                            "wrong value written into CONFIG\n");
564
#endif
565
        return;
566

    
567
    default:
568
#ifdef TSC_VERBOSE
569
        fprintf(stderr, "tsc2102_control_register_write: "
570
                        "no such register: 0x%02x\n", reg);
571
#endif
572
    }
573
}
574

    
575
static void tsc2102_audio_register_write(
576
                struct tsc210x_state_s *s, int reg, uint16_t value)
577
{
578
    switch (reg) {
579
    case 0x00:        /* Audio Control 1 */
580
        s->audio_ctrl1 = value & 0x0f3f;
581
#ifdef TSC_VERBOSE
582
        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
583
            fprintf(stderr, "tsc2102_audio_register_write: "
584
                            "wrong value written into Audio 1\n");
585
#endif
586
        if (s->audio)
587
            tsc2102_audio_set_format(s);
588
        return;
589

    
590
    case 0x01:
591
#ifdef TSC_VERBOSE
592
        if (value != 0xff00)
593
            fprintf(stderr, "tsc2102_audio_register_write: "
594
                            "wrong value written into reg 0x01\n");
595
#endif
596
        return;
597

    
598
    case 0x02:        /* DAC Volume Control */
599
        s->volume = value;
600
        s->volume_change = qemu_get_clock(vm_clock);
601
        return;
602

    
603
    case 0x03:
604
#ifdef TSC_VERBOSE
605
        if (value != 0x8b00)
606
            fprintf(stderr, "tsc2102_audio_register_write: "
607
                            "wrong value written into reg 0x03\n");
608
#endif
609
        return;
610

    
611
    case 0x04:        /* Audio Control 2 */
612
        s->audio_ctrl2 = value & 0xf7f2;
613
#ifdef TSC_VERBOSE
614
        if (value & ~0xf7fd)
615
            fprintf(stderr, "tsc2102_audio_register_write: "
616
                            "wrong value written into Audio 2\n");
617
#endif
618
        return;
619

    
620
    case 0x05:        /* Stereo DAC Power Control */
621
        if ((value & ~s->dac_power) & (1 << 10))
622
            s->powerdown = qemu_get_clock(vm_clock);
623

    
624
        s->dac_power = value & 0x9543;
625
#ifdef TSC_VERBOSE
626
        if ((value & ~0x9543) != 0x2aa0)
627
            fprintf(stderr, "tsc2102_audio_register_write: "
628
                            "wrong value written into Power\n");
629
#endif
630
        if (s->audio)
631
            tsc2102_audio_set_format(s);
632
        return;
633

    
634
    case 0x06:        /* Audio Control 3 */
635
        s->audio_ctrl3 &= 0x00c0;
636
        s->audio_ctrl3 |= value & 0xf800;
637
#ifdef TSC_VERBOSE
638
        if (value & ~0xf8c7)
639
            fprintf(stderr, "tsc2102_audio_register_write: "
640
                            "wrong value written into Audio 3\n");
641
#endif
642
        if (s->audio)
643
            tsc2102_audio_set_format(s);
644
        return;
645

    
646
    case 0x07:        /* LCH_BASS_BOOST_N0 */
647
    case 0x08:        /* LCH_BASS_BOOST_N1 */
648
    case 0x09:        /* LCH_BASS_BOOST_N2 */
649
    case 0x0a:        /* LCH_BASS_BOOST_N3 */
650
    case 0x0b:        /* LCH_BASS_BOOST_N4 */
651
    case 0x0c:        /* LCH_BASS_BOOST_N5 */
652
    case 0x0d:        /* LCH_BASS_BOOST_D1 */
653
    case 0x0e:        /* LCH_BASS_BOOST_D2 */
654
    case 0x0f:        /* LCH_BASS_BOOST_D4 */
655
    case 0x10:        /* LCH_BASS_BOOST_D5 */
656
    case 0x11:        /* RCH_BASS_BOOST_N0 */
657
    case 0x12:        /* RCH_BASS_BOOST_N1 */
658
    case 0x13:        /* RCH_BASS_BOOST_N2 */
659
    case 0x14:        /* RCH_BASS_BOOST_N3 */
660
    case 0x15:        /* RCH_BASS_BOOST_N4 */
661
    case 0x16:        /* RCH_BASS_BOOST_N5 */
662
    case 0x17:        /* RCH_BASS_BOOST_D1 */
663
    case 0x18:        /* RCH_BASS_BOOST_D2 */
664
    case 0x19:        /* RCH_BASS_BOOST_D4 */
665
    case 0x1a:        /* RCH_BASS_BOOST_D5 */
666
        s->filter_data[reg - 0x07] = value;
667
        return;
668

    
669
    case 0x1b:        /* PLL Programmability 1 */
670
        s->pll[0] = value & 0xfffc;
671
#ifdef TSC_VERBOSE
672
        if (value & ~0xfffc)
673
            fprintf(stderr, "tsc2102_audio_register_write: "
674
                            "wrong value written into PLL 1\n");
675
#endif
676
        return;
677

    
678
    case 0x1c:        /* PLL Programmability 2 */
679
        s->pll[1] = value & 0xfffc;
680
#ifdef TSC_VERBOSE
681
        if (value & ~0xfffc)
682
            fprintf(stderr, "tsc2102_audio_register_write: "
683
                            "wrong value written into PLL 2\n");
684
#endif
685
        return;
686

    
687
    case 0x1d:        /* Audio Control 4 */
688
        s->softstep = !(value & 0x4000);
689
#ifdef TSC_VERBOSE
690
        if (value & ~0x4000)
691
            fprintf(stderr, "tsc2102_audio_register_write: "
692
                            "wrong value written into Audio 4\n");
693
#endif
694
        return;
695

    
696
    default:
697
#ifdef TSC_VERBOSE
698
        fprintf(stderr, "tsc2102_audio_register_write: "
699
                        "no such register: 0x%02x\n", reg);
700
#endif
701
    }
702
}
703

    
704
/* This handles most of the chip logic.  */
705
static void tsc210x_pin_update(struct tsc210x_state_s *s)
706
{
707
    int64_t expires;
708
    int pin_state;
709

    
710
    switch (s->pin_func) {
711
    case 0:
712
        pin_state = s->pressure;
713
        break;
714
    case 1:
715
        pin_state = !!s->dav;
716
        break;
717
    case 2:
718
    default:
719
        pin_state = s->pressure && !s->dav;
720
    }
721

    
722
    if (!s->enabled)
723
        pin_state = 0;
724

    
725
    if (pin_state != s->irq) {
726
        s->irq = pin_state;
727
        qemu_set_irq(s->pint, !s->irq);
728
    }
729

    
730
    switch (s->nextfunction) {
731
    case TSC_MODE_XY_SCAN:
732
    case TSC_MODE_XYZ_SCAN:
733
        if (!s->pressure)
734
            return;
735
        break;
736

    
737
    case TSC_MODE_X:
738
    case TSC_MODE_Y:
739
    case TSC_MODE_Z:
740
        if (!s->pressure)
741
            return;
742
        /* Fall through */
743
    case TSC_MODE_BAT1:
744
    case TSC_MODE_BAT2:
745
    case TSC_MODE_AUX:
746
    case TSC_MODE_TEMP1:
747
    case TSC_MODE_TEMP2:
748
        if (s->dav)
749
            s->enabled = 0;
750
        break;
751

    
752
    case TSC_MODE_AUX_SCAN:
753
    case TSC_MODE_PORT_SCAN:
754
        break;
755

    
756
    case TSC_MODE_NO_SCAN:
757
    case TSC_MODE_XX_DRV:
758
    case TSC_MODE_YY_DRV:
759
    case TSC_MODE_YX_DRV:
760
    default:
761
        return;
762
    }
763

    
764
    if (!s->enabled || s->busy)
765
        return;
766

    
767
    s->busy = 1;
768
    s->precision = s->nextprecision;
769
    s->function = s->nextfunction;
770
    expires = qemu_get_clock(vm_clock) + (ticks_per_sec >> 10);
771
    qemu_mod_timer(s->timer, expires);
772
}
773

    
774
static uint16_t tsc210x_read(struct tsc210x_state_s *s)
775
{
776
    uint16_t ret = 0x0000;
777

    
778
    if (!s->command)
779
        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
780

    
781
    switch (s->page) {
782
    case TSC_DATA_REGISTERS_PAGE:
783
        ret = tsc2102_data_register_read(s, s->offset);
784
        break;
785
    case TSC_CONTROL_REGISTERS_PAGE:
786
        ret = tsc2102_control_register_read(s, s->offset);
787
        break;
788
    case TSC_AUDIO_REGISTERS_PAGE:
789
        ret = tsc2102_audio_register_read(s, s->offset);
790
        break;
791
    default:
792
        cpu_abort(cpu_single_env, "tsc210x_read: wrong memory page\n");
793
    }
794

    
795
    tsc210x_pin_update(s);
796

    
797
    /* Allow sequential reads.  */
798
    s->offset ++;
799
    s->state = 0;
800
    return ret;
801
}
802

    
803
static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value)
804
{
805
    /*
806
     * This is a two-state state machine for reading
807
     * command and data every second time.
808
     */
809
    if (!s->state) {
810
        s->command = value >> 15;
811
        s->page = (value >> 11) & 0x0f;
812
        s->offset = (value >> 5) & 0x3f;
813
        s->state = 1;
814
    } else {
815
        if (s->command)
816
            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
817
        else
818
            switch (s->page) {
819
            case TSC_DATA_REGISTERS_PAGE:
820
                tsc2102_data_register_write(s, s->offset, value);
821
                break;
822
            case TSC_CONTROL_REGISTERS_PAGE:
823
                tsc2102_control_register_write(s, s->offset, value);
824
                break;
825
            case TSC_AUDIO_REGISTERS_PAGE:
826
                tsc2102_audio_register_write(s, s->offset, value);
827
                break;
828
            default:
829
                cpu_abort(cpu_single_env,
830
                                "tsc210x_write: wrong memory page\n");
831
            }
832

    
833
        tsc210x_pin_update(s);
834
        s->state = 0;
835
    }
836
}
837

    
838
static void tsc210x_timer_tick(void *opaque)
839
{
840
    struct tsc210x_state_s *s = opaque;
841

    
842
    /* Timer ticked -- a set of conversions has been finished.  */
843

    
844
    if (!s->busy)
845
        return;
846

    
847
    s->busy = 0;
848
    s->dav |= mode_regs[s->function];
849
    tsc210x_pin_update(s);
850
}
851

    
852
static void tsc210x_touchscreen_event(void *opaque,
853
                int x, int y, int z, int buttons_state)
854
{
855
    struct tsc210x_state_s *s = opaque;
856
    int p = s->pressure;
857

    
858
    if (buttons_state) {
859
        s->x = x;
860
        s->y = y;
861
    }
862
    s->pressure = !!buttons_state;
863

    
864
    /*
865
     * Note: We would get better responsiveness in the guest by
866
     * signaling TS events immediately, but for now we simulate
867
     * the first conversion delay for sake of correctness.
868
     */
869
    if (p != s->pressure)
870
        tsc210x_pin_update(s);
871
}
872

    
873
static void tsc210x_i2s_swallow(struct tsc210x_state_s *s)
874
{
875
    if (s->dac_voice[0])
876
        tsc210x_out_flush(s, s->codec.out.len);
877
    else
878
        s->codec.out.len = 0;
879
}
880

    
881
static void tsc210x_i2s_set_rate(struct tsc210x_state_s *s, int in, int out)
882
{
883
    s->i2s_tx_rate = out;
884
    s->i2s_rx_rate = in;
885
}
886

    
887
static void tsc210x_save(QEMUFile *f, void *opaque)
888
{
889
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
890
    int64_t now = qemu_get_clock(vm_clock);
891
    int i;
892

    
893
    qemu_put_be16(f, s->x);
894
    qemu_put_be16(f, s->y);
895
    qemu_put_byte(f, s->pressure);
896

    
897
    qemu_put_byte(f, s->state);
898
    qemu_put_byte(f, s->page);
899
    qemu_put_byte(f, s->offset);
900
    qemu_put_byte(f, s->command);
901

    
902
    qemu_put_byte(f, s->irq);
903
    qemu_put_be16s(f, &s->dav);
904

    
905
    qemu_put_timer(f, s->timer);
906
    qemu_put_byte(f, s->enabled);
907
    qemu_put_byte(f, s->host_mode);
908
    qemu_put_byte(f, s->function);
909
    qemu_put_byte(f, s->nextfunction);
910
    qemu_put_byte(f, s->precision);
911
    qemu_put_byte(f, s->nextprecision);
912
    qemu_put_byte(f, s->filter);
913
    qemu_put_byte(f, s->pin_func);
914
    qemu_put_byte(f, s->ref);
915
    qemu_put_byte(f, s->timing);
916
    qemu_put_be32(f, s->noise);
917

    
918
    qemu_put_be16s(f, &s->audio_ctrl1);
919
    qemu_put_be16s(f, &s->audio_ctrl2);
920
    qemu_put_be16s(f, &s->audio_ctrl3);
921
    qemu_put_be16s(f, &s->pll[0]);
922
    qemu_put_be16s(f, &s->pll[1]);
923
    qemu_put_be16s(f, &s->volume);
924
    qemu_put_be64(f, (uint64_t) (s->volume_change - now));
925
    qemu_put_be64(f, (uint64_t) (s->powerdown - now));
926
    qemu_put_byte(f, s->softstep);
927
    qemu_put_be16s(f, &s->dac_power);
928

    
929
    for (i = 0; i < 0x14; i ++)
930
        qemu_put_be16s(f, &s->filter_data[i]);
931
}
932

    
933
static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
934
{
935
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
936
    int64_t now = qemu_get_clock(vm_clock);
937
    int i;
938

    
939
    s->x = qemu_get_be16(f);
940
    s->y = qemu_get_be16(f);
941
    s->pressure = qemu_get_byte(f);
942

    
943
    s->state = qemu_get_byte(f);
944
    s->page = qemu_get_byte(f);
945
    s->offset = qemu_get_byte(f);
946
    s->command = qemu_get_byte(f);
947

    
948
    s->irq = qemu_get_byte(f);
949
    qemu_get_be16s(f, &s->dav);
950

    
951
    qemu_get_timer(f, s->timer);
952
    s->enabled = qemu_get_byte(f);
953
    s->host_mode = qemu_get_byte(f);
954
    s->function = qemu_get_byte(f);
955
    s->nextfunction = qemu_get_byte(f);
956
    s->precision = qemu_get_byte(f);
957
    s->nextprecision = qemu_get_byte(f);
958
    s->filter = qemu_get_byte(f);
959
    s->pin_func = qemu_get_byte(f);
960
    s->ref = qemu_get_byte(f);
961
    s->timing = qemu_get_byte(f);
962
    s->noise = qemu_get_be32(f);
963

    
964
    qemu_get_be16s(f, &s->audio_ctrl1);
965
    qemu_get_be16s(f, &s->audio_ctrl2);
966
    qemu_get_be16s(f, &s->audio_ctrl3);
967
    qemu_get_be16s(f, &s->pll[0]);
968
    qemu_get_be16s(f, &s->pll[1]);
969
    qemu_get_be16s(f, &s->volume);
970
    s->volume_change = (int64_t) qemu_get_be64(f) + now;
971
    s->powerdown = (int64_t) qemu_get_be64(f) + now;
972
    s->softstep = qemu_get_byte(f);
973
    qemu_get_be16s(f, &s->dac_power);
974

    
975
    for (i = 0; i < 0x14; i ++)
976
        qemu_get_be16s(f, &s->filter_data[i]);
977

    
978
    s->busy = qemu_timer_pending(s->timer);
979
    qemu_set_irq(s->pint, !s->irq);
980

    
981
    return 0;
982
}
983

    
984
static int tsc2102_iid = 0;
985

    
986
struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio)
987
{
988
    struct tsc210x_state_s *s;
989

    
990
    s = (struct tsc210x_state_s *)
991
            qemu_mallocz(sizeof(struct tsc210x_state_s));
992
    memset(s, 0, sizeof(struct tsc210x_state_s));
993
    s->x = 160;
994
    s->y = 160;
995
    s->pressure = 0;
996
    s->precision = s->nextprecision = 0;
997
    s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);
998
    s->pint = pint;
999
    s->name = "tsc2102";
1000
    s->audio = audio;
1001

    
1002
    s->chip.opaque = s;
1003
    s->chip.send = (void *) tsc210x_write;
1004
    s->chip.receive = (void *) tsc210x_read;
1005

    
1006
    s->codec.opaque = s;
1007
    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1008
    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1009
    s->codec.in.fifo = s->in_fifo;
1010
    s->codec.out.fifo = s->out_fifo;
1011

    
1012
    tsc210x_reset(s);
1013

    
1014
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1015
                    "QEMU TSC2102-driven Touchscreen");
1016

    
1017
    if (s->audio)
1018
        AUD_register_card(s->audio, s->name, &s->card);
1019

    
1020
    qemu_register_reset((void *) tsc210x_reset, s);
1021
    register_savevm(s->name, tsc2102_iid ++, 0,
1022
                    tsc210x_save, tsc210x_load, s);
1023

    
1024
    return &s->chip;
1025
}
1026

    
1027
struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip)
1028
{
1029
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
1030

    
1031
    return &s->codec;
1032
}