Statistics
| Branch: | Revision:

root / hw / tsc210x.c @ 997641a8

History | View | Annotate | Download (34.7 kB)

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

1234 a5d7eb65 balrog
    ltr[0] = (int64_t) info->a[1] * info->y;
1235 a5d7eb65 balrog
    ltr[1] = (int64_t) info->a[4] * info->x;
1236 a5d7eb65 balrog
    ltr[2] = (int64_t) info->a[1] * info->a[3] -
1237 a5d7eb65 balrog
            (int64_t) info->a[4] * info->a[0];
1238 a5d7eb65 balrog
    ltr[3] = (int64_t) info->a[2] * info->a[4] -
1239 a5d7eb65 balrog
            (int64_t) info->a[5] * info->a[1];
1240 a5d7eb65 balrog
    ltr[4] = (int64_t) info->a[0] * info->y;
1241 a5d7eb65 balrog
    ltr[5] = (int64_t) info->a[3] * info->x;
1242 a5d7eb65 balrog
    ltr[6] = (int64_t) info->a[4] * info->a[0] -
1243 a5d7eb65 balrog
            (int64_t) info->a[1] * info->a[3];
1244 a5d7eb65 balrog
    ltr[7] = (int64_t) info->a[2] * info->a[3] -
1245 a5d7eb65 balrog
            (int64_t) info->a[5] * info->a[0];
1246 a5d7eb65 balrog

1247 a5d7eb65 balrog
    /* Avoid integer overflow */
1248 a5d7eb65 balrog
    s->tr[0] = ltr[0] >> 11;
1249 a5d7eb65 balrog
    s->tr[1] = ltr[1] >> 11;
1250 a5d7eb65 balrog
    s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
1251 a5d7eb65 balrog
    s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
1252 a5d7eb65 balrog
    s->tr[4] = ltr[4] >> 11;
1253 a5d7eb65 balrog
    s->tr[5] = ltr[5] >> 11;
1254 a5d7eb65 balrog
    s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
1255 a5d7eb65 balrog
    s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
1256 a5d7eb65 balrog
#else
1257 a5d7eb65 balrog
1258 a5d7eb65 balrog
    /* This version assumes touchscreen X & Y axis are parallel or
1259 a5d7eb65 balrog
     * perpendicular to LCD's  X & Y axis in some way.  */
1260 a5d7eb65 balrog
    if (abs(info->a[0]) > abs(info->a[1])) {
1261 a5d7eb65 balrog
        s->tr[0] = 0;
1262 a5d7eb65 balrog
        s->tr[1] = -info->a[6] * info->x;
1263 a5d7eb65 balrog
        s->tr[2] = info->a[0];
1264 a5d7eb65 balrog
        s->tr[3] = -info->a[2] / info->a[0];
1265 a5d7eb65 balrog
        s->tr[4] = info->a[6] * info->y;
1266 a5d7eb65 balrog
        s->tr[5] = 0;
1267 a5d7eb65 balrog
        s->tr[6] = info->a[4];
1268 a5d7eb65 balrog
        s->tr[7] = -info->a[5] / info->a[4];
1269 a5d7eb65 balrog
    } else {
1270 a5d7eb65 balrog
        s->tr[0] = info->a[6] * info->y;
1271 a5d7eb65 balrog
        s->tr[1] = 0;
1272 a5d7eb65 balrog
        s->tr[2] = info->a[1];
1273 a5d7eb65 balrog
        s->tr[3] = -info->a[2] / info->a[1];
1274 a5d7eb65 balrog
        s->tr[4] = 0;
1275 a5d7eb65 balrog
        s->tr[5] = -info->a[6] * info->x;
1276 a5d7eb65 balrog
        s->tr[6] = info->a[3];
1277 a5d7eb65 balrog
        s->tr[7] = -info->a[5] / info->a[3];
1278 a5d7eb65 balrog
    }
1279 a5d7eb65 balrog
1280 a5d7eb65 balrog
    s->tr[0] >>= 11;
1281 a5d7eb65 balrog
    s->tr[1] >>= 11;
1282 a5d7eb65 balrog
    s->tr[3] <<= 4;
1283 a5d7eb65 balrog
    s->tr[4] >>= 11;
1284 a5d7eb65 balrog
    s->tr[5] >>= 11;
1285 a5d7eb65 balrog
    s->tr[7] <<= 4;
1286 a5d7eb65 balrog
#endif
1287 a5d7eb65 balrog
}
1288 a5d7eb65 balrog
1289 a5d7eb65 balrog
void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down)
1290 a5d7eb65 balrog
{
1291 a5d7eb65 balrog
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
1292 a5d7eb65 balrog
1293 a5d7eb65 balrog
    if (down)
1294 a5d7eb65 balrog
        s->kb.down |= 1 << key;
1295 a5d7eb65 balrog
    else
1296 a5d7eb65 balrog
        s->kb.down &= ~(1 << key);
1297 a5d7eb65 balrog
1298 a5d7eb65 balrog
    if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
1299 a5d7eb65 balrog
        s->kb.intr = 1;
1300 a5d7eb65 balrog
        qemu_irq_lower(s->kbint);
1301 a5d7eb65 balrog
    } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
1302 a5d7eb65 balrog
                    !(s->kb.mode & 1)) {
1303 a5d7eb65 balrog
        s->kb.intr = 0;
1304 a5d7eb65 balrog
        qemu_irq_raise(s->kbint);
1305 a5d7eb65 balrog
    }
1306 a5d7eb65 balrog
}