qemu

Форк
0
/
tsc210x.c 
1241 строка · 33.2 Кб
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 "qemu/log.h"
27
#include "sysemu/reset.h"
28
#include "ui/console.h"
29
#include "hw/arm/omap.h"            /* For I2SCodec */
30
#include "hw/boards.h"              /* for current_machine */
31
#include "hw/input/tsc2xxx.h"
32
#include "hw/irq.h"
33
#include "migration/vmstate.h"
34
#include "qapi/error.h"
35

36
#define TSC_DATA_REGISTERS_PAGE		0x0
37
#define TSC_CONTROL_REGISTERS_PAGE	0x1
38
#define TSC_AUDIO_REGISTERS_PAGE	0x2
39

40
#define TSC_VERBOSE
41

42
#define TSC_CUT_RESOLUTION(value, p)	((value) >> (16 - resolution[p]))
43

44
typedef struct {
45
    qemu_irq pint;
46
    qemu_irq kbint;
47
    qemu_irq davint;
48
    QEMUTimer *timer;
49
    QEMUSoundCard card;
50
    uWireSlave chip;
51
    I2SCodec codec;
52
    uint8_t in_fifo[16384];
53
    uint8_t out_fifo[16384];
54
    uint16_t model;
55

56
    int32_t x, y;
57
    bool pressure;
58

59
    uint8_t page, offset;
60
    uint16_t dav;
61

62
    bool state;
63
    bool irq;
64
    bool command;
65
    bool busy;
66
    bool enabled;
67
    bool host_mode;
68
    uint8_t function, nextfunction;
69
    uint8_t precision, nextprecision;
70
    uint8_t filter;
71
    uint8_t pin_func;
72
    uint8_t ref;
73
    uint8_t timing;
74
    uint8_t noise;
75

76
    uint16_t audio_ctrl1;
77
    uint16_t audio_ctrl2;
78
    uint16_t audio_ctrl3;
79
    uint16_t pll[3];
80
    uint16_t volume;
81
    int64_t volume_change;
82
    bool softstep;
83
    uint16_t dac_power;
84
    int64_t powerdown;
85
    uint16_t filter_data[0x14];
86

87
    const char *name;
88
    SWVoiceIn *adc_voice[1];
89
    SWVoiceOut *dac_voice[1];
90
    int i2s_rx_rate;
91
    int i2s_tx_rate;
92

93
    int tr[8];
94

95
    struct {
96
        uint16_t down;
97
        uint16_t mask;
98
        int scan;
99
        int debounce;
100
        int mode;
101
        int intr;
102
    } kb;
103
    int64_t now; /* Time at migration */
104
} TSC210xState;
105

106
static const int resolution[4] = { 12, 8, 10, 12 };
107

108
#define TSC_MODE_NO_SCAN	0x0
109
#define TSC_MODE_XY_SCAN	0x1
110
#define TSC_MODE_XYZ_SCAN	0x2
111
#define TSC_MODE_X		0x3
112
#define TSC_MODE_Y		0x4
113
#define TSC_MODE_Z		0x5
114
#define TSC_MODE_BAT1		0x6
115
#define TSC_MODE_BAT2		0x7
116
#define TSC_MODE_AUX		0x8
117
#define TSC_MODE_AUX_SCAN	0x9
118
#define TSC_MODE_TEMP1		0xa
119
#define TSC_MODE_PORT_SCAN	0xb
120
#define TSC_MODE_TEMP2		0xc
121
#define TSC_MODE_XX_DRV		0xd
122
#define TSC_MODE_YY_DRV		0xe
123
#define TSC_MODE_YX_DRV		0xf
124

125
static const uint16_t mode_regs[16] = {
126
    0x0000,	/* No scan */
127
    0x0600,	/* X, Y scan */
128
    0x0780,	/* X, Y, Z scan */
129
    0x0400,	/* X */
130
    0x0200,	/* Y */
131
    0x0180,	/* Z */
132
    0x0040,	/* BAT1 */
133
    0x0030,	/* BAT2 */
134
    0x0010,	/* AUX */
135
    0x0010,	/* AUX scan */
136
    0x0004,	/* TEMP1 */
137
    0x0070,	/* Port scan */
138
    0x0002,	/* TEMP2 */
139
    0x0000,	/* X+, X- drivers */
140
    0x0000,	/* Y+, Y- drivers */
141
    0x0000,	/* Y+, X- drivers */
142
};
143

144
#define X_TRANSFORM(s)			\
145
    ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
146
#define Y_TRANSFORM(s)			\
147
    ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
148
#define Z1_TRANSFORM(s)			\
149
    ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
150
#define Z2_TRANSFORM(s)			\
151
    ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
152

153
#define BAT1_VAL			0x8660
154
#define BAT2_VAL			0x0000
155
#define AUX1_VAL			0x35c0
156
#define AUX2_VAL			0xffff
157
#define TEMP1_VAL			0x8c70
158
#define TEMP2_VAL			0xa5b0
159

160
#define TSC_POWEROFF_DELAY		50
161
#define TSC_SOFTSTEP_DELAY		50
162

