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