Revision bc24a225 hw/tsc210x.c
b/hw/tsc210x.c | ||
---|---|---|
24 | 24 |
#include "audio/audio.h" |
25 | 25 |
#include "qemu-timer.h" |
26 | 26 |
#include "console.h" |
27 |
#include "omap.h" /* For struct i2s_codec_s and struct uwire_slave_s */
|
|
27 |
#include "omap.h" /* For I2SCodec and uWireSlave */
|
|
28 | 28 |
#include "devices.h" |
29 | 29 |
|
30 | 30 |
#define TSC_DATA_REGISTERS_PAGE 0x0 |
... | ... | |
35 | 35 |
|
36 | 36 |
#define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - resolution[p])) |
37 | 37 |
|
38 |
struct tsc210x_state_s {
|
|
38 |
typedef struct {
|
|
39 | 39 |
qemu_irq pint; |
40 | 40 |
qemu_irq kbint; |
41 | 41 |
qemu_irq davint; |
42 | 42 |
QEMUTimer *timer; |
43 | 43 |
QEMUSoundCard card; |
44 |
struct uwire_slave_s chip;
|
|
45 |
struct i2s_codec_s codec;
|
|
44 |
uWireSlave chip;
|
|
45 |
I2SCodec codec;
|
|
46 | 46 |
uint8_t in_fifo[16384]; |
47 | 47 |
uint8_t out_fifo[16384]; |
48 | 48 |
uint16_t model; |
... | ... | |
94 | 94 |
int mode; |
95 | 95 |
int intr; |
96 | 96 |
} kb; |
97 |
}; |
|
97 |
} TSC210xState;
|
|
98 | 98 |
|
99 | 99 |
static const int resolution[4] = { 12, 8, 10, 12 }; |
100 | 100 |
|
... | ... | |
153 | 153 |
#define TSC_POWEROFF_DELAY 50 |
154 | 154 |
#define TSC_SOFTSTEP_DELAY 50 |
155 | 155 |
|
156 |
static void tsc210x_reset(struct tsc210x_state_s *s)
|
|
156 |
static void tsc210x_reset(TSC210xState *s)
|
|
157 | 157 |
{ |
158 | 158 |
s->state = 0; |
159 | 159 |
s->pin_func = 2; |
... | ... | |
211 | 211 |
qemu_irq_raise(s->kbint); |
212 | 212 |
} |
213 | 213 |
|
214 |
struct tsc210x_rate_info_s {
|
|
214 |
typedef struct {
|
|
215 | 215 |
int rate; |
216 | 216 |
int dsor; |
217 | 217 |
int fsref; |
218 |
}; |
|
218 |
} TSC210xRateInfo;
|
|
219 | 219 |
|
220 | 220 |
/* { rate, dsor, fsref } */ |
221 |
static const struct tsc210x_rate_info_s tsc2101_rates[] = {
|
|
221 |
static const TSC210xRateInfo tsc2101_rates[] = {
|
|
222 | 222 |
/* Fsref / 6.0 */ |
223 | 223 |
{ 7350, 7, 1 }, |
224 | 224 |
{ 8000, 7, 0 }, |
... | ... | |
248 | 248 |
}; |
249 | 249 |
|
250 | 250 |
/* { rate, dsor, fsref } */ |
251 |
static const struct tsc210x_rate_info_s tsc2102_rates[] = {
|
|
251 |
static const TSC210xRateInfo tsc2102_rates[] = {
|
|
252 | 252 |
/* Fsref / 6.0 */ |
253 | 253 |
{ 7350, 63, 1 }, |
254 | 254 |
{ 8000, 63, 0 }, |
... | ... | |
277 | 277 |
{ 0, 0, 0 }, |
278 | 278 |
}; |
279 | 279 |
|
280 |
static inline void tsc210x_out_flush(struct tsc210x_state_s *s, int len)
|
|
280 |
static inline void tsc210x_out_flush(TSC210xState *s, int len)
|
|
281 | 281 |
{ |
282 | 282 |
uint8_t *data = s->codec.out.fifo + s->codec.out.start; |
283 | 283 |
uint8_t *end = data + len; |
... | ... | |
291 | 291 |
s->codec.out.start = 0; |
292 | 292 |
} |
293 | 293 |
|
294 |
static void tsc210x_audio_out_cb(struct tsc210x_state_s *s, int free_b)
|
|
294 |
static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
|
|
295 | 295 |
{ |
296 | 296 |
if (s->codec.out.len >= free_b) { |
297 | 297 |
tsc210x_out_flush(s, free_b); |
... | ... | |
302 | 302 |
qemu_irq_raise(s->codec.tx_start); |
303 | 303 |
} |
304 | 304 |
|
305 |
static void tsc2102_audio_rate_update(struct tsc210x_state_s *s)
|
|
305 |
static void tsc2102_audio_rate_update(TSC210xState *s)
|
|
306 | 306 |
{ |
307 |
const struct tsc210x_rate_info_s *rate;
|
|
307 |
const TSC210xRateInfo *rate;
|
|
308 | 308 |
|
309 | 309 |
s->codec.tx_rate = 0; |
310 | 310 |
s->codec.rx_rate = 0; |
... | ... | |
323 | 323 |
s->codec.tx_rate = rate->rate; |
324 | 324 |
} |
325 | 325 |
|
326 |
static void tsc2102_audio_output_update(struct tsc210x_state_s *s)
|
|
326 |
static void tsc2102_audio_output_update(TSC210xState *s)
|
|
327 | 327 |
{ |
328 | 328 |
int enable; |
329 | 329 |
struct audsettings fmt; |
... | ... | |
357 | 357 |
} |
358 | 358 |
} |
359 | 359 |
|
360 |
static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
|
|
360 |
static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
|
|
361 | 361 |
{ |
362 | 362 |
switch (reg) { |
363 | 363 |
case 0x00: /* X */ |
... | ... | |
433 | 433 |
} |
434 | 434 |
|
435 | 435 |
static uint16_t tsc2102_control_register_read( |
436 |
struct tsc210x_state_s *s, int reg)
|
|
436 |
TSC210xState *s, int reg)
|
|
437 | 437 |
{ |
438 | 438 |
switch (reg) { |
439 | 439 |
case 0x00: /* TSC ADC */ |
... | ... | |
483 | 483 |
} |
484 | 484 |
} |
485 | 485 |
|
486 |
static uint16_t tsc2102_audio_register_read(struct tsc210x_state_s *s, int reg)
|
|
486 |
static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
|
|
487 | 487 |
{ |
488 | 488 |
int l_ch, r_ch; |
489 | 489 |
uint16_t val; |
... | ... | |
565 | 565 |
} |
566 | 566 |
|
567 | 567 |
static void tsc2102_data_register_write( |
568 |
struct tsc210x_state_s *s, int reg, uint16_t value)
|
|
568 |
TSC210xState *s, int reg, uint16_t value)
|
|
569 | 569 |
{ |
570 | 570 |
switch (reg) { |
571 | 571 |
case 0x00: /* X */ |
... | ... | |
589 | 589 |
} |
590 | 590 |
|
591 | 591 |
static void tsc2102_control_register_write( |
592 |
struct tsc210x_state_s *s, int reg, uint16_t value)
|
|
592 |
TSC210xState *s, int reg, uint16_t value)
|
|
593 | 593 |
{ |
594 | 594 |
switch (reg) { |
595 | 595 |
case 0x00: /* TSC ADC */ |
... | ... | |
673 | 673 |
} |
674 | 674 |
|
675 | 675 |
static void tsc2102_audio_register_write( |
676 |
struct tsc210x_state_s *s, int reg, uint16_t value)
|
|
676 |
TSC210xState *s, int reg, uint16_t value)
|
|
677 | 677 |
{ |
678 | 678 |
switch (reg) { |
679 | 679 |
case 0x00: /* Audio Control 1 */ |
... | ... | |
804 | 804 |
} |
805 | 805 |
|
806 | 806 |
/* This handles most of the chip logic. */ |
807 |
static void tsc210x_pin_update(struct tsc210x_state_s *s)
|
|
807 |
static void tsc210x_pin_update(TSC210xState *s)
|
|
808 | 808 |
{ |
809 | 809 |
int64_t expires; |
810 | 810 |
int pin_state; |
... | ... | |
873 | 873 |
qemu_mod_timer(s->timer, expires); |
874 | 874 |
} |
875 | 875 |
|
876 |
static uint16_t tsc210x_read(struct tsc210x_state_s *s)
|
|
876 |
static uint16_t tsc210x_read(TSC210xState *s)
|
|
877 | 877 |
{ |
878 | 878 |
uint16_t ret = 0x0000; |
879 | 879 |
|
... | ... | |
904 | 904 |
return ret; |
905 | 905 |
} |
906 | 906 |
|
907 |
static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value)
|
|
907 |
static void tsc210x_write(TSC210xState *s, uint16_t value)
|
|
908 | 908 |
{ |
909 | 909 |
/* |
910 | 910 |
* This is a two-state state machine for reading |
... | ... | |
940 | 940 |
|
941 | 941 |
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len) |
942 | 942 |
{ |
943 |
struct tsc210x_state_s *s = opaque;
|
|
943 |
TSC210xState *s = opaque;
|
|
944 | 944 |
uint32_t ret = 0; |
945 | 945 |
|
946 | 946 |
if (len != 16) |
... | ... | |
959 | 959 |
|
960 | 960 |
static void tsc210x_timer_tick(void *opaque) |
961 | 961 |
{ |
962 |
struct tsc210x_state_s *s = opaque;
|
|
962 |
TSC210xState *s = opaque;
|
|
963 | 963 |
|
964 | 964 |
/* Timer ticked -- a set of conversions has been finished. */ |
965 | 965 |
|
... | ... | |
975 | 975 |
static void tsc210x_touchscreen_event(void *opaque, |
976 | 976 |
int x, int y, int z, int buttons_state) |
977 | 977 |
{ |
978 |
struct tsc210x_state_s *s = opaque;
|
|
978 |
TSC210xState *s = opaque;
|
|
979 | 979 |
int p = s->pressure; |
980 | 980 |
|
981 | 981 |
if (buttons_state) { |
... | ... | |
993 | 993 |
tsc210x_pin_update(s); |
994 | 994 |
} |
995 | 995 |
|
996 |
static void tsc210x_i2s_swallow(struct tsc210x_state_s *s)
|
|
996 |
static void tsc210x_i2s_swallow(TSC210xState *s)
|
|
997 | 997 |
{ |
998 | 998 |
if (s->dac_voice[0]) |
999 | 999 |
tsc210x_out_flush(s, s->codec.out.len); |
... | ... | |
1001 | 1001 |
s->codec.out.len = 0; |
1002 | 1002 |
} |
1003 | 1003 |
|
1004 |
static void tsc210x_i2s_set_rate(struct tsc210x_state_s *s, int in, int out)
|
|
1004 |
static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
|
|
1005 | 1005 |
{ |
1006 | 1006 |
s->i2s_tx_rate = out; |
1007 | 1007 |
s->i2s_rx_rate = in; |
... | ... | |
1009 | 1009 |
|
1010 | 1010 |
static void tsc210x_save(QEMUFile *f, void *opaque) |
1011 | 1011 |
{ |
1012 |
struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
|
|
1012 |
TSC210xState *s = (TSC210xState *) opaque;
|
|
1013 | 1013 |
int64_t now = qemu_get_clock(vm_clock); |
1014 | 1014 |
int i; |
1015 | 1015 |
|
... | ... | |
1055 | 1055 |
|
1056 | 1056 |
static int tsc210x_load(QEMUFile *f, void *opaque, int version_id) |
1057 | 1057 |
{ |
1058 |
struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
|
|
1058 |
TSC210xState *s = (TSC210xState *) opaque;
|
|
1059 | 1059 |
int64_t now = qemu_get_clock(vm_clock); |
1060 | 1060 |
int i; |
1061 | 1061 |
|
... | ... | |
1105 | 1105 |
return 0; |
1106 | 1106 |
} |
1107 | 1107 |
|
1108 |
struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio)
|
|
1108 |
uWireSlave *tsc2102_init(qemu_irq pint, AudioState *audio)
|
|
1109 | 1109 |
{ |
1110 |
struct tsc210x_state_s *s;
|
|
1110 |
TSC210xState *s;
|
|
1111 | 1111 |
|
1112 |
s = (struct tsc210x_state_s *)
|
|
1113 |
qemu_mallocz(sizeof(struct tsc210x_state_s));
|
|
1114 |
memset(s, 0, sizeof(struct tsc210x_state_s));
|
|
1112 |
s = (TSC210xState *)
|
|
1113 |
qemu_mallocz(sizeof(TSC210xState));
|
|
1114 |
memset(s, 0, sizeof(TSC210xState));
|
|
1115 | 1115 |
s->x = 160; |
1116 | 1116 |
s->y = 160; |
1117 | 1117 |
s->pressure = 0; |
... | ... | |
1156 | 1156 |
return &s->chip; |
1157 | 1157 |
} |
1158 | 1158 |
|
1159 |
struct uwire_slave_s *tsc2301_init(qemu_irq penirq, qemu_irq kbirq,
|
|
1159 |
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq,
|
|
1160 | 1160 |
qemu_irq dav, AudioState *audio) |
1161 | 1161 |
{ |
1162 |
struct tsc210x_state_s *s;
|
|
1162 |
TSC210xState *s;
|
|
1163 | 1163 |
|
1164 |
s = (struct tsc210x_state_s *)
|
|
1165 |
qemu_mallocz(sizeof(struct tsc210x_state_s));
|
|
1166 |
memset(s, 0, sizeof(struct tsc210x_state_s));
|
|
1164 |
s = (TSC210xState *)
|
|
1165 |
qemu_mallocz(sizeof(TSC210xState));
|
|
1166 |
memset(s, 0, sizeof(TSC210xState));
|
|
1167 | 1167 |
s->x = 400; |
1168 | 1168 |
s->y = 240; |
1169 | 1169 |
s->pressure = 0; |
... | ... | |
1209 | 1209 |
return &s->chip; |
1210 | 1210 |
} |
1211 | 1211 |
|
1212 |
struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip)
|
|
1212 |
I2SCodec *tsc210x_codec(uWireSlave *chip)
|
|
1213 | 1213 |
{ |
1214 |
struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
|
|
1214 |
TSC210xState *s = (TSC210xState *) chip->opaque;
|
|
1215 | 1215 |
|
1216 | 1216 |
return &s->codec; |
1217 | 1217 |
} |
... | ... | |
1221 | 1221 |
* from the touchscreen. Assuming 12-bit precision was used during |
1222 | 1222 |
* tslib calibration. |
1223 | 1223 |
*/ |
1224 |
void tsc210x_set_transform(struct uwire_slave_s *chip,
|
|
1225 |
struct mouse_transform_info_s *info)
|
|
1224 |
void tsc210x_set_transform(uWireSlave *chip,
|
|
1225 |
MouseTransformInfo *info)
|
|
1226 | 1226 |
{ |
1227 |
struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
|
|
1227 |
TSC210xState *s = (TSC210xState *) chip->opaque;
|
|
1228 | 1228 |
#if 0 |
1229 | 1229 |
int64_t ltr[8]; |
1230 | 1230 |
|
... | ... | |
1283 | 1283 |
#endif |
1284 | 1284 |
} |
1285 | 1285 |
|
1286 |
void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down)
|
|
1286 |
void tsc210x_key_event(uWireSlave *chip, int key, int down)
|
|
1287 | 1287 |
{ |
1288 |
struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
|
|
1288 |
TSC210xState *s = (TSC210xState *) chip->opaque;
|
|
1289 | 1289 |
|
1290 | 1290 |
if (down) |
1291 | 1291 |
s->kb.down |= 1 << key; |
Also available in: Unified diff