163
static void tsc210x_reset(TSC210xState *s)
164
{
165
    s->state = false;
166
    s->pin_func = 2;
167
    s->enabled = false;
168
    s->busy = false;
169
    s->nextfunction = 0;
170
    s->ref = 0;
171
    s->timing = 0;
172
    s->irq = false;
173
    s->dav = 0;
174

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

207
    s->i2s_tx_rate = 0;
208
    s->i2s_rx_rate = 0;
209

210
    s->kb.scan = 1;
211
    s->kb.debounce = 0;
212
    s->kb.mask = 0x0000;
213
    s->kb.mode = 3;
214
    s->kb.intr = 0;
215

216
    qemu_set_irq(s->pint, !s->irq);
217
    qemu_set_irq(s->davint, !s->dav);
218
    qemu_irq_raise(s->kbint);
219
}
220

221
typedef struct {
222
    int rate;
223
    int dsor;
224
    int fsref;
225
} TSC210xRateInfo;
226

227
/*  { rate,   dsor, fsref }	*/
228
static const TSC210xRateInfo 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(TSC210xState *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(TSC210xState *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_rate_update(TSC210xState *s)
283
{
284
    const TSC210xRateInfo *rate;
285

286
    s->codec.tx_rate = 0;
287
    s->codec.rx_rate = 0;
288
    if (s->dac_power & (1 << 15))				/* PWDNC */
289
        return;
290

291
    for (rate = tsc2102_rates; rate->rate; rate ++)
292
        if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&		/* DACFS */
293
                        rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
294
            break;
295
    if (!rate->rate) {
296
        printf("%s: unknown sampling rate configured\n", __func__);
297
        return;
298
    }
299

300
    s->codec.tx_rate = rate->rate;
301
}
302

303
static void tsc2102_audio_output_update(TSC210xState *s)
304
{
305
    int enable;
306
    struct audsettings fmt;
307

308
    if (s->dac_voice[0]) {
309
        tsc210x_out_flush(s, s->codec.out.len);
310
        s->codec.out.size = 0;
311
        AUD_set_active_out(s->dac_voice[0], 0);
312
        AUD_close_out(&s->card, s->dac_voice[0]);
313
        s->dac_voice[0] = NULL;
314
    }
315
    s->codec.cts = 0;
316

317
    enable =
318
            (~s->dac_power & (1 << 15)) &&			/* PWDNC */
319
            (~s->dac_power & (1 << 10));			/* DAPWDN */
320
    if (!enable || !s->codec.tx_rate)
321
        return;
322

323
    /* Force our own sampling rate even in slave DAC mode */
324
    fmt.endianness = 0;
325
    fmt.nchannels = 2;
326
    fmt.freq = s->codec.tx_rate;
327
    fmt.fmt = AUDIO_FORMAT_S16;
328

329
    s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
330
                    "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
331
    if (s->dac_voice[0]) {
332
        s->codec.cts = 1;
333
        AUD_set_active_out(s->dac_voice[0], 1);
334
    }
335
}
336

337
static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
338
{
339
    switch (reg) {
340
    case 0x00:	/* X */
341
        s->dav &= 0xfbff;
342
        return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
343
                (s->noise & 3);
344

345
    case 0x01:	/* Y */
346
        s->noise ++;
347
        s->dav &= 0xfdff;
348
        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
349
                (s->noise & 3);
350

351
    case 0x02:	/* Z1 */
352
        s->dav &= 0xfeff;
353
        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
354
                (s->noise & 3);
355

356
    case 0x03:	/* Z2 */
357
        s->dav &= 0xff7f;
358
        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
359
                (s->noise & 3);
360

361
    case 0x04:	/* KPData */
362
        if ((s->model & 0xff00) == 0x2300) {
363
            if (s->kb.intr && (s->kb.mode & 2)) {
364
                s->kb.intr = 0;
365
                qemu_irq_raise(s->kbint);
366
            }
367
            return s->kb.down;
368
        }
369

370
        return 0xffff;
371

372
    case 0x05:	/* BAT1 */
373
        s->dav &= 0xffbf;
374
        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision) +
375
                (s->noise & 6);
376

377
    case 0x06:	/* BAT2 */
378
        s->dav &= 0xffdf;
379
        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
380

381
    case 0x07:	/* AUX1 */
382
        s->dav &= 0xffef;
383
        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
384

385
    case 0x08:	/* AUX2 */
386
        s->dav &= 0xfff7;
387
        return 0xffff;
388

389
    case 0x09:	/* TEMP1 */
390
        s->dav &= 0xfffb;
391
        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
392
                (s->noise & 5);
393

394
    case 0x0a:	/* TEMP2 */
395
        s->dav &= 0xfffd;
396
        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
397
                (s->noise & 3);
398

399
    case 0x0b:	/* DAC */
400
        s->dav &= 0xfffe;
401
        return 0xffff;
402

403
    default:
404
#ifdef TSC_VERBOSE
405
        fprintf(stderr, "tsc2102_data_register_read: "
406
                        "no such register: 0x%02x\n", reg);
407
#endif
408
        return 0xffff;
409
    }
410
}
411

412
static uint16_t tsc2102_control_register_read(
413
                TSC210xState *s, int reg)
414
{
415
    switch (reg) {
416
    case 0x00:	/* TSC ADC */
417
        return (s->pressure << 15) | ((!s->busy) << 14) |
418
                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
419

420
    case 0x01:	/* Status / Keypad Control */
421
        if ((s->model & 0xff00) == 0x2100)
422
            return (s->pin_func << 14) | ((!s->enabled) << 13) |
423
                    (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
424
        else
425
            return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) |
426
                    (s->kb.debounce << 11);
427

428
    case 0x02:	/* DAC Control */
429
        if ((s->model & 0xff00) == 0x2300)
430
            return s->dac_power & 0x8000;
431
        else
432
            goto bad_reg;
433

434
    case 0x03:	/* Reference */
435
        return s->ref;
436

437
    case 0x04:	/* Reset */
438
        return 0xffff;
439

440
    case 0x05:	/* Configuration */
441
        return s->timing;
442

443
    case 0x06:	/* Secondary configuration */
444
        if ((s->model & 0xff00) == 0x2100)
445
            goto bad_reg;
446
        return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2];
447

448
    case 0x10:	/* Keypad Mask */
449
        if ((s->model & 0xff00) == 0x2100)
450
            goto bad_reg;
451
        return s->kb.mask;
452

453
    default:
454
    bad_reg:
455
#ifdef TSC_VERBOSE
456
        fprintf(stderr, "tsc2102_control_register_read: "
457
                        "no such register: 0x%02x\n", reg);
458
#endif
459
        return 0xffff;
460
    }
461
}
462

