1 /* 2 * TI TSC2005 emulator. 3 * 4 * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org> 5 * Copyright (C) 2008 Nokia Corporation 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 or 10 * (at your option) version 3 of the License. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qemu/log.h" 23 #include "qemu/timer.h" 24 #include "sysemu/reset.h" 25 #include "ui/console.h" 26 #include "hw/input/tsc2xxx.h" 27 #include "hw/irq.h" 28 #include "migration/vmstate.h" 29 #include "trace.h" 30 31 #define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - (p ? 12 : 10))) 32 33 typedef struct { 34 qemu_irq pint; /* Combination of the nPENIRQ and DAV signals */ 35 QEMUTimer *timer; 36 uint16_t model; 37 38 int32_t x, y; 39 bool pressure; 40 41 uint8_t reg, state; 42 bool irq, command; 43 uint16_t data, dav; 44 45 bool busy; 46 bool enabled; 47 bool host_mode; 48 int8_t function; 49 int8_t nextfunction; 50 bool precision; 51 bool nextprecision; 52 uint16_t filter; 53 uint8_t pin_func; 54 uint16_t timing[2]; 55 uint8_t noise; 56 bool reset; 57 bool pdst; 58 bool pnd0; 59 uint16_t temp_thr[2]; 60 uint16_t aux_thr[2]; 61 62 int32_t tr[8]; 63 } TSC2005State; 64 65 enum { 66 TSC_MODE_XYZ_SCAN = 0x0, 67 TSC_MODE_XY_SCAN, 68 TSC_MODE_X, 69 TSC_MODE_Y, 70 TSC_MODE_Z, 71 TSC_MODE_AUX, 72 TSC_MODE_TEMP1, 73 TSC_MODE_TEMP2, 74 TSC_MODE_AUX_SCAN, 75 TSC_MODE_X_TEST, 76 TSC_MODE_Y_TEST, 77 TSC_MODE_TS_TEST, 78 TSC_MODE_RESERVED, 79 TSC_MODE_XX_DRV, 80 TSC_MODE_YY_DRV, 81 TSC_MODE_YX_DRV, 82 }; 83 84 static const uint16_t mode_regs[16] = { 85 0xf000, /* X, Y, Z scan */ 86 0xc000, /* X, Y scan */ 87 0x8000, /* X */ 88 0x4000, /* Y */ 89 0x3000, /* Z */ 90 0x0800, /* AUX */ 91 0x0400, /* TEMP1 */ 92 0x0200, /* TEMP2 */ 93 0x0800, /* AUX scan */ 94 0x0040, /* X test */ 95 0x0020, /* Y test */ 96 0x0080, /* Short-circuit test */ 97 0x0000, /* Reserved */ 98 0x0000, /* X+, X- drivers */ 99 0x0000, /* Y+, Y- drivers */ 100 0x0000, /* Y+, X- drivers */ 101 }; 102 103 #define X_TRANSFORM(s) \ 104 ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3]) 105 #define Y_TRANSFORM(s) \ 106 ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7]) 107 #define Z1_TRANSFORM(s) \ 108 ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4) 109 #define Z2_TRANSFORM(s) \ 110 ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4) 111 112 #define AUX_VAL (700 << 4) /* +/- 3 at 12-bit */ 113 #define TEMP1_VAL (1264 << 4) /* +/- 5 at 12-bit */ 114 #define TEMP2_VAL (1531 << 4) /* +/- 5 at 12-bit */ 115 116 static uint16_t tsc2005_read(TSC2005State *s, int reg) 117 { 118 uint16_t ret; 119 120 switch (reg) { 121 case 0x0: /* X */ 122 s->dav &= ~mode_regs[TSC_MODE_X]; 123 return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) + 124 (s->noise & 3); 125 case 0x1: /* Y */ 126 s->dav &= ~mode_regs[TSC_MODE_Y]; 127 s->noise++; 128 return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^ 129 (s->noise & 3); 130 case 0x2: /* Z1 */ 131 s->dav &= 0xdfff; 132 return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) - 133 (s->noise & 3); 134 case 0x3: /* Z2 */ 135 s->dav &= 0xefff; 136 return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) | 137 (s->noise & 3); 138 139 case 0x4: /* AUX */ 140 s->dav &= ~mode_regs[TSC_MODE_AUX]; 141 return TSC_CUT_RESOLUTION(AUX_VAL, s->precision); 142 143 case 0x5: /* TEMP1 */ 144 s->dav &= ~mode_regs[TSC_MODE_TEMP1]; 145 return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) - 146 (s->noise & 5); 147 case 0x6: /* TEMP2 */ 148 s->dav &= 0xdfff; 149 s->dav &= ~mode_regs[TSC_MODE_TEMP2]; 150 return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^ 151 (s->noise & 3); 152 153 case 0x7: /* Status */ 154 ret = s->dav | (s->reset << 7) | (s->pdst << 2) | 0x0; 155 s->dav &= ~(mode_regs[TSC_MODE_X_TEST] | mode_regs[TSC_MODE_Y_TEST] | 156 mode_regs[TSC_MODE_TS_TEST]); 157 s->reset = true; 158 return ret; 159 160 case 0x8: /* AUX high threshold */ 161 return s->aux_thr[1]; 162 case 0x9: /* AUX low threshold */ 163 return s->aux_thr[0]; 164 165 case 0xa: /* TEMP high threshold */ 166 return s->temp_thr[1]; 167 case 0xb: /* TEMP low threshold */ 168 return s->temp_thr[0]; 169 170 case 0xc: /* CFR0 */ 171 return (s->pressure << 15) | ((!s->busy) << 14) | 172 (s->nextprecision << 13) | s->timing[0]; 173 case 0xd: /* CFR1 */ 174 return s->timing[1]; 175 case 0xe: /* CFR2 */ 176 return (s->pin_func << 14) | s->filter; 177 178 case 0xf: /* Function select status */ 179 return s->function >= 0 ? 1 << s->function : 0; 180 } 181 182 /* Never gets here */ 183 return 0xffff; 184 } 185 186 static void tsc2005_write(TSC2005State *s, int reg, uint16_t data) 187 { 188 switch (reg) { 189 case 0x8: /* AUX high threshold */ 190 s->aux_thr[1] = data; 191 break; 192 case 0x9: /* AUX low threshold */ 193 s->aux_thr[0] = data; 194 break; 195 196 case 0xa: /* TEMP high threshold */ 197 s->temp_thr[1] = data; 198 break; 199 case 0xb: /* TEMP low threshold */ 200 s->temp_thr[0] = data; 201 break; 202 203 case 0xc: /* CFR0 */ 204 s->host_mode = (data >> 15) != 0; 205 if (s->enabled != !(data & 0x4000)) { 206 s->enabled = !(data & 0x4000); 207 trace_tsc2005_sense(s->enabled ? "enabled" : "disabled"); 208 if (s->busy && !s->enabled) { 209 timer_del(s->timer); 210 } 211 s->busy = s->busy && s->enabled; 212 } 213 s->nextprecision = (data >> 13) & 1; 214 s->timing[0] = data & 0x1fff; 215 if ((s->timing[0] >> 11) == 3) { 216 qemu_log_mask(LOG_GUEST_ERROR, 217 "tsc2005_write: illegal conversion clock setting\n"); 218 } 219 break; 220 case 0xd: /* CFR1 */ 221 s->timing[1] = data & 0xf07; 222 break; 223 case 0xe: /* CFR2 */ 224 s->pin_func = (data >> 14) & 3; 225 s->filter = data & 0x3fff; 226 break; 227 228 default: 229 qemu_log_mask(LOG_GUEST_ERROR, 230 "%s: write into read-only register 0x%x\n", 231 __func__, reg); 232 } 233 } 234 235 /* This handles most of the chip's logic. */ 236 static void tsc2005_pin_update(TSC2005State *s) 237 { 238 int64_t expires; 239 bool pin_state; 240 241 switch (s->pin_func) { 242 case 0: 243 pin_state = !s->pressure && !!s->dav; 244 break; 245 case 1: 246 case 3: 247 default: 248 pin_state = !s->dav; 249 break; 250 case 2: 251 pin_state = !s->pressure; 252 } 253 254 if (pin_state != s->irq) { 255 s->irq = pin_state; 256 qemu_set_irq(s->pint, s->irq); 257 } 258 259 switch (s->nextfunction) { 260 case TSC_MODE_XYZ_SCAN: 261 case TSC_MODE_XY_SCAN: 262 if (!s->host_mode && s->dav) { 263 s->enabled = false; 264 } 265 if (!s->pressure) { 266 return; 267 } 268 /* Fall through */ 269 case TSC_MODE_AUX_SCAN: 270 break; 271 272 case TSC_MODE_X: 273 case TSC_MODE_Y: 274 case TSC_MODE_Z: 275 if (!s->pressure) { 276 return; 277 } 278 /* Fall through */ 279 case TSC_MODE_AUX: 280 case TSC_MODE_TEMP1: 281 case TSC_MODE_TEMP2: 282 case TSC_MODE_X_TEST: 283 case TSC_MODE_Y_TEST: 284 case TSC_MODE_TS_TEST: 285 if (s->dav) { 286 s->enabled = false; 287 } 288 break; 289 290 case TSC_MODE_RESERVED: 291 case TSC_MODE_XX_DRV: 292 case TSC_MODE_YY_DRV: 293 case TSC_MODE_YX_DRV: 294 default: 295 return; 296 } 297 298 if (!s->enabled || s->busy) { 299 return; 300 } 301 302 s->busy = true; 303 s->precision = s->nextprecision; 304 s->function = s->nextfunction; 305 s->pdst = !s->pnd0; /* Synchronised on internal clock */ 306 expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 307 (NANOSECONDS_PER_SECOND >> 7); 308 timer_mod(s->timer, expires); 309 } 310 311 static void tsc2005_reset(TSC2005State *s) 312 { 313 s->state = 0; 314 s->pin_func = 0; 315 s->enabled = false; 316 s->busy = false; 317 s->nextprecision = false; 318 s->nextfunction = 0; 319 s->timing[0] = 0; 320 s->timing[1] = 0; 321 s->irq = false; 322 s->dav = 0; 323 s->reset = false; 324 s->pdst = true; 325 s->pnd0 = false; 326 s->function = -1; 327 s->temp_thr[0] = 0x000; 328 s->temp_thr[1] = 0xfff; 329 s->aux_thr[0] = 0x000; 330 s->aux_thr[1] = 0xfff; 331 332 tsc2005_pin_update(s); 333 } 334 335 static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value) 336 { 337 TSC2005State *s = opaque; 338 uint32_t ret = 0; 339 340 switch (s->state++) { 341 case 0: 342 if (value & 0x80) { 343 /* Command */ 344 if (value & (1 << 1)) 345 tsc2005_reset(s); 346 else { 347 s->nextfunction = (value >> 3) & 0xf; 348 s->nextprecision = (value >> 2) & 1; 349 if (s->enabled != !(value & 1)) { 350 s->enabled = !(value & 1); 351 trace_tsc2005_sense(s->enabled ? "enabled" : "disabled"); 352 if (s->busy && !s->enabled) { 353 timer_del(s->timer); 354 } 355 s->busy = s->busy && s->enabled; 356 } 357 tsc2005_pin_update(s); 358 } 359 360 s->state = 0; 361 } else if (value) { 362 /* Data transfer */ 363 s->reg = (value >> 3) & 0xf; 364 s->pnd0 = (value >> 1) & 1; 365 s->command = value & 1; 366 367 if (s->command) { 368 /* Read */ 369 s->data = tsc2005_read(s, s->reg); 370 tsc2005_pin_update(s); 371 } else 372 s->data = 0; 373 } else 374 s->state = 0; 375 break; 376 377 case 1: 378 if (s->command) { 379 ret = (s->data >> 8) & 0xff; 380 } else { 381 s->data |= value << 8; 382 } 383 break; 384 385 case 2: 386 if (s->command) 387 ret = s->data & 0xff; 388 else { 389 s->data |= value; 390 tsc2005_write(s, s->reg, s->data); 391 tsc2005_pin_update(s); 392 } 393 394 s->state = 0; 395 break; 396 } 397 398 return ret; 399 } 400 401 uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len) 402 { 403 uint32_t ret = 0; 404 405 len &= ~7; 406 while (len > 0) { 407 len -= 8; 408 ret |= tsc2005_txrx_word(opaque, (value >> len) & 0xff) << len; 409 } 410 411 return ret; 412 } 413 414 static void tsc2005_timer_tick(void *opaque) 415 { 416 TSC2005State *s = opaque; 417 unsigned int function = s->function; 418 419 assert(function < ARRAY_SIZE(mode_regs)); 420 421 /* Timer ticked -- a set of conversions has been finished. */ 422 423 if (!s->busy) { 424 return; 425 } 426 427 s->busy = false; 428 s->dav |= mode_regs[function]; 429 s->function = -1; 430 tsc2005_pin_update(s); 431 } 432 433 static void tsc2005_touchscreen_event(void *opaque, 434 int x, int y, int z, int buttons_state) 435 { 436 TSC2005State *s = opaque; 437 int p = s->pressure; 438 439 if (buttons_state) { 440 s->x = x; 441 s->y = y; 442 } 443 s->pressure = !!buttons_state; 444 445 /* 446 * Note: We would get better responsiveness in the guest by 447 * signaling TS events immediately, but for now we simulate 448 * the first conversion delay for sake of correctness. 449 */ 450 if (p != s->pressure) { 451 tsc2005_pin_update(s); 452 } 453 } 454 455 static int tsc2005_post_load(void *opaque, int version_id) 456 { 457 TSC2005State *s = (TSC2005State *) opaque; 458 459 s->busy = timer_pending(s->timer); 460 tsc2005_pin_update(s); 461 462 return 0; 463 } 464 465 static const VMStateDescription vmstate_tsc2005 = { 466 .name = "tsc2005", 467 .version_id = 2, 468 .minimum_version_id = 2, 469 .post_load = tsc2005_post_load, 470 .fields = (const VMStateField []) { 471 VMSTATE_BOOL(pressure, TSC2005State), 472 VMSTATE_BOOL(irq, TSC2005State), 473 VMSTATE_BOOL(command, TSC2005State), 474 VMSTATE_BOOL(enabled, TSC2005State), 475 VMSTATE_BOOL(host_mode, TSC2005State), 476 VMSTATE_BOOL(reset, TSC2005State), 477 VMSTATE_BOOL(pdst, TSC2005State), 478 VMSTATE_BOOL(pnd0, TSC2005State), 479 VMSTATE_BOOL(precision, TSC2005State), 480 VMSTATE_BOOL(nextprecision, TSC2005State), 481 VMSTATE_UINT8(reg, TSC2005State), 482 VMSTATE_UINT8(state, TSC2005State), 483 VMSTATE_UINT16(data, TSC2005State), 484 VMSTATE_UINT16(dav, TSC2005State), 485 VMSTATE_UINT16(filter, TSC2005State), 486 VMSTATE_INT8(nextfunction, TSC2005State), 487 VMSTATE_INT8(function, TSC2005State), 488 VMSTATE_INT32(x, TSC2005State), 489 VMSTATE_INT32(y, TSC2005State), 490 VMSTATE_TIMER_PTR(timer, TSC2005State), 491 VMSTATE_UINT8(pin_func, TSC2005State), 492 VMSTATE_UINT16_ARRAY(timing, TSC2005State, 2), 493 VMSTATE_UINT8(noise, TSC2005State), 494 VMSTATE_UINT16_ARRAY(temp_thr, TSC2005State, 2), 495 VMSTATE_UINT16_ARRAY(aux_thr, TSC2005State, 2), 496 VMSTATE_INT32_ARRAY(tr, TSC2005State, 8), 497 VMSTATE_END_OF_LIST() 498 } 499 }; 500 501 void *tsc2005_init(qemu_irq pintdav) 502 { 503 TSC2005State *s; 504 505 s = g_new0(TSC2005State, 1); 506 s->x = 400; 507 s->y = 240; 508 s->pressure = false; 509 s->precision = s->nextprecision = false; 510 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc2005_timer_tick, s); 511 s->pint = pintdav; 512 s->model = 0x2005; 513 514 s->tr[0] = 0; 515 s->tr[1] = 1; 516 s->tr[2] = 1; 517 s->tr[3] = 0; 518 s->tr[4] = 1; 519 s->tr[5] = 0; 520 s->tr[6] = 1; 521 s->tr[7] = 0; 522 523 tsc2005_reset(s); 524 525 qemu_add_mouse_event_handler(tsc2005_touchscreen_event, s, 1, 526 "QEMU TSC2005-driven Touchscreen"); 527 528 qemu_register_reset((void *) tsc2005_reset, s); 529 vmstate_register(NULL, 0, &vmstate_tsc2005, s); 530 531 return s; 532 } 533 534 /* 535 * Use tslib generated calibration data to generate ADC input values 536 * from the touchscreen. Assuming 12-bit precision was used during 537 * tslib calibration. 538 */ 539 void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info) 540 { 541 TSC2005State *s = (TSC2005State *) opaque; 542 543 /* This version assumes touchscreen X & Y axis are parallel or 544 * perpendicular to LCD's X & Y axis in some way. */ 545 if (abs(info->a[0]) > abs(info->a[1])) { 546 s->tr[0] = 0; 547 s->tr[1] = -info->a[6] * info->x; 548 s->tr[2] = info->a[0]; 549 s->tr[3] = -info->a[2] / info->a[0]; 550 s->tr[4] = info->a[6] * info->y; 551 s->tr[5] = 0; 552 s->tr[6] = info->a[4]; 553 s->tr[7] = -info->a[5] / info->a[4]; 554 } else { 555 s->tr[0] = info->a[6] * info->y; 556 s->tr[1] = 0; 557 s->tr[2] = info->a[1]; 558 s->tr[3] = -info->a[2] / info->a[1]; 559 s->tr[4] = 0; 560 s->tr[5] = -info->a[6] * info->x; 561 s->tr[6] = info->a[3]; 562 s->tr[7] = -info->a[5] / info->a[3]; 563 } 564 565 s->tr[0] >>= 11; 566 s->tr[1] >>= 11; 567 s->tr[3] <<= 4; 568 s->tr[4] >>= 11; 569 s->tr[5] >>= 11; 570 s->tr[7] <<= 4; 571 } 572