Statistics
| Branch: | Revision:

root / hw / tsc210x.c @ 66450b15

History | View | Annotate | Download (22.7 kB)

1 3efda49d balrog
/*
2 7fc42b4b balrog
 * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
3 3efda49d balrog
 *
4 3efda49d balrog
 * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
5 3efda49d balrog
 *
6 3efda49d balrog
 * This program is free software; you can redistribute it and/or
7 3efda49d balrog
 * modify it under the terms of the GNU General Public License as
8 3efda49d balrog
 * published by the Free Software Foundation; either version 2 of
9 3efda49d balrog
 * the License, or (at your option) any later version.
10 3efda49d balrog
 *
11 3efda49d balrog
 * This program is distributed in the hope that it will be useful,
12 3efda49d balrog
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 3efda49d balrog
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 3efda49d balrog
 * GNU General Public License for more details.
15 3efda49d balrog
 *
16 3efda49d balrog
 * You should have received a copy of the GNU General Public License
17 3efda49d balrog
 * along with this program; if not, write to the Free Software
18 3efda49d balrog
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 3efda49d balrog
 * MA 02111-1307 USA
20 3efda49d balrog
 */
21 3efda49d balrog
22 3efda49d balrog
#include "vl.h"
23 3efda49d balrog
24 3efda49d balrog
#define TSC_DATA_REGISTERS_PAGE                0x0
25 3efda49d balrog
#define TSC_CONTROL_REGISTERS_PAGE        0x1
26 3efda49d balrog
#define TSC_AUDIO_REGISTERS_PAGE        0x2
27 3efda49d balrog
28 3efda49d balrog
#define TSC_VERBOSE
29 3efda49d balrog
30 3efda49d balrog
#define TSC_CUT_RESOLUTION(value, p)        ((value) >> (16 - resolution[p]))
31 3efda49d balrog
32 3efda49d balrog
struct tsc210x_state_s {
33 3efda49d balrog
    qemu_irq pint;
34 3efda49d balrog
    QEMUTimer *timer;
35 3efda49d balrog
    struct uwire_slave_s chip;
36 3efda49d balrog
37 3efda49d balrog
    int x, y;
38 3efda49d balrog
    int pressure;
39 3efda49d balrog
40 3efda49d balrog
    int state, page, offset, irq;
41 3efda49d balrog
    uint16_t command, dav;
42 3efda49d balrog
43 3efda49d balrog
    int busy;
44 3efda49d balrog
    int enabled;
45 3efda49d balrog
    int host_mode;
46 3efda49d balrog
    int function;
47 3efda49d balrog
    int nextfunction;
48 3efda49d balrog
    int precision;
49 3efda49d balrog
    int nextprecision;
50 3efda49d balrog
    int filter;
51 3efda49d balrog
    int pin_func;
52 3efda49d balrog
    int ref;
53 3efda49d balrog
    int timing;
54 3efda49d balrog
    int noise;
55 3efda49d balrog
56 3efda49d balrog
    uint16_t audio_ctrl1;
57 3efda49d balrog
    uint16_t audio_ctrl2;
58 3efda49d balrog
    uint16_t audio_ctrl3;
59 3efda49d balrog
    uint16_t pll[2];
60 3efda49d balrog
    uint16_t volume;
61 3efda49d balrog
    int64_t volume_change;
62 3efda49d balrog
    int softstep;
63 3efda49d balrog
    uint16_t dac_power;
64 3efda49d balrog
    int64_t powerdown;
65 3efda49d balrog
    uint16_t filter_data[0x14];
66 3efda49d balrog
};
67 3efda49d balrog
68 3efda49d balrog
static const int resolution[4] = { 12, 8, 10, 12 };
69 3efda49d balrog
70 3efda49d balrog
#define TSC_MODE_NO_SCAN        0x0
71 3efda49d balrog
#define TSC_MODE_XY_SCAN        0x1
72 3efda49d balrog
#define TSC_MODE_XYZ_SCAN        0x2
73 3efda49d balrog
#define TSC_MODE_X                0x3
74 3efda49d balrog
#define TSC_MODE_Y                0x4
75 3efda49d balrog
#define TSC_MODE_Z                0x5
76 3efda49d balrog
#define TSC_MODE_BAT1                0x6
77 3efda49d balrog
#define TSC_MODE_BAT2                0x7
78 3efda49d balrog
#define TSC_MODE_AUX                0x8
79 3efda49d balrog
#define TSC_MODE_AUX_SCAN        0x9
80 3efda49d balrog
#define TSC_MODE_TEMP1                0xa
81 3efda49d balrog
#define TSC_MODE_PORT_SCAN        0xb
82 3efda49d balrog
#define TSC_MODE_TEMP2                0xc
83 3efda49d balrog
#define TSC_MODE_XX_DRV                0xd
84 3efda49d balrog
#define TSC_MODE_YY_DRV                0xe
85 3efda49d balrog
#define TSC_MODE_YX_DRV                0xf
86 3efda49d balrog
87 3efda49d balrog
static const uint16_t mode_regs[16] = {
88 3efda49d balrog
    0x0000,        /* No scan */
89 3efda49d balrog
    0x0600,        /* X, Y scan */
90 3efda49d balrog
    0x0780,        /* X, Y, Z scan */
91 3efda49d balrog
    0x0400,        /* X */
92 3efda49d balrog
    0x0200,        /* Y */
93 3efda49d balrog
    0x0180,        /* Z */
94 3efda49d balrog
    0x0040,        /* BAT1 */
95 3efda49d balrog
    0x0030,        /* BAT2 */
96 3efda49d balrog
    0x0010,        /* AUX */
97 3efda49d balrog
    0x0010,        /* AUX scan */
98 3efda49d balrog
    0x0004,        /* TEMP1 */
99 3efda49d balrog
    0x0070,        /* Port scan */
100 3efda49d balrog
    0x0002,        /* TEMP2 */
101 3efda49d balrog
    0x0000,        /* X+, X- drivers */
102 3efda49d balrog
    0x0000,        /* Y+, Y- drivers */
103 3efda49d balrog
    0x0000,        /* Y+, X- drivers */
104 3efda49d balrog
};
105 3efda49d balrog
106 3efda49d balrog
/*
107 3efda49d balrog
 * Convert screen coordinates to arbitrary values that the
108 3efda49d balrog
 * touchscreen in my Palm Tungsten E device returns.
109 3efda49d balrog
 * This shouldn't really matter (because the guest system
110 3efda49d balrog
 * should calibrate the touchscreen anyway), but let's
111 3efda49d balrog
 * imitate some real hardware.
112 3efda49d balrog
 */