463
static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
464
{
465
    int l_ch, r_ch;
466
    uint16_t val;
467

468
    switch (reg) {
469
    case 0x00:	/* Audio Control 1 */
470
        return s->audio_ctrl1;
471

472
    case 0x01:
473
        return 0xff00;
474

475
    case 0x02:	/* DAC Volume Control */
476
        return s->volume;
477

478
    case 0x03:
479
        return 0x8b00;
480

481
    case 0x04:	/* Audio Control 2 */
482
        l_ch = 1;
483
        r_ch = 1;
484
        if (s->softstep && !(s->dac_power & (1 << 10))) {
485
            l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
486
                            s->volume_change + TSC_SOFTSTEP_DELAY);
487
            r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
488
                            s->volume_change + TSC_SOFTSTEP_DELAY);
489
        }
490

491
        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
492

493
    case 0x05:	/* Stereo DAC Power Control */
494
        return 0x2aa0 | s->dac_power |
495
                (((s->dac_power & (1 << 10)) &&
496
                  (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
497
                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
498

499
    case 0x06:	/* Audio Control 3 */
500
        val = s->audio_ctrl3 | 0x0001;
501
        s->audio_ctrl3 &= 0xff3f;
502
        return val;
503

504
    case 0x07:	/* LCH_BASS_BOOST_N0 */
505
    case 0x08:	/* LCH_BASS_BOOST_N1 */
506
    case 0x09:	/* LCH_BASS_BOOST_N2 */
507
    case 0x0a:	/* LCH_BASS_BOOST_N3 */
508
    case 0x0b:	/* LCH_BASS_BOOST_N4 */
509
    case 0x0c:	/* LCH_BASS_BOOST_N5 */
510
    case 0x0d:	/* LCH_BASS_BOOST_D1 */
511
    case 0x0e:	/* LCH_BASS_BOOST_D2 */
512
    case 0x0f:	/* LCH_BASS_BOOST_D4 */
513
    case 0x10:	/* LCH_BASS_BOOST_D5 */
514
    case 0x11:	/* RCH_BASS_BOOST_N0 */
515
    case 0x12:	/* RCH_BASS_BOOST_N1 */
516
    case 0x13:	/* RCH_BASS_BOOST_N2 */
517
    case 0x14:	/* RCH_BASS_BOOST_N3 */
518
    case 0x15:	/* RCH_BASS_BOOST_N4 */
519
    case 0x16:	/* RCH_BASS_BOOST_N5 */
520
    case 0x17:	/* RCH_BASS_BOOST_D1 */
521
    case 0x18:	/* RCH_BASS_BOOST_D2 */
522
    case 0x19:	/* RCH_BASS_BOOST_D4 */
523
    case 0x1a:	/* RCH_BASS_BOOST_D5 */
524
        return s->filter_data[reg - 0x07];
525

526
    case 0x1b:	/* PLL Programmability 1 */
527
        return s->pll[0];
528

529
    case 0x1c:	/* PLL Programmability 2 */
530
        return s->pll[1];
531

532
    case 0x1d:	/* Audio Control 4 */
533
        return (!s->softstep) << 14;
534

535
    default:
536
#ifdef TSC_VERBOSE
537
        fprintf(stderr, "tsc2102_audio_register_read: "
538
                        "no such register: 0x%02x\n", reg);
539
#endif
540
        return 0xffff;
541
    }
542
}
543

544
static void tsc2102_data_register_write(
545
                TSC210xState *s, int reg, uint16_t value)
546
{
547
    switch (reg) {
548
    case 0x00:	/* X */
549
    case 0x01:	/* Y */
550
    case 0x02:	/* Z1 */
551
    case 0x03:	/* Z2 */
552
    case 0x05:	/* BAT1 */
553
    case 0x06:	/* BAT2 */
554
    case 0x07:	/* AUX1 */
555
    case 0x08:	/* AUX2 */
556
    case 0x09:	/* TEMP1 */
557
    case 0x0a:	/* TEMP2 */
558
        return;
559

560
    default:
561
        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_data_register_write: "
562
                                       "no such register: 0x%02x\n", reg);
563
    }
564
}
565

