vrpiu.c revision 1.12
1/* $NetBSD: vrpiu.c,v 1.12 2001/06/10 12:37:43 sato Exp $ */ 2 3/* 4 * Copyright (c) 1999 Shin Takemura All rights reserved. 5 * Copyright (c) 2000 SATO Kazumi, All rights reserved. 6 * Copyright (c) 1999,2000 PocketBSD Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31/* 32 * A/D polling part written by SATO Kazumi. 33 */ 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/device.h> 38#include <sys/kernel.h> 39#include <sys/callout.h> 40#include <sys/boot_flag.h> 41 42#include <dev/wscons/wsconsio.h> 43#include <dev/wscons/wsmousevar.h> 44 45#include <machine/bus.h> 46#include <machine/platid.h> 47#include <machine/platid_mask.h> 48#include <machine/config_hook.h> 49 50#include <dev/hpc/tpcalibvar.h> 51 52#include <hpcmips/hpcmips/machdep.h> 53#include <hpcmips/vr/vripvar.h> 54#include <hpcmips/vr/cmureg.h> 55#include <hpcmips/vr/vrpiuvar.h> 56#include <hpcmips/vr/vrpiureg.h> 57 58/* 59 * contant and macro definitions 60 */ 61#define VRPIUDEBUG 62#ifdef VRPIUDEBUG 63int vrpiu_debug = 0; 64#define DPRINTF(arg) if (vrpiu_debug) printf arg; 65#define VPRINTF(arg) if (bootverbose || vrpiu_debug) printf arg; 66#else 67#define DPRINTF(arg) 68#define VPRINTF(arg) if (bootverbose) printf arg; 69#endif 70 71#ifndef VRPIU_AD_POLL_INTERVAL 72#define VRPIU_AD_POLL_INTERVAL 60 /* interval is 60 sec */ 73#endif /* VRPIU_AD_POLL_INTERTVAL */ 74 75#define PIUSIVL_SCANINTVAL_MIN 333 /* 10msec */ 76#define PIUSIVL_SCANINTVAL_MAX PIUSIVL_SCANINTVAL_MASK /* 60msec */ 77#define VRPIU_TP_SCAN_TIMEOUT (hz/10) /* timeout is 100msec */ 78 79#define TP_INTR (PIUINT_ALLINTR & ~PIUINT_PADADPINTR) 80#define AD_INTR (PIUINT_PADADPINTR) 81 82/* 83 * data types 84 */ 85/* struct vrpiu_softc is defined in vrpiuvar.h */ 86 87/* 88 * function prototypes 89 */ 90static int vrpiumatch __P((struct device *, struct cfdata *, void *)); 91static void vrpiuattach __P((struct device *, struct device *, void *)); 92 93static void vrpiu_write __P((struct vrpiu_softc *, int, unsigned short)); 94static u_short vrpiu_read __P((struct vrpiu_softc *, int)); 95 96static int vrpiu_intr __P((void *)); 97static void vrpiu_tp_intr __P((struct vrpiu_softc *)); 98static void vrpiu_ad_intr __P((struct vrpiu_softc *)); 99#ifdef DEBUG 100static void vrpiu_dump_cntreg __P((unsigned int cmd)); 101#endif 102 103static int vrpiu_tp_enable __P((void *)); 104static int vrpiu_tp_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 105static void vrpiu_tp_disable __P((void *)); 106static void vrpiu_tp_up __P((struct vrpiu_softc *)); 107static void vrpiu_tp_timeout __P((void *)); 108int vrpiu_ad_enable __P((void *)); 109void vrpiu_ad_disable __P((void *)); 110static void vrpiu_start_powerstate __P((void *)); 111static void vrpiu_calc_powerstate __P((struct vrpiu_softc *)); 112static void vrpiu_power __P((int, void *)); 113static u_int scan_interval __P((u_int data)); 114 115/* mra is defined in mra.c */ 116int mra_Y_AX1_BX2_C __P((int *y, int ys, int *x1, int x1s, int *x2, int x2s, 117 int n, int scale, int *a, int *b, int *c)); 118 119/* 120 * static or global variables 121 */ 122struct cfattach vrpiu_ca = { 123 sizeof(struct vrpiu_softc), vrpiumatch, vrpiuattach 124}; 125 126const struct wsmouse_accessops vrpiu_accessops = { 127 vrpiu_tp_enable, 128 vrpiu_tp_ioctl, 129 vrpiu_tp_disable, 130}; 131 132int vrpiu_ad_poll_interval = VRPIU_AD_POLL_INTERVAL; 133 134/* 135 * function definitions 136 */ 137static inline void 138vrpiu_write(sc, port, val) 139 struct vrpiu_softc *sc; 140 int port; 141 unsigned short val; 142{ 143 bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val); 144} 145 146static inline u_short 147vrpiu_read(sc, port) 148 struct vrpiu_softc *sc; 149 int port; 150{ 151 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, port); 152} 153 154static int 155vrpiumatch(parent, cf, aux) 156 struct device *parent; 157 struct cfdata *cf; 158 void *aux; 159{ 160 return 1; 161} 162 163static void 164vrpiuattach(parent, self, aux) 165 struct device *parent; 166 struct device *self; 167 void *aux; 168{ 169 struct vrpiu_softc *sc = (struct vrpiu_softc *)self; 170 struct vrip_attach_args *va = aux; 171 struct wsmousedev_attach_args wsmaa; 172 173 bus_space_tag_t iot = va->va_iot; 174 bus_space_handle_t ioh; 175 176 if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) { 177 printf(": can't map bus space\n"); 178 return; 179 } 180 181 sc->sc_iot = iot; 182 sc->sc_ioh = ioh; 183 sc->sc_vrip = va->va_vc; 184 185 sc->sc_interval = scan_interval(WSMOUSE_RES_DEFAULT); 186 187 /* 188 * disable device until vrpiu_enable called 189 */ 190 sc->sc_tpstat = VRPIU_TP_STAT_DISABLE; 191 192 /* initialize touch panel timeout structure */ 193 callout_init(&sc->sc_tptimeout); 194 195 /* initialize calibration context */ 196 tpcalib_init(&sc->sc_tpcalib); 197#if 1 198 /* 199 * XXX, calibrate parameters 200 */ 201 { 202 int i; 203 static const struct { 204 platid_mask_t *mask; 205 struct wsmouse_calibcoords coords; 206 } calibrations[] = { 207 { &platid_mask_MACH_NEC_MCR_700, 208 { 0, 0, 799, 599, 209 4, 210 { { 115, 80, 0, 0 }, 211 { 115, 966, 0, 599 }, 212 { 912, 80, 799, 0 }, 213 { 912, 966, 799, 599 } } } }, 214 215 { &platid_mask_MACH_NEC_MCR_700A, 216 { 0, 0, 799, 599, 217 4, 218 { { 115, 80, 0, 0 }, 219 { 115, 966, 0, 599 }, 220 { 912, 80, 799, 0 }, 221 { 912, 966, 799, 599 } } } }, 222 223 { &platid_mask_MACH_NEC_MCR_730, 224 { 0, 0, 799, 599, 225 4, 226 { { 115, 80, 0, 0 }, 227 { 115, 966, 0, 599 }, 228 { 912, 80, 799, 0 }, 229 { 912, 966, 799, 599 } } } }, 230 231 { NULL, /* samples got on my MC-R500 */ 232 { 0, 0, 639, 239, 233 5, 234 { { 502, 486, 320, 120 }, 235 { 55, 109, 0, 0 }, 236 { 54, 913, 0, 239 }, 237 { 973, 924, 639, 239 }, 238 { 975, 123, 639, 0 } } } }, 239 }; 240 for (i = 0; ; i++) { 241 if (calibrations[i].mask == NULL 242 || platid_match(&platid, calibrations[i].mask)) 243 break; 244 } 245 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 246 (caddr_t)&calibrations[i].coords, 0, 0); 247 } 248#endif 249 250 /* install interrupt handler and enable interrupt */ 251 if (!(sc->sc_handler = 252 vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY, 253 vrpiu_intr, sc))) { 254 printf (": can't map interrupt line.\n"); 255 return; 256 } 257 258 /* mask level2 interrupt, stop scan sequencer and mask clock to piu */ 259 vrpiu_tp_disable(sc); 260 261 printf("\n"); 262 263 wsmaa.accessops = &vrpiu_accessops; 264 wsmaa.accesscookie = sc; 265 266 /* 267 * attach the wsmouse 268 */ 269 sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint); 270 271 /* 272 * power management events 273 */ 274 sc->sc_power_hook = powerhook_establish(vrpiu_power, sc); 275 276 /* 277 * init A/D port polling. 278 */ 279 sc->sc_battery.n_values = 3; 280 sc->sc_battery.value[0] = -1; 281 sc->sc_battery.value[1] = -1; 282 sc->sc_battery.value[2] = -1; 283 sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval; 284 callout_init(&sc->sc_adpoll); 285 callout_reset(&sc->sc_adpoll, hz, vrpiu_start_powerstate, sc); 286} 287 288/* 289 * calculate interval value 290 * input: WSMOUSE_RES_MIN - WSMOUSE_RES_MAX 291 * output: value for PIUSIVL_REG 292 */ 293static u_int 294scan_interval(u_int data) 295{ 296 int scale; 297 298 if (data < WSMOUSE_RES_MIN) 299 data = WSMOUSE_RES_MIN; 300 301 if (WSMOUSE_RES_MAX < data) 302 data = WSMOUSE_RES_MAX; 303 304 scale = WSMOUSE_RES_MAX - WSMOUSE_RES_MIN; 305 data += WSMOUSE_RES_MIN; 306 307 return PIUSIVL_SCANINTVAL_MIN + 308 (PIUSIVL_SCANINTVAL_MAX - PIUSIVL_SCANINTVAL_MIN) * 309 (scale - data) / scale; 310} 311 312int 313vrpiu_ad_enable(v) 314 void *v; 315{ 316 struct vrpiu_softc *sc = v; 317 int s; 318 unsigned int cnt; 319 320 DPRINTF(("%s(%d): vrpiu_ad_enable(): interval=0x%03x\n", 321 __FILE__, __LINE__, sc->sc_interval)); 322 if (sc->sc_adstat != VRPIU_AD_STAT_DISABLE) 323 return EBUSY; 324 325 /* supply clock to PIU */ 326 __vrcmu_supply(CMUMSKPIU, 1); 327 328 /* set scan interval */ 329 vrpiu_write(sc, PIUSIVL_REG_W, sc->sc_interval); 330 331 s = spltty(); 332 333 /* clear interrupt status */ 334 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 335 336 /* Disable -> Standby */ 337 cnt = PIUCNT_PIUPWR | 338 PIUCNT_PIUMODE_COORDINATE | 339 PIUCNT_PADATSTART | PIUCNT_PADATSTOP; 340 vrpiu_write(sc, PIUCNT_REG_W, cnt); 341 342 /* Level2 interrupt register setting */ 343 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AD_INTR, 1); 344 345 /* save pen status, touch or release */ 346 cnt = vrpiu_read(sc, PIUCNT_REG_W); 347 348 /* 349 * Enable scan sequencer operation 350 * Standby -> WaitPenTouch 351 */ 352 cnt |= PIUCNT_PIUSEQEN; 353 vrpiu_write(sc, PIUCNT_REG_W, cnt); 354 355 sc->sc_adstat = VRPIU_AD_STAT_ENABLE; 356 357 splx(s); 358 359 return 0; 360} 361 362void 363vrpiu_ad_disable(v) 364 void *v; 365{ 366 struct vrpiu_softc *sc = v; 367 368 DPRINTF(("%s(%d): vrpiu_ad_disable()\n", __FILE__, __LINE__)); 369 370 /* Set level2 interrupt register to mask interrupts */ 371 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AD_INTR, 0); 372 373 sc->sc_adstat = VRPIU_AD_STAT_DISABLE; 374 375 if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE){ 376 /* Disable scan sequencer operation and power off */ 377 vrpiu_write(sc, PIUCNT_REG_W, 0); 378 379 /* mask clock to PIU */ 380 __vrcmu_supply(CMUMSKPIU, 1); 381 } 382} 383 384int 385vrpiu_tp_enable(v) 386 void *v; 387{ 388 struct vrpiu_softc *sc = v; 389 int s; 390 unsigned int cnt; 391 392 DPRINTF(("%s(%d): vrpiu_tp_enable(): interval=0x%03x\n", 393 __FILE__, __LINE__, sc->sc_interval)); 394 if (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE) 395 return EBUSY; 396 397 /* supply clock to PIU */ 398 __vrcmu_supply(CMUMSKPIU, 1); 399 400 /* set scan interval */ 401 vrpiu_write(sc, PIUSIVL_REG_W, sc->sc_interval); 402 403 s = spltty(); 404 405 /* clear interrupt status */ 406 vrpiu_write(sc, PIUINT_REG_W, TP_INTR); 407 408 /* Disable -> Standby */ 409 cnt = PIUCNT_PIUPWR | 410 PIUCNT_PIUMODE_COORDINATE | 411 PIUCNT_PADATSTART | PIUCNT_PADATSTOP; 412 vrpiu_write(sc, PIUCNT_REG_W, cnt); 413 414 /* Level2 interrupt register setting */ 415 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, TP_INTR, 1); 416 417 /* save pen status, touch or release */ 418 cnt = vrpiu_read(sc, PIUCNT_REG_W); 419 420 /* 421 * Enable scan sequencer operation 422 * Standby -> WaitPenTouch 423 */ 424 cnt |= PIUCNT_PIUSEQEN; 425 vrpiu_write(sc, PIUCNT_REG_W, cnt); 426 427 /* transit status DISABLE -> TOUCH or RELEASE */ 428 sc->sc_tpstat = (cnt & PIUCNT_PENSTC) ? 429 VRPIU_TP_STAT_TOUCH : VRPIU_TP_STAT_RELEASE; 430 431 splx(s); 432 433 return 0; 434} 435 436void 437vrpiu_tp_disable(v) 438 void *v; 439{ 440 struct vrpiu_softc *sc = v; 441 442 DPRINTF(("%s(%d): vrpiu_tp_disable()\n", __FILE__, __LINE__)); 443 444 /* Set level2 interrupt register to mask interrupts */ 445 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, TP_INTR, 0); 446 447 sc->sc_tpstat = VRPIU_TP_STAT_DISABLE; 448 449 if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE){ 450 /* Disable scan sequencer operation and power off */ 451 vrpiu_write(sc, PIUCNT_REG_W, 0); 452 453 /* mask clock to PIU */ 454 __vrcmu_supply(CMUMSKPIU, 1); 455 } 456} 457 458int 459vrpiu_tp_ioctl(v, cmd, data, flag, p) 460 void *v; 461 u_long cmd; 462 caddr_t data; 463 int flag; 464 struct proc *p; 465{ 466 struct vrpiu_softc *sc = v; 467 468 DPRINTF(("%s(%d): vrpiu_tp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd)); 469 470 switch (cmd) { 471 case WSMOUSEIO_GTYPE: 472 *(u_int *)data = WSMOUSE_TYPE_TPANEL; 473 break; 474 475 case WSMOUSEIO_SRES: 476 { 477 int tp_enable; 478 int ad_enable; 479 480 tp_enable = (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE); 481 ad_enable = (sc->sc_adstat != VRPIU_AD_STAT_DISABLE); 482 483 if (tp_enable) 484 vrpiu_tp_disable(sc); 485 if (ad_enable) 486 vrpiu_ad_disable(sc); 487 488 sc->sc_interval = scan_interval(*(u_int *)data); 489 DPRINTF(("%s(%d): WSMOUSEIO_SRES: *data=%d, interval=0x%03x\n", 490 __FILE__, __LINE__, *(u_int *)data, sc->sc_interval)); 491 492 if (sc->sc_interval < PIUSIVL_SCANINTVAL_MIN) 493 sc->sc_interval = PIUSIVL_SCANINTVAL_MIN; 494 495 if (PIUSIVL_SCANINTVAL_MAX < sc->sc_interval) 496 sc->sc_interval = PIUSIVL_SCANINTVAL_MAX; 497 498 if (tp_enable) 499 vrpiu_tp_enable(sc); 500 if (ad_enable) 501 vrpiu_ad_enable(sc); 502 } 503 break; 504 505 case WSMOUSEIO_SCALIBCOORDS: 506 case WSMOUSEIO_GCALIBCOORDS: 507 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p); 508 509 default: 510 return (-1); 511 } 512 return (0); 513} 514 515/* 516 * PIU AD interrupt handler. 517 */ 518void 519vrpiu_ad_intr(sc) 520 struct vrpiu_softc *sc; 521{ 522 unsigned int i; 523 unsigned int intrstat; 524 525 intrstat = vrpiu_read(sc, PIUINT_REG_W); 526 527 if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE) { 528 /* 529 * the device isn't enabled. just clear interrupt. 530 */ 531 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 532 return; 533 } 534 535 if (intrstat & PIUINT_PADADPINTR) { 536 sc->sc_battery.value[0] = (unsigned int)vrpiu_read(sc, PIUAB(0)); 537 sc->sc_battery.value[1] = (unsigned int)vrpiu_read(sc, PIUAB(1)); 538 sc->sc_battery.value[2] = (unsigned int)vrpiu_read(sc, PIUAB(2)); 539 } 540 541 if (intrstat & PIUINT_PADADPINTR) { 542 for (i = 0; i < 3; i++) { 543 if (sc->sc_battery.value[i] & PIUAB_VALID) 544 sc->sc_battery.value[i] &= PIUAB_PADDATA_MASK; 545 else 546 sc->sc_battery.value[i] = 0; 547 } 548 vrpiu_calc_powerstate(sc); 549 } 550 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 551 552 return; 553} 554/* 555 * PIU TP interrupt handler. 556 */ 557void 558vrpiu_tp_intr(sc) 559 struct vrpiu_softc *sc; 560{ 561 unsigned int cnt, i; 562 unsigned int intrstat, page; 563 int tpx0, tpx1, tpy0, tpy1; 564 int x, y, xraw, yraw; 565 566 intrstat = vrpiu_read(sc, PIUINT_REG_W); 567 568 if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE) { 569 /* 570 * the device isn't enabled. just clear interrupt. 571 */ 572 vrpiu_write(sc, PIUINT_REG_W, intrstat & TP_INTR); 573 return; 574 } 575 576 page = (intrstat & PIUINT_OVP) ? 1 : 0; 577 if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) { 578 tpx0 = vrpiu_read(sc, PIUPB(page, 0)); 579 tpx1 = vrpiu_read(sc, PIUPB(page, 1)); 580 tpy0 = vrpiu_read(sc, PIUPB(page, 2)); 581 tpy1 = vrpiu_read(sc, PIUPB(page, 3)); 582 } 583 584 if (intrstat & PIUINT_PADDLOSTINTR) { 585 page = page ? 0 : 1; 586 for (i = 0; i < 4; i++) 587 vrpiu_read(sc, PIUPB(page, i)); 588 } 589 590 cnt = vrpiu_read(sc, PIUCNT_REG_W); 591#ifdef DEBUG 592 if (vrpiu_debug) 593 vrpiu_dump_cntreg(cnt); 594#endif 595 596 /* clear interrupt status */ 597 vrpiu_write(sc, PIUINT_REG_W, intrstat & TP_INTR); 598 599#if 0 600 DPRINTF(("vrpiu_intr: OVP=%d", page)); 601 if (intrstat & PIUINT_PADCMDINTR) 602 DPRINTF((" CMD")); 603 if (intrstat & PIUINT_PADADPINTR) 604 DPRINTF((" A/D")); 605 if (intrstat & PIUINT_PADPAGE1INTR) 606 DPRINTF((" PAGE1")); 607 if (intrstat & PIUINT_PADPAGE0INTR) 608 DPRINTF((" PAGE0")); 609 if (intrstat & PIUINT_PADDLOSTINTR) 610 DPRINTF((" DLOST")); 611 if (intrstat & PIUINT_PENCHGINTR) 612 DPRINTF((" PENCHG")); 613 DPRINTF(("\n")); 614#endif 615 if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) { 616 /* 617 * just ignore scan data if status isn't Touch. 618 */ 619 if (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH) { 620 /* reset tp scan timeout */ 621 callout_reset(&sc->sc_tptimeout, VRPIU_TP_SCAN_TIMEOUT, 622 vrpiu_tp_timeout, sc); 623 624 if (!((tpx0 & PIUPB_VALID) && (tpx1 & PIUPB_VALID) && 625 (tpy0 & PIUPB_VALID) && (tpy1 & PIUPB_VALID))) { 626 printf("vrpiu: internal error, data is not valid!\n"); 627 } else { 628 tpx0 &= PIUPB_PADDATA_MASK; 629 tpx1 &= PIUPB_PADDATA_MASK; 630 tpy0 &= PIUPB_PADDATA_MASK; 631 tpy1 &= PIUPB_PADDATA_MASK; 632#define ISVALID(n, c, m) ((c) - (m) < (n) && (n) < (c) + (m)) 633 if (ISVALID(tpx0 + tpx1, 1024, 200) && 634 ISVALID(tpy0 + tpy1, 1024, 200)) { 635#if 0 636 DPRINTF(("%04x %04x %04x %04x\n", 637 tpx0, tpx1, tpy0, tpy1)); 638 DPRINTF(("%3d %3d (%4d %4d)->", tpx0, tpy0, 639 tpx0 + tpx1, tpy0 + tpy1)); 640#endif 641 xraw = tpy1 * 1024 / (tpy0 + tpy1); 642 yraw = tpx1 * 1024 / (tpx0 + tpx1); 643 DPRINTF(("%3d %3d", xraw, yraw)); 644 645 tpcalib_trans(&sc->sc_tpcalib, xraw, yraw, &x, &y); 646 647 DPRINTF(("->%4d %4d", x, y)); 648 wsmouse_input(sc->sc_wsmousedev, 649 1, /* button 0 down */ 650 x, /* x */ 651 y, /* y */ 652 0, /* z */ 653 WSMOUSE_INPUT_ABSOLUTE_X | 654 WSMOUSE_INPUT_ABSOLUTE_Y); 655 DPRINTF(("\n")); 656 } 657 } 658 } 659 } 660 661 if (cnt & PIUCNT_PENSTC) { 662 if (sc->sc_tpstat == VRPIU_TP_STAT_RELEASE) { 663 /* 664 * pen touch 665 */ 666 DPRINTF(("PEN TOUCH\n")); 667 sc->sc_tpstat = VRPIU_TP_STAT_TOUCH; 668 /* 669 * We should not report button down event while 670 * we don't know where it occur. 671 */ 672 673 /* set tp scan timeout */ 674 callout_reset(&sc->sc_tptimeout, VRPIU_TP_SCAN_TIMEOUT, 675 vrpiu_tp_timeout, sc); 676 } 677 } else { 678 vrpiu_tp_up(sc); 679 } 680 681 if (intrstat & PIUINT_PADDLOSTINTR) { 682 cnt |= PIUCNT_PIUSEQEN; 683 vrpiu_write(sc, PIUCNT_REG_W, cnt); 684 } 685 686 return; 687} 688 689void 690vrpiu_tp_up(sc) 691 struct vrpiu_softc *sc; 692{ 693 if (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH) { 694 /* 695 * pen release 696 */ 697 DPRINTF(("RELEASE\n")); 698 sc->sc_tpstat = VRPIU_TP_STAT_RELEASE; 699 700 /* clear tp scan timeout */ 701 callout_stop(&sc->sc_tptimeout); 702 703 /* button 0 UP */ 704 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0); 705 } 706} 707 708/* touch panel timeout handler */ 709void 710vrpiu_tp_timeout(v) 711 void *v; 712{ 713 struct vrpiu_softc *sc = (struct vrpiu_softc *)v; 714 715#ifdef VRPIUDEBUG 716 { 717 unsigned int cnt = vrpiu_read(sc, PIUCNT_REG_W); 718 DPRINTF(("TIMEOUT: stat=%s reg=%s\n", 719 (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH)?"touch":"release", 720 (cnt & PIUCNT_PENSTC)?"touch":"release")); 721 } 722#endif 723 vrpiu_tp_up(sc); 724} 725 726/* 727 * PIU interrupt handler. 728 */ 729int 730vrpiu_intr(arg) 731 void *arg; 732{ 733 struct vrpiu_softc *sc = arg; 734 735 vrpiu_ad_intr(sc); 736 vrpiu_tp_intr(sc); 737 738 return 0; 739} 740 741void 742vrpiu_start_powerstate(v) 743 void *v; 744{ 745 int mask; 746 struct vrpiu_softc *sc = (struct vrpiu_softc *)v; 747 748 vrpiu_ad_enable(sc); 749 mask = vrpiu_read(sc, PIUAMSK_REG_W); 750 mask &= 0xff8f; /* XXX */ 751 vrpiu_write(sc, PIUAMSK_REG_W, mask); 752 vrpiu_write(sc, PIUASCN_REG_W, PIUACN_ADPSSTART); 753 /* 754 * restart next A/D polling 755 */ 756 callout_reset(&sc->sc_adpoll, hz*vrpiu_ad_poll_interval, 757 vrpiu_start_powerstate, sc); 758} 759 760void 761vrpiu_calc_powerstate(sc) 762 struct vrpiu_softc *sc; 763{ 764 extern void vrgiu_diff_io __P((void)); 765 vrpiu_ad_disable(sc); 766 VPRINTF(("vrpiu:AD: %d, %d, %d\n", 767 sc->sc_battery.value[0], 768 sc->sc_battery.value[1], 769 sc->sc_battery.value[2])); 770 sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval; 771#ifdef notyet 772 config_hook_call(CONFIG_HOOK_SET, 773 CONFIG_HOOK_BATTERYVAL, 774 (void *)&sc->sc_battery); 775#endif /* notyet */ 776 /* 777 * restart next A/D polling if change polling timming. 778 */ 779 if (sc->sc_battery.nextpoll != hz*vrpiu_ad_poll_interval) 780 callout_reset(&sc->sc_adpoll, sc->sc_battery.nextpoll, 781 vrpiu_start_powerstate, sc); 782 if (bootverbose) 783 vrgiu_diff_io(); 784 785} 786 787static void 788vrpiu_power(why, arg) 789 int why; 790 void *arg; 791{ 792 struct vrpiu_softc *sc = arg; 793 794 switch (why) { 795 case PWR_STANDBY: 796 case PWR_SUSPEND: 797 break; 798 case PWR_RESUME: 799 callout_reset(&sc->sc_adpoll, hz, 800 vrpiu_start_powerstate, sc); 801 break; 802 } 803} 804 805#ifdef DEBUG 806void 807vrpiu_dump_cntreg(cnt) 808 unsigned int cnt; 809{ 810 printf("%s", (cnt & PIUCNT_PENSTC) ? "Touch" : "Release"); 811 printf(" state="); 812 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_CmdScan) 813 printf("CmdScan"); 814 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_IntervalNextScan) 815 printf("IntervalNextScan"); 816 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_PenDataScan) 817 printf("PenDataScan"); 818 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_WaitPenTouch) 819 printf("WaitPenTouch"); 820 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_RFU) 821 printf("???"); 822 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_ADPortScan) 823 printf("ADPortScan"); 824 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Standby) 825 printf("Standby"); 826 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Disable) 827 printf("Disable"); 828 if (cnt & PIUCNT_PADATSTOP) 829 printf(" AutoStop"); 830 if (cnt & PIUCNT_PADATSTART) 831 printf(" AutoStart"); 832 if (cnt & PIUCNT_PADSCANSTOP) 833 printf(" Stop"); 834 if (cnt & PIUCNT_PADSCANSTART) 835 printf(" Start"); 836 if (cnt & PIUCNT_PADSCANTYPE) 837 printf(" ScanPressure"); 838 if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_ADCONVERTER) 839 printf(" A/D"); 840 if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_COORDINATE) 841 printf(" Coordinate"); 842 if (cnt & PIUCNT_PIUSEQEN) 843 printf(" SeqEn"); 844 if ((cnt & PIUCNT_PIUPWR) == 0) 845 printf(" PowerOff"); 846 if ((cnt & PIUCNT_PADRST) == 0) 847 printf(" Reset"); 848 printf("\n"); 849} 850#endif 851