113 3efda49d balrog
#define X_TRANSFORM(value)                \
114 3efda49d balrog
    ((3850 - ((int) (value) * (3850 - 250) / 32768)) << 4)
115 3efda49d balrog
#define Y_TRANSFORM(value)                \
116 3efda49d balrog
    ((150 + ((int) (value) * (3037 - 150) / 32768)) << 4)
117 3efda49d balrog
#define Z1_TRANSFORM(s)                        \
118 3efda49d balrog
    ((400 - (s)->x + ((s)->pressure << 9)) << 4)
119 3efda49d balrog
#define Z2_TRANSFORM(s)                        \
120 3efda49d balrog
    ((4000 + (s)->y - ((s)->pressure << 10)) << 4)
121 3efda49d balrog
#define BAT1_VAL                        0x8660
122 3efda49d balrog
#define BAT2_VAL                        0x0000
123 3efda49d balrog
#define AUX1_VAL                        0x35c0
124 3efda49d balrog
#define AUX2_VAL                        0xffff
125 3efda49d balrog
#define TEMP1_VAL                        0x8c70
126 3efda49d balrog
#define TEMP2_VAL                        0xa5b0
127 3efda49d balrog
128 3efda49d balrog
#define TSC_POWEROFF_DELAY                50
129 3efda49d balrog
#define TSC_SOFTSTEP_DELAY                50
130 3efda49d balrog
131 3efda49d balrog
static void tsc210x_reset(struct tsc210x_state_s *s)
132 3efda49d balrog
{
133 3efda49d balrog
    s->state = 0;
134 3efda49d balrog
    s->pin_func = 2;
135 3efda49d balrog
    s->enabled = 0;
136 3efda49d balrog
    s->busy = 0;
137 3efda49d balrog
    s->nextfunction = 0;
138 3efda49d balrog
    s->ref = 0;
139 3efda49d balrog
    s->timing = 0;
140 3efda49d balrog
    s->irq = 0;
141 3efda49d balrog
    s->dav = 0;
142 3efda49d balrog
143 3efda49d balrog
    s->audio_ctrl1 = 0x0000;
144 3efda49d balrog
    s->audio_ctrl2 = 0x4410;
145 3efda49d balrog
    s->audio_ctrl3 = 0x0000;
146 3efda49d balrog
    s->pll[0] = 0x1004;
147 3efda49d balrog
    s->pll[1] = 0x0000;
148 3efda49d balrog
    s->volume = 0xffff;
149 3efda49d balrog
    s->dac_power = 0x8540;
150 3efda49d balrog
    s->softstep = 1;
151 3efda49d balrog
    s->volume_change = 0;
152 3efda49d balrog
    s->powerdown = 0;
153 3efda49d balrog
    s->filter_data[0x00] = 0x6be3;
154 3efda49d balrog
    s->filter_data[0x01] = 0x9666;
155 3efda49d balrog
    s->filter_data[0x02] = 0x675d;
156 3efda49d balrog
    s->filter_data[0x03] = 0x6be3;
157 3efda49d balrog
    s->filter_data[0x04] = 0x9666;
158 3efda49d balrog
    s->filter_data[0x05] = 0x675d;
159 3efda49d balrog
    s->filter_data[0x06] = 0x7d83;
160 3efda49d balrog
    s->filter_data[0x07] = 0x84ee;
161 3efda49d balrog
    s->filter_data[0x08] = 0x7d83;
162 3efda49d balrog
    s->filter_data[0x09] = 0x84ee;
163 3efda49d balrog
    s->filter_data[0x0a] = 0x6be3;
164 3efda49d balrog
    s->filter_data[0x0b] = 0x9666;
165 3efda49d balrog
    s->filter_data[0x0c] = 0x675d;
166 3efda49d balrog
    s->filter_data[0x0d] = 0x6be3;
167 3efda49d balrog
    s->filter_data[0x0e] = 0x9666;
168 3efda49d balrog
    s->filter_data[0x0f] = 0x675d;
169 3efda49d balrog
    s->filter_data[0x10] = 0x7d83;
170 3efda49d balrog
    s->filter_data[0x11] = 0x84ee;
171 3efda49d balrog
    s->filter_data[0x12] = 0x7d83;
172 3efda49d balrog
    s->filter_data[0x13] = 0x84ee;
173 3efda49d balrog
174 7fc42b4b balrog
    qemu_set_irq(s->pint, !s->irq);
175 3efda49d balrog
}
176 3efda49d balrog
177 3efda49d balrog
static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
178 3efda49d balrog
{
179 3efda49d balrog
    switch (reg) {
180 3efda49d balrog
    case 0x00:        /* X */
181 3efda49d balrog
        s->dav &= 0xfbff;
182 3efda49d balrog
        return TSC_CUT_RESOLUTION(X_TRANSFORM(s->x), s->precision) +
183 3efda49d balrog
                (s->noise & 3);
184 3efda49d balrog
185 3efda49d balrog
    case 0x01:        /* Y */
186 3efda49d balrog
        s->noise ++;
187 3efda49d balrog
        s->dav &= 0xfdff;
188 3efda49d balrog
        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s->y), s->precision) ^
189 3efda49d balrog
                (s->noise & 3);
190 3efda49d balrog
191 3efda49d balrog
    case 0x02:        /* Z1 */
192 3efda49d balrog
        s->dav &= 0xfeff;
193 3efda49d balrog
        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
194 3efda49d balrog
                (s->noise & 3);
195 3efda49d balrog
196 3efda49d balrog
    case 0x03:        /* Z2 */
197 3efda49d balrog
        s->dav &= 0xff7f;
198 3efda49d balrog
        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
199 3efda49d balrog
                (s->noise & 3);
200 3efda49d balrog
201 3efda49d balrog
    case 0x04:        /* KPData */
202 3efda49d balrog
        return 0xffff;
203 3efda49d balrog
204 3efda49d balrog
    case 0x05:        /* BAT1 */
205 3efda49d balrog
        s->dav &= 0xffbf;