566
static void tsc2102_control_register_write(
567
                TSC210xState *s, int reg, uint16_t value)
568
{
569
    switch (reg) {
570
    case 0x00:	/* TSC ADC */
571
        s->host_mode = value >> 15;
572
        s->enabled = !(value & 0x4000);
573
        if (s->busy && !s->enabled)
574
            timer_del(s->timer);
575
        s->busy = s->busy && s->enabled;
576
        s->nextfunction = (value >> 10) & 0xf;
577
        s->nextprecision = (value >> 8) & 3;
578
        s->filter = value & 0xff;
579
        return;
580

581
    case 0x01:	/* Status / Keypad Control */
582
        if ((s->model & 0xff00) == 0x2100)
583
            s->pin_func = value >> 14;
584
        else {
585
            s->kb.scan = (value >> 14) & 1;
586
            s->kb.debounce = (value >> 11) & 7;
587
            if (s->kb.intr && s->kb.scan) {
588
                s->kb.intr = 0;
589
                qemu_irq_raise(s->kbint);
590
            }
591
        }
592
        return;
593

594
    case 0x02:	/* DAC Control */
595
        if ((s->model & 0xff00) == 0x2300) {
596
            s->dac_power &= 0x7fff;
597
            s->dac_power |= 0x8000 & value;
598
        } else
599
            goto bad_reg;
600
        break;
601

602
    case 0x03:	/* Reference */
603
        s->ref = value & 0x1f;
604
        return;
605

606
    case 0x04:	/* Reset */
607
        if (value == 0xbb00) {
608
            if (s->busy)
609
                timer_del(s->timer);
610
            tsc210x_reset(s);
611
#ifdef TSC_VERBOSE
612
        } else {
613
            fprintf(stderr, "tsc2102_control_register_write: "
614
                            "wrong value written into RESET\n");
615
#endif
616
        }
617
        return;
618

619
    case 0x05:	/* Configuration */
620
        s->timing = value & 0x3f;
621
#ifdef TSC_VERBOSE
622
        if (value & ~0x3f)
623
            fprintf(stderr, "tsc2102_control_register_write: "
624
                            "wrong value written into CONFIG\n");
625
#endif
626
        return;
627

628
    case 0x06:	/* Secondary configuration */
629
        if ((s->model & 0xff00) == 0x2100)
630
            goto bad_reg;
631
        s->kb.mode = value >> 14;
632
        s->pll[2] = value & 0x3ffff;
633
        return;
634

635
    case 0x10:	/* Keypad Mask */
636
        if ((s->model & 0xff00) == 0x2100)
637
            goto bad_reg;
638
        s->kb.mask = value;
639
        return;
640

641
    default:
642
    bad_reg:
643
        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_control_register_write: "
644
                                       "no such register: 0x%02x\n", reg);
645
    }
646
}
647

648
static void tsc2102_audio_register_write(
649
                TSC210xState *s, int reg, uint16_t value)
