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