206 3efda49d balrog
        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision);
207 3efda49d balrog
208 3efda49d balrog
    case 0x06:        /* BAT2 */
209 3efda49d balrog
        s->dav &= 0xffdf;
210 3efda49d balrog
        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
211 3efda49d balrog
212 3efda49d balrog
    case 0x07:        /* AUX1 */
213 3efda49d balrog
        s->dav &= 0xffef;
214 3efda49d balrog
        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
215 3efda49d balrog
216 3efda49d balrog
    case 0x08:        /* AUX2 */
217 3efda49d balrog
        s->dav &= 0xfff7;
218 3efda49d balrog
        return 0xffff;
219 3efda49d balrog
220 3efda49d balrog
    case 0x09:        /* TEMP1 */
221 3efda49d balrog
        s->dav &= 0xfffb;
222 3efda49d balrog
        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision);
223 3efda49d balrog
224 3efda49d balrog
    case 0x0a:        /* TEMP2 */
225 3efda49d balrog
        s->dav &= 0xfffd;
226 3efda49d balrog
        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision);
227 3efda49d balrog
228 3efda49d balrog
    case 0x0b:        /* DAC */
229 3efda49d balrog
        s->dav &= 0xfffe;
230 3efda49d balrog
        return 0xffff;
231 3efda49d balrog
232 3efda49d balrog
    default:
233 3efda49d balrog
#ifdef TSC_VERBOSE
234 3efda49d balrog
        fprintf(stderr, "tsc2102_data_register_read: "
235 3efda49d balrog
                        "no such register: 0x%02x\n", reg);
236 3efda49d balrog
#endif
237 3efda49d balrog
        return 0xffff;
238 3efda49d balrog
    }
239 3efda49d balrog
}
240 3efda49d balrog
241 3efda49d balrog
static uint16_t tsc2102_control_register_read(
242 3efda49d balrog
                struct tsc210x_state_s *s, int reg)