650
{
651
    switch (reg) {
652
    case 0x00:	/* Audio Control 1 */
653
        s->audio_ctrl1 = value & 0x0f3f;
654
#ifdef TSC_VERBOSE
655
        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
656
            fprintf(stderr, "tsc2102_audio_register_write: "
657
                            "wrong value written into Audio 1\n");
658
#endif
659
        tsc2102_audio_rate_update(s);
660
        tsc2102_audio_output_update(s);
661
        return;
662

663
    case 0x01:
664
#ifdef TSC_VERBOSE
665
        if (value != 0xff00)
666
            fprintf(stderr, "tsc2102_audio_register_write: "
667
                            "wrong value written into reg 0x01\n");
668
#endif
669
        return;
670

671
    case 0x02:	/* DAC Volume Control */
672
        s->volume = value;
673
        s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
674
        return;
675

676
    case 0x03:
677
#ifdef TSC_VERBOSE
678
        if (value != 0x8b00)
679
            fprintf(stderr, "tsc2102_audio_register_write: "
680
                            "wrong value written into reg 0x03\n");
681
#endif
682
        return;
683

684
    case 0x04:	/* Audio Control 2 */
685
        s->audio_ctrl2 = value & 0xf7f2;
686
#ifdef TSC_VERBOSE
687
        if (value & ~0xf7fd)
688
            fprintf(stderr, "tsc2102_audio_register_write: "
689
                            "wrong value written into Audio 2\n");
690
#endif
691
        return;
692

693
    case 0x05:	/* Stereo DAC Power Control */
694
        if ((value & ~s->dac_power) & (1 << 10))
695
            s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
696

697
        s->dac_power = value & 0x9543;
698
#ifdef TSC_VERBOSE
699
        if ((value & ~0x9543) != 0x2aa0)
700
            fprintf(stderr, "tsc2102_audio_register_write: "
701
                            "wrong value written into Power\n");
702
#endif
703
        tsc2102_audio_rate_update(s);
704
        tsc2102_audio_output_update(s);
705
        return;
706

707
    case 0x06:	/* Audio Control 3 */
708
        s->audio_ctrl3 &= 0x00c0;
709
        s->audio_ctrl3 |= value & 0xf800;
710
#ifdef TSC_VERBOSE
711
        if (value & ~0xf8c7)
712
            fprintf(stderr, "tsc2102_audio_register_write: "
713
                            "wrong value written into Audio 3\n");
714
#endif
715
        tsc2102_audio_output_update(s);
716
        return;
717

718
    case 0x07:	/* LCH_BASS_BOOST_N0 */
719
    case 0x08:	/* LCH_BASS_BOOST_N1 */
720
    case 0x09:	/* LCH_BASS_BOOST_N2 */
721
    case 0x0a:	/* LCH_BASS_BOOST_N3 */
722
    case 0x0b:	/* LCH_BASS_BOOST_N4 */
723
    case 0x0c:	/* LCH_BASS_BOOST_N5 */
724
    case 0x0d:	/* LCH_BASS_BOOST_D1 */
725
    case 0x0e:	/* LCH_BASS_BOOST_D2 */
726
    case 0x0f:	/* LCH_BASS_BOOST_D4 */
727
    case 0x10:	/* LCH_BASS_BOOST_D5 */
728
    case 0x11:	/* RCH_BASS_BOOST_N0 */
729
    case 0x12:	/* RCH_BASS_BOOST_N1 */
730
    case 0x13:	/* RCH_BASS_BOOST_N2 */
731
    case 0x14:	/* RCH_BASS_BOOST_N3 */
732
    case 0x15:	/* RCH_BASS_BOOST_N4 */
733
    case 0x16:	/* RCH_BASS_BOOST_N5 */
734
    case 0x17:	/* RCH_BASS_BOOST_D1 */
735
    case 0x18:	/* RCH_BASS_BOOST_D2 */
736
    case 0x19:	/* RCH_BASS_BOOST_D4 */
737
    case 0x1a:	/* RCH_BASS_BOOST_D5 */
738
        s->filter_data[reg - 0x07] = value;
739
        return;
740

741
    case 0x1b:	/* PLL Programmability 1 */
742
        s->pll[0] = value & 0xfffc;
743
#ifdef TSC_VERBOSE
744
        if (value & ~0xfffc)
745
            fprintf(stderr, "tsc2102_audio_register_write: "
746
                            "wrong value written into PLL 1\n");
747
#endif
748
        return;
749

750
    case 0x1c:	/* PLL Programmability 2 */
751
        s->pll[1] = value & 0xfffc;
752
#ifdef TSC_VERBOSE
753
        if (value & ~0xfffc)
754
            fprintf(stderr, "tsc2102_audio_register_write: "
755
                            "wrong value written into PLL 2\n");
756
#endif
757
        return;
758

759
    case 0x1d:	/* Audio Control 4 */
760
        s->softstep = !(value & 0x4000);
761
#ifdef TSC_VERBOSE
762
        if (value & ~0x4000)
763
            fprintf(stderr, "tsc2102_audio_register_write: "
764
                            "wrong value written into Audio 4\n");
765
#endif
766
        return;
767

768
    default:
769
        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_audio_register_write: "
770
                                       "no such register: 0x%02x\n", reg);
771
    }
772
}
773

774
/* This handles most of the chip logic.  */
775
static void tsc210x_pin_update(TSC210xState *s)
776
{
777
    int64_t expires;
778
    bool pin_state;
779

780
    switch (s->pin_func) {
781
    case 0:
782
        pin_state = s->pressure;
783
        break;
784
    case 1:
785
        pin_state = !!s->dav;
786
        break;
787
    case 2:
788
    default:
789
        pin_state = s->pressure && !s->dav;
790
    }
791

792
    if (!s->enabled)
793
        pin_state = false;
794

795
    if (pin_state != s->irq) {
796
        s->irq = pin_state;
797
        qemu_set_irq(s->pint, !s->irq);
798
    }
799

800
    switch (s->nextfunction) {
801
    case TSC_MODE_XY_SCAN:
802
    case TSC_MODE_XYZ_SCAN:
803
        if (!s->pressure)
804
            return;
805
        break;
806

807
    case TSC_MODE_X:
808
    case TSC_MODE_Y:
809
    case TSC_MODE_Z:
810
        if (!s->pressure)
811
            return;
812
        /* Fall through */
813
    case TSC_MODE_BAT1:
814
    case TSC_MODE_BAT2:
815
    case TSC_MODE_AUX:
816
    case TSC_MODE_TEMP1:
817
    case TSC_MODE_TEMP2:
818
        if (s->dav)
819
            s->enabled = false;
820
        break;
821

822
    case TSC_MODE_AUX_SCAN:
823
    case TSC_MODE_PORT_SCAN:
824
        break;
825

826
    case TSC_MODE_NO_SCAN:
827
    case TSC_MODE_XX_DRV:
828
    case TSC_MODE_YY_DRV:
829
    case TSC_MODE_YX_DRV:
830
    default:
831
        return;
832
    }
833

834
    if (!s->enabled || s->busy || s->dav)
835
        return;
836

837
    s->busy = true;
838
    s->precision = s->nextprecision;
839
    s->function = s->nextfunction;
840
    expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
841
        (NANOSECONDS_PER_SECOND >> 10);
842
    timer_mod(s->timer, expires);
843
}
844

