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