243 3efda49d balrog
{
244 3efda49d balrog
    switch (reg) {
245 3efda49d balrog
    case 0x00:        /* TSC ADC */
246 3efda49d balrog
        return (s->pressure << 15) | ((!s->busy) << 14) |
247 3efda49d balrog
                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
248 3efda49d balrog
249 3efda49d balrog
    case 0x01:        /* Status */
250 3efda49d balrog
        return (s->pin_func << 14) | ((!s->enabled) << 13) |
251 3efda49d balrog
                (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
252 3efda49d balrog
253 3efda49d balrog
    case 0x03:        /* Reference */
254 3efda49d balrog
        return s->ref;
255 3efda49d balrog
256 3efda49d balrog
    case 0x04:        /* Reset */
257 3efda49d balrog
        return 0xffff;
258 3efda49d balrog
259 3efda49d balrog
    case 0x05:        /* Configuration */
260 3efda49d balrog
        return s->timing;
261 3efda49d balrog
262 3efda49d balrog
    default:
263 3efda49d balrog
#ifdef TSC_VERBOSE
264 3efda49d balrog
        fprintf(stderr, "tsc2102_control_register_read: "
265 3efda49d balrog
                        "no such register: 0x%02x\n", reg);
266 3efda49d balrog
#endif
267 3efda49d balrog
        return 0xffff;
268 3efda49d balrog
    }
269 3efda49d balrog
}
270 3efda49d balrog
271 3efda49d balrog
static uint16_t tsc2102_audio_register_read(struct tsc210x_state_s *s, int reg)
272 3efda49d balrog
{
273 3efda49d balrog
    int l_ch, r_ch;
274 3efda49d balrog
    uint16_t val;
275 3efda49d balrog
276 3efda49d balrog
    switch (reg) {
277 3efda49d balrog
    case 0x00:        /* Audio Control 1 */
278 3efda49d balrog
        return s->audio_ctrl1;
279 3efda49d balrog
280 3efda49d balrog
    case 0x01:
281 3efda49d balrog
        return 0xff00;
282 3efda49d balrog
283 3efda49d balrog
    case 0x02:        /* DAC Volume Control */
284 3efda49d balrog
        return s->volume;
285 3efda49d balrog
286 3efda49d balrog
    case 0x03:
287 3efda49d balrog
        return 0x8b00;
288 3efda49d balrog
289 3efda49d balrog
    case 0x04:        /* Audio Control 2 */
290 3efda49d balrog
        l_ch = 1;
291 3efda49d balrog
        r_ch = 1;
292 3efda49d balrog
        if (s->softstep && !(s->dac_power & (1 << 10))) {
293 3efda49d balrog
            l_ch = (qemu_get_clock(vm_clock) >
294 3efda49d balrog
                            s->volume_change + TSC_SOFTSTEP_DELAY);
295 3efda49d balrog
            r_ch = (qemu_get_clock(vm_clock) >
296 3efda49d balrog
                            s->volume_change + TSC_SOFTSTEP_DELAY);
297 3efda49d balrog
        }
298 3efda49d balrog
299 3efda49d balrog
        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
300 3efda49d balrog
301 3efda49d balrog
    case 0x05:        /* Stereo DAC Power Control */
302 3efda49d balrog
        return 0x2aa0 | s->dac_power |
303 3efda49d balrog
                (((s->dac_power & (1 << 10)) &&
304 3efda49d balrog
                  (qemu_get_clock(vm_clock) >
305 3efda49d balrog
                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
306 3efda49d balrog
307 3efda49d balrog
    case 0x06:        /* Audio Control 3 */
308 3efda49d balrog
        val = s->audio_ctrl3 | 0x0001;
309 3efda49d balrog
        s->audio_ctrl3 &= 0xff3f;
310 3efda49d balrog
        return val;
311 3efda49d balrog
312 3efda49d balrog
    case 0x07:        /* LCH_BASS_BOOST_N0 */
313 3efda49d balrog
    case 0x08:        /* LCH_BASS_BOOST_N1 */
314 3efda49d balrog
    case 0x09:        /* LCH_BASS_BOOST_N2 */
315 3efda49d balrog
    case 0x0a:        /* LCH_BASS_BOOST_N3 */
316 3efda49d balrog
    case 0x0b:        /* LCH_BASS_BOOST_N4 */
317 3efda49d balrog
    case 0x0c:        /* LCH_BASS_BOOST_N5 */
318 3efda49d balrog
    case 0x0d:        /* LCH_BASS_BOOST_D1 */
319 3efda49d balrog
    case 0x0e:        /* LCH_BASS_BOOST_D2 */
320 3efda49d balrog
    case 0x0f:        /* LCH_BASS_BOOST_D4 */
321 3efda49d balrog
    case 0x10:        /* LCH_BASS_BOOST_D5 */
322 3efda49d balrog
    case 0x11:        /* RCH_BASS_BOOST_N0 */
323 3efda49d balrog
    case 0x12:        /* RCH_BASS_BOOST_N1 */
324 3efda49d balrog
    case 0x13:        /* RCH_BASS_BOOST_N2 */
325 3efda49d balrog
    case 0x14:        /* RCH_BASS_BOOST_N3 */
326 3efda49d balrog
    case 0x15:        /* RCH_BASS_BOOST_N4 */
327 3efda49d balrog
    case 0x16:        /* RCH_BASS_BOOST_N5 */
328 3efda49d balrog
    case 0x17:        /* RCH_BASS_BOOST_D1 */
329 3efda49d balrog
    case 0x18:        /* RCH_BASS_BOOST_D2 */
330 3efda49d balrog
    case 0x19:        /* RCH_BASS_BOOST_D4 */
331 3efda49d balrog
    case 0x1a:        /* RCH_BASS_BOOST_D5 */
332 3efda49d balrog
        return s->filter_data[reg - 0x07];
333 3efda49d balrog
334 3efda49d balrog
    case 0x1b:        /* PLL Programmability 1 */
335 3efda49d balrog
        return s->pll[0];
336 3efda49d balrog
337 3efda49d balrog
    case 0x1c:        /* PLL Programmability 2 */
338 3efda49d balrog
        return s->pll[1];
339 3efda49d balrog
340 3efda49d balrog
    case 0x1d:        /* Audio Control 4 */
341 3efda49d balrog
        return (!s->softstep) << 14;
342 3efda49d balrog
343 3efda49d balrog
    default:
344 3efda49d balrog
#ifdef TSC_VERBOSE
345 3efda49d balrog
        fprintf(stderr, "tsc2102_audio_register_read: "
346 3efda49d balrog
                        "no such register: 0x%02x\n", reg);
347 3efda49d balrog
#endif
348 3efda49d balrog
        return 0xffff;
349 3efda49d balrog
    }
350 3efda49d balrog
}
351 3efda49d balrog
352 3efda49d balrog
static void tsc2102_data_register_write(
353 3efda49d balrog
                struct tsc210x_state_s *s, int reg, uint16_t value)
354 3efda49d balrog
{
355 3efda49d balrog
    switch (reg) {
356 3efda49d balrog
    case 0x00:        /* X */
357 3efda49d balrog
    case 0x01:        /* Y */
358 3efda49d balrog
    case 0x02:        /* Z1 */
359 3efda49d balrog
    case 0x03:        /* Z2 */
360 3efda49d balrog
    case 0x05:        /* BAT1 */
361 3efda49d balrog
    case 0x06:        /* BAT2 */
362 3efda49d balrog
    case 0x07:        /* AUX1 */
363 3efda49d balrog
    case 0x08:        /* AUX2 */
364 3efda49d balrog
    case 0x09:        /* TEMP1 */
365 3efda49d balrog
    case 0x0a:        /* TEMP2 */
366 3efda49d balrog
        return;
367 3efda49d balrog
368 3efda49d balrog
    default:
369 3efda49d balrog
#ifdef TSC_VERBOSE
370 3efda49d balrog
        fprintf(stderr, "tsc2102_data_register_write: "
371 3efda49d balrog
                        "no such register: 0x%02x\n", reg);
372 3efda49d balrog
#endif
373 3efda49d balrog
    }
374 3efda49d balrog
}
375 3efda49d balrog
376 3efda49d balrog
static void tsc2102_control_register_write(
377 3efda49d balrog
                struct tsc210x_state_s *s, int reg, uint16_t value)
378 3efda49d balrog
{
379 3efda49d balrog
    switch (reg) {
380 3efda49d balrog
    case 0x00:        /* TSC ADC */
381 3efda49d balrog
        s->host_mode = value >> 15;
382 3efda49d balrog
        s->enabled = !(value & 0x4000);
383 3efda49d balrog
        if (s->busy && !s->enabled)
384 3efda49d balrog
            qemu_del_timer(s->timer);
385 3efda49d balrog
        s->busy &= s->enabled;
386 3efda49d balrog
        s->nextfunction = (value >> 10) & 0xf;
387 3efda49d balrog
        s->nextprecision = (value >> 8) & 3;
388 3efda49d balrog
        s->filter = value & 0xff;
389 3efda49d balrog
        return;
390 3efda49d balrog
391 3efda49d balrog
    case 0x01:        /* Status */
392 3efda49d balrog
        s->pin_func = value >> 14;
393 3efda49d balrog
        return;
394 3efda49d balrog
395 3efda49d balrog
    case 0x03:        /* Reference */
396 3efda49d balrog
        s->ref = value & 0x1f;
397 3efda49d balrog
        return;
398 3efda49d balrog
399 3efda49d balrog
    case 0x04:        /* Reset */
400 3efda49d balrog
        if (value == 0xbb00) {
401 3efda49d balrog
            if (s->busy)
402 3efda49d balrog
                qemu_del_timer(s->timer);
403 3efda49d balrog
            tsc210x_reset(s);
404 3efda49d balrog
#ifdef TSC_VERBOSE
405 3efda49d balrog
        } else {
406 3efda49d balrog
            fprintf(stderr, "tsc2102_control_register_write: "
407 3efda49d balrog
                            "wrong value written into RESET\n");
408 3efda49d balrog
#endif
409 3efda49d balrog
        }
410 3efda49d balrog
        return;
411 3efda49d balrog
412 3efda49d balrog
    case 0x05:        /* Configuration */
413 3efda49d balrog
        s->timing = value & 0x3f;
414 3efda49d balrog
#ifdef TSC_VERBOSE
415 3efda49d balrog
        if (value & ~0x3f)
416 3efda49d balrog
            fprintf(stderr, "tsc2102_control_register_write: "
417 3efda49d balrog
                            "wrong value written into CONFIG\n");
418 3efda49d balrog
#endif
419 3efda49d balrog
        return;
420 3efda49d balrog
421 3efda49d balrog
    default:
422 3efda49d balrog
#ifdef TSC_VERBOSE
423 3efda49d balrog
        fprintf(stderr, "tsc2102_control_register_write: "
424 3efda49d balrog
                        "no such register: 0x%02x\n", reg);
425 3efda49d balrog
#endif
426 3efda49d balrog
    }
427 3efda49d balrog
}
428 3efda49d balrog
429 3efda49d balrog
static void tsc2102_audio_register_write(
430 3efda49d balrog
                struct tsc210x_state_s *s, int reg, uint16_t value)
431 3efda49d balrog
{
432 3efda49d balrog
    switch (reg) {
433 3efda49d balrog
    case 0x00:        /* Audio Control 1 */
434 3efda49d balrog
        s->audio_ctrl1 = value & 0x0f3f;
435 3efda49d balrog
#ifdef TSC_VERBOSE
436 3efda49d balrog
        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
437 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
438 3efda49d balrog
                            "wrong value written into Audio 1\n");
439 3efda49d balrog
#endif
440 3efda49d balrog
        return;
441 3efda49d balrog
442 3efda49d balrog
    case 0x01:
443 3efda49d balrog
#ifdef TSC_VERBOSE
444 3efda49d balrog
        if (value != 0xff00)
445 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
446 3efda49d balrog
                            "wrong value written into reg 0x01\n");
447 3efda49d balrog
#endif
448 3efda49d balrog
        return;
449 3efda49d balrog
450 3efda49d balrog
    case 0x02:        /* DAC Volume Control */
451 3efda49d balrog
        s->volume = value;
452 3efda49d balrog
        s->volume_change = qemu_get_clock(vm_clock);
453 3efda49d balrog
        return;
454 3efda49d balrog
455 3efda49d balrog
    case 0x03:
456 3efda49d balrog
#ifdef TSC_VERBOSE
457 3efda49d balrog
        if (value != 0x8b00)
458 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
459 3efda49d balrog
                            "wrong value written into reg 0x03\n");
460 3efda49d balrog
#endif
461 3efda49d balrog
        return;
462 3efda49d balrog
463 3efda49d balrog
    case 0x04:        /* Audio Control 2 */
464 3efda49d balrog
        s->audio_ctrl2 = value & 0xf7f2;
465 3efda49d balrog
#ifdef TSC_VERBOSE
466 3efda49d balrog
        if (value & ~0xf7fd)
467 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
468 3efda49d balrog
                            "wrong value written into Audio 2\n");
469 3efda49d balrog
#endif
470 3efda49d balrog
        return;
471 3efda49d balrog
472 3efda49d balrog
    case 0x05:        /* Stereo DAC Power Control */
473 3efda49d balrog
        if ((value & ~s->dac_power) & (1 << 10))
474 3efda49d balrog
            s->powerdown = qemu_get_clock(vm_clock);
475 3efda49d balrog
476 3efda49d balrog
        s->dac_power = value & 0x9543;
477 3efda49d balrog
#ifdef TSC_VERBOSE
478 3efda49d balrog
        if ((value & ~0x9543) != 0x2aa0)
479 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
480 3efda49d balrog
                            "wrong value written into Power\n");
481 3efda49d balrog
#endif
482 3efda49d balrog
        return;
483 3efda49d balrog
484 3efda49d balrog
    case 0x06:        /* Audio Control 3 */
485 3efda49d balrog
        s->audio_ctrl3 &= 0x00c0;
486 3efda49d balrog
        s->audio_ctrl3 |= value & 0xf800;
487 3efda49d balrog
#ifdef TSC_VERBOSE
488 3efda49d balrog
        if (value & ~0xf8c7)
489 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
490 3efda49d balrog
                            "wrong value written into Audio 3\n");
