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