845
static uint16_t tsc210x_read(TSC210xState *s)
846
{
847
    uint16_t ret = 0x0000;
848

849
    if (!s->command)
850
        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
851

852
    switch (s->page) {
853
    case TSC_DATA_REGISTERS_PAGE:
854
        ret = tsc2102_data_register_read(s, s->offset);
855
        if (!s->dav)
856
            qemu_irq_raise(s->davint);
857
        break;
858
    case TSC_CONTROL_REGISTERS_PAGE:
859
        ret = tsc2102_control_register_read(s, s->offset);
860
        break;
861
    case TSC_AUDIO_REGISTERS_PAGE:
862
        ret = tsc2102_audio_register_read(s, s->offset);
863
        break;
864
    default:
865
        hw_error("tsc210x_read: wrong memory page\n");
866
    }
867

868
    tsc210x_pin_update(s);
869

870
    /* Allow sequential reads.  */
871
    s->offset ++;
872
    s->state = false;
873
    return ret;
874
}
875

876
static void tsc210x_write(TSC210xState *s, uint16_t value)
877
{
878
    /*
879
     * This is a two-state state machine for reading
880
     * command and data every second time.
881
     */
882
    if (!s->state) {
883
        s->command = (value >> 15) != 0;
884
        s->page = (value >> 11) & 0x0f;
885
        s->offset = (value >> 5) & 0x3f;
886
        s->state = true;
887
    } else {
888
        if (s->command)
889
            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
890
        else
891
            switch (s->page) {
892
            case TSC_DATA_REGISTERS_PAGE:
893
                tsc2102_data_register_write(s, s->offset, value);
894
                break;
895
            case TSC_CONTROL_REGISTERS_PAGE:
896
                tsc2102_control_register_write(s, s->offset, value);
897
                break;
898
            case TSC_AUDIO_REGISTERS_PAGE:
899
                tsc2102_audio_register_write(s, s->offset, value);
900
                break;
901
            default:
902
                hw_error("tsc210x_write: wrong memory page\n");
903
            }
904

905
        tsc210x_pin_update(s);
906
        s->state = false;
907
    }
908
}
909

910
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
911
{
912
    TSC210xState *s = opaque;
913
    uint32_t ret = 0;
914

915
    if (len != 16) {
916
        qemu_log_mask(LOG_GUEST_ERROR,
917
                      "%s: bad SPI word width %i\n", __func__, len);
918
        return 0;
919
    }
920

921
    /* TODO: sequential reads etc - how do we make sure the host doesn't
922
     * unintentionally read out a conversion result from a register while
923
     * transmitting the command word of the next command?  */
924
    if (!value || (s->state && s->command))
925
        ret = tsc210x_read(s);
926
    if (value || (s->state && !s->command))
927
        tsc210x_write(s, value);
928

929
    return ret;
930
}
931

932
static void tsc210x_timer_tick(void *opaque)
933
{
934
    TSC210xState *s = opaque;
935

936
    /* Timer ticked -- a set of conversions has been finished.  */
937

938
    if (!s->busy)
939
        return;
940

941
    s->busy = false;
942
    s->dav |= mode_regs[s->function];
943
    tsc210x_pin_update(s);
944
    qemu_irq_lower(s->davint);
945
}
946

947
static void tsc210x_touchscreen_event(void *opaque,
948
                int x, int y, int z, int buttons_state)
949
{
950
    TSC210xState *s = opaque;
951
    int p = s->pressure;
952

953
    if (buttons_state) {
954
        s->x = x;
955
        s->y = y;
956
    }
957
    s->pressure = !!buttons_state;
958

959
    /*
960
     * Note: We would get better responsiveness in the guest by
961
     * signaling TS events immediately, but for now we simulate
962
     * the first conversion delay for sake of correctness.
963
     */
964
    if (p != s->pressure)
965
        tsc210x_pin_update(s);
966
}
967

968
static void tsc210x_i2s_swallow(TSC210xState *s)
969
{
970
    if (s->dac_voice[0])
971
        tsc210x_out_flush(s, s->codec.out.len);
972
    else
973
        s->codec.out.len = 0;
974
}
975

976
static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
977
{
978
    s->i2s_tx_rate = out;
979
    s->i2s_rx_rate = in;
980
}
981

982
static int tsc210x_pre_save(void *opaque)
983
{
984
    TSC210xState *s = (TSC210xState *) opaque;
985
    s->now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
986

987
    return 0;
988
}
989