491 3efda49d balrog
#endif
492 3efda49d balrog
        return;
493 3efda49d balrog
494 3efda49d balrog
    case 0x07:        /* LCH_BASS_BOOST_N0 */
495 3efda49d balrog
    case 0x08:        /* LCH_BASS_BOOST_N1 */
496 3efda49d balrog
    case 0x09:        /* LCH_BASS_BOOST_N2 */
497 3efda49d balrog
    case 0x0a:        /* LCH_BASS_BOOST_N3 */
498 3efda49d balrog
    case 0x0b:        /* LCH_BASS_BOOST_N4 */
499 3efda49d balrog
    case 0x0c:        /* LCH_BASS_BOOST_N5 */
500 3efda49d balrog
    case 0x0d:        /* LCH_BASS_BOOST_D1 */
501 3efda49d balrog
    case 0x0e:        /* LCH_BASS_BOOST_D2 */
502 3efda49d balrog
    case 0x0f:        /* LCH_BASS_BOOST_D4 */
503 3efda49d balrog
    case 0x10:        /* LCH_BASS_BOOST_D5 */
504 3efda49d balrog
    case 0x11:        /* RCH_BASS_BOOST_N0 */
505 3efda49d balrog
    case 0x12:        /* RCH_BASS_BOOST_N1 */
506 3efda49d balrog
    case 0x13:        /* RCH_BASS_BOOST_N2 */
507 3efda49d balrog
    case 0x14:        /* RCH_BASS_BOOST_N3 */
508 3efda49d balrog
    case 0x15:        /* RCH_BASS_BOOST_N4 */
509 3efda49d balrog
    case 0x16:        /* RCH_BASS_BOOST_N5 */
510 3efda49d balrog
    case 0x17:        /* RCH_BASS_BOOST_D1 */
511 3efda49d balrog
    case 0x18:        /* RCH_BASS_BOOST_D2 */
512 3efda49d balrog
    case 0x19:        /* RCH_BASS_BOOST_D4 */
513 3efda49d balrog
    case 0x1a:        /* RCH_BASS_BOOST_D5 */
514 3efda49d balrog
        s->filter_data[reg - 0x07] = value;
515 3efda49d balrog
        return;
516 3efda49d balrog
517 3efda49d balrog
    case 0x1b:        /* PLL Programmability 1 */
518 3efda49d balrog
        s->pll[0] = value & 0xfffc;
519 3efda49d balrog
#ifdef TSC_VERBOSE
520 3efda49d balrog
        if (value & ~0xfffc)
521 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
522 3efda49d balrog
                            "wrong value written into PLL 1\n");
523 3efda49d balrog
#endif
524 3efda49d balrog
        return;
525 3efda49d balrog
526 3efda49d balrog
    case 0x1c:        /* PLL Programmability 2 */
527 3efda49d balrog
        s->pll[1] = value & 0xfffc;
528 3efda49d balrog
#ifdef TSC_VERBOSE
529 3efda49d balrog
        if (value & ~0xfffc)
530 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
531 3efda49d balrog
                            "wrong value written into PLL 2\n");
532 3efda49d balrog
#endif
533 3efda49d balrog
        return;
534 3efda49d balrog
535 3efda49d balrog
    case 0x1d:        /* Audio Control 4 */
536 3efda49d balrog
        s->softstep = !(value & 0x4000);
537 3efda49d balrog
#ifdef TSC_VERBOSE
538 3efda49d balrog
        if (value & ~0x4000)
539 3efda49d balrog
            fprintf(stderr, "tsc2102_audio_register_write: "
540 3efda49d balrog
                            "wrong value written into Audio 4\n");
541 3efda49d balrog
#endif
542 3efda49d balrog
        return;
543 3efda49d balrog
544 3efda49d balrog
    default:
545 3efda49d balrog
#ifdef TSC_VERBOSE
546 3efda49d balrog
        fprintf(stderr, "tsc2102_audio_register_write: "
547 3efda49d balrog
                        "no such register: 0x%02x\n", reg);
548 3efda49d balrog
#endif
549 3efda49d balrog
    }
550 3efda49d balrog
}
551 3efda49d balrog
552 3efda49d balrog
/* This handles most of the chip logic.  */
553 3efda49d balrog
static void tsc210x_pin_update(struct tsc210x_state_s *s)
554 3efda49d balrog
{
555 3efda49d balrog
    int64_t expires;
556 3efda49d balrog
    int pin_state;
557 3efda49d balrog
558 3efda49d balrog
    switch (s->pin_func) {
559 3efda49d balrog
    case 0:
560 3efda49d balrog
        pin_state = s->pressure;
561 3efda49d balrog
        break;
562 3efda49d balrog
    case 1:
563 3efda49d balrog
        pin_state = !!s->dav;
564 3efda49d balrog
        break;
565 3efda49d balrog
    case 2:
566 3efda49d balrog
    default:
567 3efda49d balrog
        pin_state = s->pressure && !s->dav;
568 3efda49d balrog
    }
569 3efda49d balrog
570 3efda49d balrog
    if (!s->enabled)
571 3efda49d balrog
        pin_state = 0;
572 3efda49d balrog
573 3efda49d balrog
    if (pin_state != s->irq) {
574 3efda49d balrog
        s->irq = pin_state;
575 7fc42b4b balrog
        qemu_set_irq(s->pint, !s->irq);
576 3efda49d balrog
    }
577 3efda49d balrog
578 3efda49d balrog
    switch (s->nextfunction) {
579 3efda49d balrog
    case TSC_MODE_XY_SCAN:
580 3efda49d balrog
    case TSC_MODE_XYZ_SCAN:
581 3efda49d balrog
        if (!s->pressure)
582 3efda49d balrog
            return;
583 3efda49d balrog
        break;
584 3efda49d balrog
585 3efda49d balrog
    case TSC_MODE_X:
586 3efda49d balrog
    case TSC_MODE_Y:
587 3efda49d balrog
    case TSC_MODE_Z:
588 3efda49d balrog
        if (!s->pressure)
589 3efda49d balrog
            return;
590 3efda49d balrog
        /* Fall through */
591 3efda49d balrog
    case TSC_MODE_BAT1:
592 3efda49d balrog
    case TSC_MODE_BAT2:
593 3efda49d balrog
    case TSC_MODE_AUX:
594 3efda49d balrog
    case TSC_MODE_TEMP1:
595 3efda49d balrog
    case TSC_MODE_TEMP2:
596 3efda49d balrog
        if (s->dav)
597 3efda49d balrog
            s->enabled = 0;
598 3efda49d balrog
        break;
599 3efda49d balrog
600 3efda49d balrog
    case TSC_MODE_AUX_SCAN:
601 3efda49d balrog
    case TSC_MODE_PORT_SCAN:
602 3efda49d balrog
        break;
603 3efda49d balrog
604 3efda49d balrog
    case TSC_MODE_NO_SCAN:
605 3efda49d balrog
    case TSC_MODE_XX_DRV:
606 3efda49d balrog
    case TSC_MODE_YY_DRV:
607 3efda49d balrog
    case TSC_MODE_YX_DRV:
608 3efda49d balrog
    default:
609 3efda49d balrog
        return;
610 3efda49d balrog
    }
611 3efda49d balrog
612 3efda49d balrog
    if (!s->enabled || s->busy)
613 3efda49d balrog
        return;
614 3efda49d balrog
615 3efda49d balrog
    s->busy = 1;
616 3efda49d balrog
    s->precision = s->nextprecision;
617 3efda49d balrog
    s->function = s->nextfunction;
618 3efda49d balrog
    expires = qemu_get_clock(vm_clock) + (ticks_per_sec >> 10);
619 3efda49d balrog
    qemu_mod_timer(s->timer, expires);
620 3efda49d balrog
}
621 3efda49d balrog
622 3efda49d balrog
static uint16_t tsc210x_read(struct tsc210x_state_s *s)
623 3efda49d balrog
{
624 3efda49d balrog
    uint16_t ret = 0x0000;
625 3efda49d balrog
626 3efda49d balrog
    if (!s->command)
627 3efda49d balrog
        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
628 3efda49d balrog
629 3efda49d balrog
    switch (s->page) {
630 3efda49d balrog
    case TSC_DATA_REGISTERS_PAGE:
631 3efda49d balrog
        ret = tsc2102_data_register_read(s, s->offset);
632 3efda49d balrog
        break;
633 3efda49d balrog
    case TSC_CONTROL_REGISTERS_PAGE:
634 3efda49d balrog
        ret = tsc2102_control_register_read(s, s->offset);
635 3efda49d balrog
        break;
636 3efda49d balrog
    case TSC_AUDIO_REGISTERS_PAGE:
637 3efda49d balrog
        ret = tsc2102_audio_register_read(s, s->offset);
638 3efda49d balrog
        break;
639 3efda49d balrog
    default:
640 3efda49d balrog
        cpu_abort(cpu_single_env, "tsc210x_read: wrong memory page\n");
641 3efda49d balrog
    }
642 3efda49d balrog
643 3efda49d balrog
    tsc210x_pin_update(s);
644 3efda49d balrog
645 3efda49d balrog
    /* Allow sequential reads.  */
646 3efda49d balrog
    s->offset ++;
647 3efda49d balrog
    s->state = 0;
648 3efda49d balrog
    return ret;
649 3efda49d balrog
}
650 3efda49d balrog
651 3efda49d balrog
static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value)
652 3efda49d balrog
{
653 3efda49d balrog
    /*
654 3efda49d balrog
     * This is a two-state state machine for reading
655 3efda49d balrog
     * command and data every second time.
656 3efda49d balrog
     */
657 3efda49d balrog
    if (!s->state) {
658 3efda49d balrog
        s->command = value >> 15;
659 3efda49d balrog
        s->page = (value >> 11) & 0x0f;
660 3efda49d balrog
        s->offset = (value >> 5) & 0x3f;
661 3efda49d balrog
        s->state = 1;
662 3efda49d balrog
    } else {
663 3efda49d balrog
        if (s->command)
664 3efda49d balrog
            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
665 3efda49d balrog
        else
666 3efda49d balrog
            switch (s->page) {
667 3efda49d balrog
            case TSC_DATA_REGISTERS_PAGE:
668 3efda49d balrog
                tsc2102_data_register_write(s, s->offset, value);
669 3efda49d balrog
                break;
670 3efda49d balrog
            case TSC_CONTROL_REGISTERS_PAGE:
671 3efda49d balrog
                tsc2102_control_register_write(s, s->offset, value);
672 3efda49d balrog
                break;
673 3efda49d balrog
            case TSC_AUDIO_REGISTERS_PAGE:
674 3efda49d balrog
                tsc2102_audio_register_write(s, s->offset, value);
675 3efda49d balrog
                break;
676 3efda49d balrog
            default:
677 3efda49d balrog
                cpu_abort(cpu_single_env,
678 3efda49d balrog
                                "tsc210x_write: wrong memory page\n");
679 3efda49d balrog
            }
680 3efda49d balrog
681 3efda49d balrog
        tsc210x_pin_update(s);
682 3efda49d balrog
        s->state = 0;
683 3efda49d balrog
    }
684 3efda49d balrog
}
685 3efda49d balrog
686 3efda49d balrog
static void tsc210x_timer_tick(void *opaque)
687 3efda49d balrog
{
688 3efda49d balrog
    struct tsc210x_state_s *s = opaque;
689 3efda49d balrog
690 3efda49d balrog
    /* Timer ticked -- a set of conversions has been finished.  */
691 3efda49d balrog
692 3efda49d balrog
    if (!s->busy)
693 3efda49d balrog
        return;
694 3efda49d balrog
695 3efda49d balrog
    s->busy = 0;
696 3efda49d balrog
    s->dav |= mode_regs[s->function];
697 3efda49d balrog
    tsc210x_pin_update(s);
698 3efda49d balrog
}
699 3efda49d balrog
700 3efda49d balrog
static void tsc210x_touchscreen_event(void *opaque,
701 3efda49d balrog
                int x, int y, int z, int buttons_state)