990
static int tsc210x_post_load(void *opaque, int version_id)
991
{
992
    TSC210xState *s = (TSC210xState *) opaque;
993
    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
994

995
    if (s->function >= ARRAY_SIZE(mode_regs)) {
996
        return -EINVAL;
997
    }
998
    if (s->nextfunction >= ARRAY_SIZE(mode_regs)) {
999
        return -EINVAL;
1000
    }
1001
    if (s->precision >= ARRAY_SIZE(resolution)) {
1002
        return -EINVAL;
1003
    }
1004
    if (s->nextprecision >= ARRAY_SIZE(resolution)) {
1005
        return -EINVAL;
1006
    }
1007

1008
    s->volume_change -= s->now;
1009
    s->volume_change += now;
1010
    s->powerdown -= s->now;
1011
    s->powerdown += now;
1012

1013
    s->busy = timer_pending(s->timer);
1014
    qemu_set_irq(s->pint, !s->irq);
1015
    qemu_set_irq(s->davint, !s->dav);
1016

1017
    return 0;
1018
}
1019

1020
static const VMStateField vmstatefields_tsc210x[] = {
1021
    VMSTATE_BOOL(enabled, TSC210xState),
1022
    VMSTATE_BOOL(host_mode, TSC210xState),
1023
    VMSTATE_BOOL(irq, TSC210xState),
1024
    VMSTATE_BOOL(command, TSC210xState),
1025
    VMSTATE_BOOL(pressure, TSC210xState),
1026
    VMSTATE_BOOL(softstep, TSC210xState),
1027
    VMSTATE_BOOL(state, TSC210xState),
1028
    VMSTATE_UINT16(dav, TSC210xState),
1029
    VMSTATE_INT32(x, TSC210xState),
1030
    VMSTATE_INT32(y, TSC210xState),
1031
    VMSTATE_UINT8(offset, TSC210xState),
1032
    VMSTATE_UINT8(page, TSC210xState),
1033
    VMSTATE_UINT8(filter, TSC210xState),
1034
    VMSTATE_UINT8(pin_func, TSC210xState),
1035
    VMSTATE_UINT8(ref, TSC210xState),
1036
    VMSTATE_UINT8(timing, TSC210xState),
1037
    VMSTATE_UINT8(noise, TSC210xState),
1038
    VMSTATE_UINT8(function, TSC210xState),
1039
    VMSTATE_UINT8(nextfunction, TSC210xState),
1040
    VMSTATE_UINT8(precision, TSC210xState),
1041
    VMSTATE_UINT8(nextprecision, TSC210xState),
1042
    VMSTATE_UINT16(audio_ctrl1, TSC210xState),
1043
    VMSTATE_UINT16(audio_ctrl2, TSC210xState),
1044
    VMSTATE_UINT16(audio_ctrl3, TSC210xState),
1045
    VMSTATE_UINT16_ARRAY(pll, TSC210xState, 3),
1046
    VMSTATE_UINT16(volume, TSC210xState),
1047
    VMSTATE_UINT16(dac_power, TSC210xState),
1048
    VMSTATE_INT64(volume_change, TSC210xState),
1049
    VMSTATE_INT64(powerdown, TSC210xState),
1050
    VMSTATE_INT64(now, TSC210xState),
1051
    VMSTATE_UINT16_ARRAY(filter_data, TSC210xState, 0x14),
1052
    VMSTATE_TIMER_PTR(timer, TSC210xState),
1053
    VMSTATE_END_OF_LIST()
1054
};
1055

1056
static const VMStateDescription vmstate_tsc2102 = {
1057
    .name = "tsc2102",
1058
    .version_id = 1,
1059
    .minimum_version_id = 1,
1060
    .pre_save = tsc210x_pre_save,
1061
    .post_load = tsc210x_post_load,
1062
    .fields = vmstatefields_tsc210x,
1063
};
1064

1065
static const VMStateDescription vmstate_tsc2301 = {
1066
    .name = "tsc2301",
1067
    .version_id = 1,
1068
    .minimum_version_id = 1,
1069
    .pre_save = tsc210x_pre_save,
1070
    .post_load = tsc210x_post_load,
1071
    .fields = vmstatefields_tsc210x,
1072
};
1073

1074
static void tsc210x_init(TSC210xState *s,
1075
                         const char *name,
1076
                         const VMStateDescription *vmsd)
1077
{
1078
    s->tr[0] = 0;
1079
    s->tr[1] = 1;
1080
    s->tr[2] = 1;
1081
    s->tr[3] = 0;
1082
    s->tr[4] = 1;
1083
    s->tr[5] = 0;
1084
    s->tr[6] = 1;
1085
    s->tr[7] = 0;
1086

1087
    s->chip.opaque = s;
1088
    s->chip.send = (void *) tsc210x_write;
1089
    s->chip.receive = (void *) tsc210x_read;
1090

1091
    s->codec.opaque = s;
1092
    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1093
    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1094
    s->codec.in.fifo = s->in_fifo;
1095
    s->codec.out.fifo = s->out_fifo;
1096

1097
    tsc210x_reset(s);
1098

1099
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, name);
1100

1101
    if (current_machine->audiodev) {
1102
        s->card.name = g_strdup(current_machine->audiodev);
1103
        s->card.state = audio_state_by_name(s->card.name, &error_fatal);
1104
    }
1105
    AUD_register_card(s->name, &s->card, &error_fatal);
1106

1107
    qemu_register_reset((void *) tsc210x_reset, s);
1108
    vmstate_register(NULL, 0, vmsd, s);
1109
}
1110