702 3efda49d balrog
{
703 3efda49d balrog
    struct tsc210x_state_s *s = opaque;
704 3efda49d balrog
    int p = s->pressure;
705 3efda49d balrog
706 3efda49d balrog
    if (buttons_state) {
707 3efda49d balrog
        s->x = x;
708 3efda49d balrog
        s->y = y;
709 3efda49d balrog
    }
710 3efda49d balrog
    s->pressure = !!buttons_state;
711 3efda49d balrog
712 3efda49d balrog
    /*
713 3efda49d balrog
     * Note: We would get better responsiveness in the guest by
714 3efda49d balrog
     * signaling TS events immediately, but for now we simulate
715 3efda49d balrog
     * the first conversion delay for sake of correctness.
716 3efda49d balrog
     */
717 3efda49d balrog
    if (p != s->pressure)
718 3efda49d balrog
        tsc210x_pin_update(s);
719 3efda49d balrog
}
720 3efda49d balrog
721 3efda49d balrog
static void tsc210x_save(QEMUFile *f, void *opaque)
722 3efda49d balrog
{
723 3efda49d balrog
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
724 3efda49d balrog
    int64_t now = qemu_get_clock(vm_clock);
725 3efda49d balrog
    int i;
726 3efda49d balrog
727 3efda49d balrog
    qemu_put_be16(f, s->x);
728 3efda49d balrog
    qemu_put_be16(f, s->y);
729 3efda49d balrog
    qemu_put_byte(f, s->pressure);
730 3efda49d balrog
731 3efda49d balrog
    qemu_put_byte(f, s->state);
732 3efda49d balrog
    qemu_put_byte(f, s->page);
733 3efda49d balrog
    qemu_put_byte(f, s->offset);
734 3efda49d balrog
    qemu_put_byte(f, s->command);
735 3efda49d balrog
736 3efda49d balrog
    qemu_put_byte(f, s->irq);
737 3efda49d balrog
    qemu_put_be16s(f, &s->dav);
738 3efda49d balrog
739 3efda49d balrog
    qemu_put_timer(f, s->timer);
740 3efda49d balrog
    qemu_put_byte(f, s->enabled);
741 3efda49d balrog
    qemu_put_byte(f, s->host_mode);
742 3efda49d balrog
    qemu_put_byte(f, s->function);
743 3efda49d balrog
    qemu_put_byte(f, s->nextfunction);
744 3efda49d balrog
    qemu_put_byte(f, s->precision);
745 3efda49d balrog
    qemu_put_byte(f, s->nextprecision);
746 3efda49d balrog
    qemu_put_byte(f, s->filter);
747 3efda49d balrog
    qemu_put_byte(f, s->pin_func);
748 3efda49d balrog
    qemu_put_byte(f, s->ref);
749 3efda49d balrog
    qemu_put_byte(f, s->timing);
750 3efda49d balrog
    qemu_put_be32(f, s->noise);
751 3efda49d balrog
752 3efda49d balrog
    qemu_put_be16s(f, &s->audio_ctrl1);
753 3efda49d balrog
    qemu_put_be16s(f, &s->audio_ctrl2);
754 3efda49d balrog
    qemu_put_be16s(f, &s->audio_ctrl3);
755 3efda49d balrog
    qemu_put_be16s(f, &s->pll[0]);
756 3efda49d balrog
    qemu_put_be16s(f, &s->pll[1]);
757 3efda49d balrog
    qemu_put_be16s(f, &s->volume);
758 3efda49d balrog
    qemu_put_be64(f, (uint64_t) (s->volume_change - now));
759 3efda49d balrog
    qemu_put_be64(f, (uint64_t) (s->powerdown - now));
760 3efda49d balrog
    qemu_put_byte(f, s->softstep);
761 3efda49d balrog
    qemu_put_be16s(f, &s->dac_power);
762 3efda49d balrog
763 3efda49d balrog
    for (i = 0; i < 0x14; i ++)
764 3efda49d balrog
        qemu_put_be16s(f, &s->filter_data[i]);
765 3efda49d balrog
}
766 3efda49d balrog
767 3efda49d balrog
static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
768 3efda49d balrog
{
769 3efda49d balrog
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
770 3efda49d balrog
    int64_t now = qemu_get_clock(vm_clock);
771 3efda49d balrog
    int i;
772 3efda49d balrog
773 3efda49d balrog
    s->x = qemu_get_be16(f);
774 3efda49d balrog
    s->y = qemu_get_be16(f);
775 3efda49d balrog
    s->pressure = qemu_get_byte(f);
776 3efda49d balrog
777 3efda49d balrog
    s->state = qemu_get_byte(f);
778 3efda49d balrog
    s->page = qemu_get_byte(f);
779 3efda49d balrog
    s->offset = qemu_get_byte(f);
780 3efda49d balrog
    s->command = qemu_get_byte(f);
781 3efda49d balrog
782 3efda49d balrog
    s->irq = qemu_get_byte(f);
783 3efda49d balrog
    qemu_get_be16s(f, &s->dav);
784 3efda49d balrog
785 3efda49d balrog
    qemu_get_timer(f, s->timer);
786 3efda49d balrog
    s->enabled = qemu_get_byte(f);
787 3efda49d balrog
    s->host_mode = qemu_get_byte(f);
788 3efda49d balrog
    s->function = qemu_get_byte(f);
789 3efda49d balrog
    s->nextfunction = qemu_get_byte(f);
790 3efda49d balrog
    s->precision = qemu_get_byte(f);
791 3efda49d balrog
    s->nextprecision = qemu_get_byte(f);
792 3efda49d balrog
    s->filter = qemu_get_byte(f);
793 3efda49d balrog
    s->pin_func = qemu_get_byte(f);
794 3efda49d balrog
    s->ref = qemu_get_byte(f);
795 3efda49d balrog
    s->timing = qemu_get_byte(f);
796 3efda49d balrog
    s->noise = qemu_get_be32(f);
797 3efda49d balrog
798 3efda49d balrog
    qemu_get_be16s(f, &s->audio_ctrl1);
799 3efda49d balrog
    qemu_get_be16s(f, &s->audio_ctrl2);
800 3efda49d balrog
    qemu_get_be16s(f, &s->audio_ctrl3);
801 3efda49d balrog
    qemu_get_be16s(f, &s->pll[0]);
802 3efda49d balrog
    qemu_get_be16s(f, &s->pll[1]);
803 3efda49d balrog
    qemu_get_be16s(f, &s->volume);
804 3efda49d balrog
    s->volume_change = (int64_t) qemu_get_be64(f) + now;
805 3efda49d balrog
    s->powerdown = (int64_t) qemu_get_be64(f) + now;
806 3efda49d balrog
    s->softstep = qemu_get_byte(f);
807 3efda49d balrog
    qemu_get_be16s(f, &s->dac_power);
808 3efda49d balrog
809 3efda49d balrog
    for (i = 0; i < 0x14; i ++)
810 3efda49d balrog
        qemu_get_be16s(f, &s->filter_data[i]);
811 3efda49d balrog
812 3efda49d balrog
    s->busy = qemu_timer_pending(s->timer);
813 7fc42b4b balrog
    qemu_set_irq(s->pint, !s->irq);
814 3efda49d balrog
815 3efda49d balrog
    return 0;
816 3efda49d balrog
}
817 3efda49d balrog
818 3efda49d balrog
static int tsc2102_iid = 0;
819 3efda49d balrog
820 3efda49d balrog
struct uwire_slave_s *tsc2102_init(qemu_irq pint)
821 3efda49d balrog
{
822 3efda49d balrog
    struct tsc210x_state_s *s;
823 3efda49d balrog
824 3efda49d balrog
    s = (struct tsc210x_state_s *)
825 3efda49d balrog
            qemu_mallocz(sizeof(struct tsc210x_state_s));
826 3efda49d balrog
    memset(s, 0, sizeof(struct tsc210x_state_s));
827 3efda49d balrog
    s->x = 160;
828 3efda49d balrog
    s->y = 160;
829 3efda49d balrog
    s->pressure = 0;
830 3efda49d balrog
    s->precision = s->nextprecision = 0;
831 3efda49d balrog
    s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);
832 3efda49d balrog
    s->pint = pint;
833 3efda49d balrog
834 3efda49d balrog
    s->chip.opaque = s;
835 3efda49d balrog
    s->chip.send = (void *) tsc210x_write;
836 3efda49d balrog
    s->chip.receive = (void *) tsc210x_read;
837 3efda49d balrog
838 3efda49d balrog
    tsc210x_reset(s);
839 3efda49d balrog
840 3efda49d balrog
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
841 3efda49d balrog
                    "QEMU TSC2102-driven Touchscreen");
842 3efda49d balrog
843 3efda49d balrog
    qemu_register_reset((void *) tsc210x_reset, s);
844 3efda49d balrog
    register_savevm("tsc2102", tsc2102_iid ++, 0,
845 3efda49d balrog
                    tsc210x_save, tsc210x_load, s);
846 3efda49d balrog
847 3efda49d balrog
    return &s->chip;
848 3efda49d balrog
}