1111
uWireSlave *tsc2102_init(qemu_irq pint)
1112
{
1113
    TSC210xState *s;
1114

1115
    s = g_new0(TSC210xState, 1);
1116
    s->x = 160;
1117
    s->y = 160;
1118
    s->pressure = 0;
1119
    s->precision = s->nextprecision = 0;
1120
    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
1121
    s->pint = pint;
1122
    s->model = 0x2102;
1123
    s->name = "tsc2102";
1124

1125
    tsc210x_init(s, "QEMU TSC2102-driven Touchscreen", &vmstate_tsc2102);
1126

1127
    return &s->chip;
1128
}
1129

1130
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
1131
{
1132
    TSC210xState *s;
1133

1134
    s = g_new0(TSC210xState, 1);
1135
    s->x = 400;
1136
    s->y = 240;
1137
    s->pressure = 0;
1138
    s->precision = s->nextprecision = 0;
1139
    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
1140
    s->pint = penirq;
1141
    s->kbint = kbirq;
1142
    s->davint = dav;
1143
    s->model = 0x2301;
1144
    s->name = "tsc2301";
1145

1146
    tsc210x_init(s, "QEMU TSC2301-driven Touchscreen", &vmstate_tsc2301);
1147

1148
    return &s->chip;
1149
}
1150

1151
I2SCodec *tsc210x_codec(uWireSlave *chip)
1152
{
1153
    TSC210xState *s = (TSC210xState *) chip->opaque;
1154

1155
    return &s->codec;
1156
}
1157

1158
/*
1159
 * Use tslib generated calibration data to generate ADC input values
1160
 * from the touchscreen.  Assuming 12-bit precision was used during
1161
 * tslib calibration.
1162
 */
1163
void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info)
1164
{
1165
    TSC210xState *s = (TSC210xState *) chip->opaque;
1166
#if 0
1167
    int64_t ltr[8];
1168

1169
    ltr[0] = (int64_t) info->a[1] * info->y;
1170
    ltr[1] = (int64_t) info->a[4] * info->x;
1171
    ltr[2] = (int64_t) info->a[1] * info->a[3] -
1172
            (int64_t) info->a[4] * info->a[0];
1173
    ltr[3] = (int64_t) info->a[2] * info->a[4] -
1174
            (int64_t) info->a[5] * info->a[1];
1175
    ltr[4] = (int64_t) info->a[0] * info->y;
1176
    ltr[5] = (int64_t) info->a[3] * info->x;
1177
    ltr[6] = (int64_t) info->a[4] * info->a[0] -
1178
            (int64_t) info->a[1] * info->a[3];
1179
    ltr[7] = (int64_t) info->a[2] * info->a[3] -
1180
            (int64_t) info->a[5] * info->a[0];
1181

1182
    /* Avoid integer overflow */
1183
    s->tr[0] = ltr[0] >> 11;
1184
    s->tr[1] = ltr[1] >> 11;
1185
    s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
1186
    s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
1187
    s->tr[4] = ltr[4] >> 11;
1188
    s->tr[5] = ltr[5] >> 11;
1189
    s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
1190
    s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
1191
#else
1192

1193
    /* This version assumes touchscreen X & Y axis are parallel or
1194
     * perpendicular to LCD's  X & Y axis in some way.  */
1195
    if (abs(info->a[0]) > abs(info->a[1])) {
1196
        s->tr[0] = 0;
1197
        s->tr[1] = -info->a[6] * info->x;
1198
        s->tr[2] = info->a[0];
1199
        s->tr[3] = -info->a[2] / info->a[0];
1200
        s->tr[4] = info->a[6] * info->y;
1201
        s->tr[5] = 0;
1202
        s->tr[6] = info->a[4];
1203
        s->tr[7] = -info->a[5] / info->a[4];
1204
    } else {
1205
        s->tr[0] = info->a[6] * info->y;
1206
        s->tr[1] = 0;
1207
        s->tr[2] = info->a[1];
1208
        s->tr[3] = -info->a[2] / info->a[1];
1209
        s->tr[4] = 0;
1210
        s->tr[5] = -info->a[6] * info->x;
1211
        s->tr[6] = info->a[3];
1212
        s->tr[7] = -info->a[5] / info->a[3];
1213
    }
1214

1215
    s->tr[0] >>= 11;
1216
    s->tr[1] >>= 11;
1217
    s->tr[3] <<= 4;
1218
    s->tr[4] >>= 11;
1219
    s->tr[5] >>= 11;
1220
    s->tr[7] <<= 4;
1221
#endif
1222
}
1223

1224
void tsc210x_key_event(uWireSlave *chip, int key, int down)
1225
{
1226
    TSC210xState *s = (TSC210xState *) chip->opaque;
1227

1228
    if (down)
1229
        s->kb.down |= 1 << key;
1230
    else
1231
        s->kb.down &= ~(1 << key);
1232

1233
    if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
1234
        s->kb.intr = 1;
1235
        qemu_irq_lower(s->kbint);
1236
    } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
1237
                    !(s->kb.mode & 1)) {
1238
        s->kb.intr = 0;
1239
        qemu_irq_raise(s->kbint);
1240
    }
1241
}
1242

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.