vrpiu.c revision 1.9
1/* $NetBSD: vrpiu.c,v 1.9 2001/01/20 12:24:22 takemura 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 <hpcmips/hpcmips/machdep.h> 51#include <hpcmips/dev/tpcalibvar.h> 52 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 78#define TP_INTR (PIUINT_ALLINTR & ~PIUINT_PADADPINTR) 79#define AD_INTR (PIUINT_PADADPINTR) 80 81/* 82 * data types 83 */ 84/* struct vrpiu_softc is defined in vrpiuvar.h */ 85 86/* 87 * function prototypes 88 */ 89static int vrpiumatch __P((struct device *, struct cfdata *, void *)); 90static void vrpiuattach __P((struct device *, struct device *, void *)); 91 92static void vrpiu_write __P((struct vrpiu_softc *, int, unsigned short)); 93static u_short vrpiu_read __P((struct vrpiu_softc *, int)); 94 95static int vrpiu_intr __P((void *)); 96static void vrpiu_tp_intr __P((struct vrpiu_softc *)); 97static void vrpiu_ad_intr __P((struct vrpiu_softc *)); 98#ifdef DEBUG 99static void vrpiu_dump_cntreg __P((unsigned int cmd)); 100#endif 101 102static int vrpiu_tp_enable __P((void *)); 103static int vrpiu_tp_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 104static void vrpiu_tp_disable __P((void *)); 105int vrpiu_ad_enable __P((void *)); 106void vrpiu_ad_disable __P((void *)); 107static void vrpiu_start_powerstate __P((void *)); 108static void vrpiu_calc_powerstate __P((struct vrpiu_softc *)); 109static void vrpiu_power __P((int, void *)); 110static u_int scan_interval __P((u_int data)); 111 112/* mra is defined in mra.c */ 113int mra_Y_AX1_BX2_C __P((int *y, int ys, int *x1, int x1s, int *x2, int x2s, 114 int n, int scale, int *a, int *b, int *c)); 115 116/* 117 * static or global variables 118 */ 119struct cfattach vrpiu_ca = { 120 sizeof(struct vrpiu_softc), vrpiumatch, vrpiuattach 121}; 122 123const struct wsmouse_accessops vrpiu_accessops = { 124 vrpiu_tp_enable, 125 vrpiu_tp_ioctl, 126 vrpiu_tp_disable, 127}; 128 129int vrpiu_ad_poll_interval = VRPIU_AD_POLL_INTERVAL; 130 131/* 132 * function definitions 133 */ 134static inline void 135vrpiu_write(sc, port, val) 136 struct vrpiu_softc *sc; 137 int port; 138 unsigned short val; 139{ 140 bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val); 141} 142 143static inline u_short 144vrpiu_read(sc, port) 145 struct vrpiu_softc *sc; 146 int port; 147{ 148 return bus_space_read_2(sc->sc_iot, sc->sc_ioh, port); 149} 150 151static int 152vrpiumatch(parent, cf, aux) 153 struct device *parent; 154 struct cfdata *cf; 155 void *aux; 156{ 157 return 1; 158} 159 160static void 161vrpiuattach(parent, self, aux) 162 struct device *parent; 163 struct device *self; 164 void *aux; 165{ 166 struct vrpiu_softc *sc = (struct vrpiu_softc *)self; 167 struct vrip_attach_args *va = aux; 168 struct wsmousedev_attach_args wsmaa; 169 170 bus_space_tag_t iot = va->va_iot; 171 bus_space_handle_t ioh; 172 173 if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) { 174 printf(": can't map bus space\n"); 175 return; 176 } 177 178 sc->sc_iot = iot; 179 sc->sc_ioh = ioh; 180 sc->sc_vrip = va->va_vc; 181 182 sc->sc_interval = scan_interval(WSMOUSE_RES_DEFAULT); 183 184 /* 185 * disable device until vrpiu_enable called 186 */ 187 sc->sc_tpstat = VRPIU_TP_STAT_DISABLE; 188 189 tpcalib_init(&sc->sc_tpcalib); 190#if 1 191 /* 192 * XXX, calibrate parameters 193 */ 194 { 195 int i; 196 static const struct { 197 platid_mask_t *mask; 198 struct wsmouse_calibcoords coords; 199 } calibrations[] = { 200 { &platid_mask_MACH_NEC_MCR_700A, 201 { 0, 0, 799, 599, 202 4, 203 { { 115, 80, 0, 0 }, 204 { 115, 966, 0, 599 }, 205 { 912, 80, 799, 0 }, 206 { 912, 966, 799, 599 } } } }, 207 208 { NULL, /* samples got on my MC-R500 */ 209 { 0, 0, 639, 239, 210 5, 211 { { 502, 486, 320, 120 }, 212 { 55, 109, 0, 0 }, 213 { 54, 913, 0, 239 }, 214 { 973, 924, 639, 239 }, 215 { 975, 123, 639, 0 } } } }, 216 }; 217 for (i = 0; ; i++) { 218 if (calibrations[i].mask == NULL 219 || platid_match(&platid, calibrations[i].mask)) 220 break; 221 } 222 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 223 (caddr_t)&calibrations[i].coords, 0, 0); 224 } 225#endif 226 227 /* install interrupt handler and enable interrupt */ 228 if (!(sc->sc_handler = 229 vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY, 230 vrpiu_intr, sc))) { 231 printf (": can't map interrupt line.\n"); 232 return; 233 } 234 235 /* mask level2 interrupt, stop scan sequencer and mask clock to piu */ 236 vrpiu_tp_disable(sc); 237 238 printf("\n"); 239 240 wsmaa.accessops = &vrpiu_accessops; 241 wsmaa.accesscookie = sc; 242 243 /* 244 * attach the wsmouse 245 */ 246 sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint); 247 248 /* 249 * power management events 250 */ 251 sc->sc_power_hook = powerhook_establish(vrpiu_power, sc); 252 253 /* 254 * init A/D port polling. 255 */ 256 sc->sc_battery.n_values = 3; 257 sc->sc_battery.value[0] = -1; 258 sc->sc_battery.value[1] = -1; 259 sc->sc_battery.value[2] = -1; 260 sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval; 261 callout_init(&sc->sc_adpoll); 262 callout_reset(&sc->sc_adpoll, hz, vrpiu_start_powerstate, sc); 263} 264 265/* 266 * calculate interval value 267 * input: WSMOUSE_RES_MIN - WSMOUSE_RES_MAX 268 * output: value for PIUSIVL_REG 269 */ 270static u_int 271scan_interval(u_int data) 272{ 273 int scale; 274 275 if (data < WSMOUSE_RES_MIN) 276 data = WSMOUSE_RES_MIN; 277 278 if (WSMOUSE_RES_MAX < data) 279 data = WSMOUSE_RES_MAX; 280 281 scale = WSMOUSE_RES_MAX - WSMOUSE_RES_MIN; 282 data += WSMOUSE_RES_MIN; 283 284 return PIUSIVL_SCANINTVAL_MIN + 285 (PIUSIVL_SCANINTVAL_MAX - PIUSIVL_SCANINTVAL_MIN) * 286 (scale - data) / scale; 287} 288 289int 290vrpiu_ad_enable(v) 291 void *v; 292{ 293 struct vrpiu_softc *sc = v; 294 int s; 295 unsigned int cnt; 296 297 DPRINTF(("%s(%d): vrpiu_ad_enable(): interval=0x%03x\n", 298 __FILE__, __LINE__, sc->sc_interval)); 299 if (sc->sc_adstat != VRPIU_AD_STAT_DISABLE) 300 return EBUSY; 301 302 /* supply clock to PIU */ 303 __vrcmu_supply(CMUMSKPIU, 1); 304 305 /* set scan interval */ 306 vrpiu_write(sc, PIUSIVL_REG_W, sc->sc_interval); 307 308 s = spltty(); 309 310 /* clear interrupt status */ 311 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 312 313 /* Disable -> Standby */ 314 cnt = PIUCNT_PIUPWR | 315 PIUCNT_PIUMODE_COORDINATE | 316 PIUCNT_PADATSTART | PIUCNT_PADATSTOP; 317 vrpiu_write(sc, PIUCNT_REG_W, cnt); 318 319 /* Level2 interrupt register setting */ 320 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AD_INTR, 1); 321 322 /* save pen status, touch or release */ 323 cnt = vrpiu_read(sc, PIUCNT_REG_W); 324 325 /* 326 * Enable scan sequencer operation 327 * Standby -> WaitPenTouch 328 */ 329 cnt |= PIUCNT_PIUSEQEN; 330 vrpiu_write(sc, PIUCNT_REG_W, cnt); 331 332 sc->sc_adstat = VRPIU_AD_STAT_ENABLE; 333 334 splx(s); 335 336 return 0; 337} 338 339void 340vrpiu_ad_disable(v) 341 void *v; 342{ 343 struct vrpiu_softc *sc = v; 344 345 DPRINTF(("%s(%d): vrpiu_ad_disable()\n", __FILE__, __LINE__)); 346 347 /* Set level2 interrupt register to mask interrupts */ 348 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AD_INTR, 0); 349 350 sc->sc_adstat = VRPIU_AD_STAT_DISABLE; 351 352 if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE){ 353 /* Disable scan sequencer operation and power off */ 354 vrpiu_write(sc, PIUCNT_REG_W, 0); 355 356 /* mask clock to PIU */ 357 __vrcmu_supply(CMUMSKPIU, 1); 358 } 359} 360 361int 362vrpiu_tp_enable(v) 363 void *v; 364{ 365 struct vrpiu_softc *sc = v; 366 int s; 367 unsigned int cnt; 368 369 DPRINTF(("%s(%d): vrpiu_tp_enable(): interval=0x%03x\n", 370 __FILE__, __LINE__, sc->sc_interval)); 371 if (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE) 372 return EBUSY; 373 374 /* supply clock to PIU */ 375 __vrcmu_supply(CMUMSKPIU, 1); 376 377 /* set scan interval */ 378 vrpiu_write(sc, PIUSIVL_REG_W, sc->sc_interval); 379 380 s = spltty(); 381 382 /* clear interrupt status */ 383 vrpiu_write(sc, PIUINT_REG_W, TP_INTR); 384 385 /* Disable -> Standby */ 386 cnt = PIUCNT_PIUPWR | 387 PIUCNT_PIUMODE_COORDINATE | 388 PIUCNT_PADATSTART | PIUCNT_PADATSTOP; 389 vrpiu_write(sc, PIUCNT_REG_W, cnt); 390 391 /* Level2 interrupt register setting */ 392 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, TP_INTR, 1); 393 394 /* save pen status, touch or release */ 395 cnt = vrpiu_read(sc, PIUCNT_REG_W); 396 397 /* 398 * Enable scan sequencer operation 399 * Standby -> WaitPenTouch 400 */ 401 cnt |= PIUCNT_PIUSEQEN; 402 vrpiu_write(sc, PIUCNT_REG_W, cnt); 403 404 /* transit status DISABLE -> TOUCH or RELEASE */ 405 sc->sc_tpstat = (cnt & PIUCNT_PENSTC) ? 406 VRPIU_TP_STAT_TOUCH : VRPIU_TP_STAT_RELEASE; 407 408 splx(s); 409 410 return 0; 411} 412 413void 414vrpiu_tp_disable(v) 415 void *v; 416{ 417 struct vrpiu_softc *sc = v; 418 419 DPRINTF(("%s(%d): vrpiu_tp_disable()\n", __FILE__, __LINE__)); 420 421 /* Set level2 interrupt register to mask interrupts */ 422 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, TP_INTR, 0); 423 424 sc->sc_tpstat = VRPIU_TP_STAT_DISABLE; 425 426 if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE){ 427 /* Disable scan sequencer operation and power off */ 428 vrpiu_write(sc, PIUCNT_REG_W, 0); 429 430 /* mask clock to PIU */ 431 __vrcmu_supply(CMUMSKPIU, 1); 432 } 433} 434 435int 436vrpiu_tp_ioctl(v, cmd, data, flag, p) 437 void *v; 438 u_long cmd; 439 caddr_t data; 440 int flag; 441 struct proc *p; 442{ 443 struct vrpiu_softc *sc = v; 444 445 DPRINTF(("%s(%d): vrpiu_tp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd)); 446 447 switch (cmd) { 448 case WSMOUSEIO_GTYPE: 449 *(u_int *)data = WSMOUSE_TYPE_TPANEL; 450 break; 451 452 case WSMOUSEIO_SRES: 453 { 454 int tp_enable; 455 int ad_enable; 456 457 tp_enable = (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE); 458 ad_enable = (sc->sc_adstat != VRPIU_AD_STAT_DISABLE); 459 460 if (tp_enable) 461 vrpiu_tp_disable(sc); 462 if (ad_enable) 463 vrpiu_ad_disable(sc); 464 465 sc->sc_interval = scan_interval(*(u_int *)data); 466 DPRINTF(("%s(%d): WSMOUSEIO_SRES: *data=%d, interval=0x%03x\n", 467 __FILE__, __LINE__, *(u_int *)data, sc->sc_interval)); 468 469 if (sc->sc_interval < PIUSIVL_SCANINTVAL_MIN) 470 sc->sc_interval = PIUSIVL_SCANINTVAL_MIN; 471 472 if (PIUSIVL_SCANINTVAL_MAX < sc->sc_interval) 473 sc->sc_interval = PIUSIVL_SCANINTVAL_MAX; 474 475 if (tp_enable) 476 vrpiu_tp_enable(sc); 477 if (ad_enable) 478 vrpiu_ad_enable(sc); 479 } 480 break; 481 482 case WSMOUSEIO_SCALIBCOORDS: 483 case WSMOUSEIO_GCALIBCOORDS: 484 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p); 485 486 default: 487 return (-1); 488 } 489 return (0); 490} 491 492/* 493 * PIU AD interrupt handler. 494 */ 495void 496vrpiu_ad_intr(sc) 497 struct vrpiu_softc *sc; 498{ 499 unsigned int i; 500 unsigned int intrstat; 501 502 intrstat = vrpiu_read(sc, PIUINT_REG_W); 503 504 if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE) { 505 /* 506 * the device isn't enabled. just clear interrupt. 507 */ 508 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 509 return; 510 } 511 512 if (intrstat & PIUINT_PADADPINTR) { 513 sc->sc_battery.value[0] = (unsigned int)vrpiu_read(sc, PIUAB(0)); 514 sc->sc_battery.value[1] = (unsigned int)vrpiu_read(sc, PIUAB(1)); 515 sc->sc_battery.value[2] = (unsigned int)vrpiu_read(sc, PIUAB(2)); 516 } 517 518 if (intrstat & PIUINT_PADADPINTR) { 519 for (i = 0; i < 3; i++) { 520 if (sc->sc_battery.value[i] & PIUAB_VALID) 521 sc->sc_battery.value[i] &= PIUAB_PADDATA_MASK; 522 else 523 sc->sc_battery.value[i] = 0; 524 } 525 vrpiu_calc_powerstate(sc); 526 } 527 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 528 529 return; 530} 531/* 532 * PIU TP interrupt handler. 533 */ 534void 535vrpiu_tp_intr(sc) 536 struct vrpiu_softc *sc; 537{ 538 unsigned int cnt, i; 539 unsigned int intrstat, page; 540 int tpx0, tpx1, tpy0, tpy1; 541 int x, y, xraw, yraw; 542 543 intrstat = vrpiu_read(sc, PIUINT_REG_W); 544 545 if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE) { 546 /* 547 * the device isn't enabled. just clear interrupt. 548 */ 549 vrpiu_write(sc, PIUINT_REG_W, intrstat & TP_INTR); 550 return; 551 } 552 553 page = (intrstat & PIUINT_OVP) ? 1 : 0; 554 if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) { 555 tpx0 = vrpiu_read(sc, PIUPB(page, 0)); 556 tpx1 = vrpiu_read(sc, PIUPB(page, 1)); 557 tpy0 = vrpiu_read(sc, PIUPB(page, 2)); 558 tpy1 = vrpiu_read(sc, PIUPB(page, 3)); 559 } 560 561 if (intrstat & PIUINT_PADDLOSTINTR) { 562 page = page ? 0 : 1; 563 for (i = 0; i < 4; i++) 564 vrpiu_read(sc, PIUPB(page, i)); 565 } 566 567 cnt = vrpiu_read(sc, PIUCNT_REG_W); 568#ifdef DEBUG 569 if (vrpiu_debug) 570 vrpiu_dump_cntreg(cnt); 571#endif 572 573 /* clear interrupt status */ 574 vrpiu_write(sc, PIUINT_REG_W, intrstat & TP_INTR); 575 576#if 0 577 DPRINTF(("vrpiu_intr: OVP=%d", page)); 578 if (intrstat & PIUINT_PADCMDINTR) 579 DPRINTF((" CMD")); 580 if (intrstat & PIUINT_PADADPINTR) 581 DPRINTF((" A/D")); 582 if (intrstat & PIUINT_PADPAGE1INTR) 583 DPRINTF((" PAGE1")); 584 if (intrstat & PIUINT_PADPAGE0INTR) 585 DPRINTF((" PAGE0")); 586 if (intrstat & PIUINT_PADDLOSTINTR) 587 DPRINTF((" DLOST")); 588 if (intrstat & PIUINT_PENCHGINTR) 589 DPRINTF((" PENCHG")); 590 DPRINTF(("\n")); 591#endif 592 if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) { 593 if (!((tpx0 & PIUPB_VALID) && (tpx1 & PIUPB_VALID) && 594 (tpy0 & PIUPB_VALID) && (tpy1 & PIUPB_VALID))) { 595 printf("vrpiu: internal error, data is not valid!\n"); 596 } else { 597 tpx0 &= PIUPB_PADDATA_MASK; 598 tpx1 &= PIUPB_PADDATA_MASK; 599 tpy0 &= PIUPB_PADDATA_MASK; 600 tpy1 &= PIUPB_PADDATA_MASK; 601#define ISVALID(n, c, m) ((c) - (m) < (n) && (n) < (c) + (m)) 602 if (ISVALID(tpx0 + tpx1, 1024, 200) && 603 ISVALID(tpx0 + tpx1, 1024, 200)) { 604#if 0 605 DPRINTF(("%04x %04x %04x %04x\n", 606 tpx0, tpx1, tpy0, tpy1)); 607 DPRINTF(("%3d %3d (%4d %4d)->", tpx0, tpy0, 608 tpx0 + tpx1, tpy0 + tpy1)); 609#endif 610 xraw = tpy1 * 1024 / (tpy0 + tpy1); 611 yraw = tpx1 * 1024 / (tpx0 + tpx1); 612 DPRINTF(("%3d %3d", xraw, yraw)); 613 614 tpcalib_trans(&sc->sc_tpcalib, xraw, yraw, &x, &y); 615 616 DPRINTF(("->%4d %4d", x, y)); 617 wsmouse_input(sc->sc_wsmousedev, 618 (cnt & PIUCNT_PENSTC) ? 1 : 0, 619 x, /* x */ 620 y, /* y */ 621 0, /* z */ 622 WSMOUSE_INPUT_ABSOLUTE_X | 623 WSMOUSE_INPUT_ABSOLUTE_Y); 624 DPRINTF(("\n")); 625 } 626 } 627 } 628 629 if (cnt & PIUCNT_PENSTC) { 630 if (sc->sc_tpstat == VRPIU_TP_STAT_RELEASE) { 631 /* 632 * pen touch 633 */ 634 DPRINTF(("PEN TOUCH\n")); 635 sc->sc_tpstat = VRPIU_TP_STAT_TOUCH; 636 /* 637 * We should not report button down event while 638 * we don't know where it occur. 639 */ 640 } 641 } else { 642 if (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH) { 643 /* 644 * pen release 645 */ 646 DPRINTF(("RELEASE\n")); 647 sc->sc_tpstat = VRPIU_TP_STAT_RELEASE; 648 /* button 0 UP */ 649 wsmouse_input(sc->sc_wsmousedev, 650 0, 651 0, 0, 0, 0); 652 } 653 } 654 655 if (intrstat & PIUINT_PADDLOSTINTR) { 656 cnt |= PIUCNT_PIUSEQEN; 657 vrpiu_write(sc, PIUCNT_REG_W, cnt); 658 } 659 660 return; 661} 662 663/* 664 * PIU interrupt handler. 665 */ 666int 667vrpiu_intr(arg) 668 void *arg; 669{ 670 struct vrpiu_softc *sc = arg; 671 672 vrpiu_ad_intr(sc); 673 vrpiu_tp_intr(sc); 674 675 return 0; 676} 677 678void 679vrpiu_start_powerstate(v) 680 void *v; 681{ 682 int mask; 683 struct vrpiu_softc *sc = (struct vrpiu_softc *)v; 684 685 vrpiu_ad_enable(sc); 686 mask = vrpiu_read(sc, PIUAMSK_REG_W); 687 mask &= 0xff8f; /* XXX */ 688 vrpiu_write(sc, PIUAMSK_REG_W, mask); 689 vrpiu_write(sc, PIUASCN_REG_W, PIUACN_ADPSSTART); 690 /* 691 * restart next A/D polling 692 */ 693 callout_reset(&sc->sc_adpoll, hz*vrpiu_ad_poll_interval, 694 vrpiu_start_powerstate, sc); 695} 696 697void 698vrpiu_calc_powerstate(sc) 699 struct vrpiu_softc *sc; 700{ 701 extern void vrgiu_diff_io __P((void)); 702 vrpiu_ad_disable(sc); 703 VPRINTF(("vrpiu:AD: %d, %d, %d\n", 704 sc->sc_battery.value[0], 705 sc->sc_battery.value[1], 706 sc->sc_battery.value[2])); 707 sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval; 708#ifdef notyet 709 config_hook_call(CONFIG_HOOK_SET, 710 CONFIG_HOOK_BATTERYVAL, 711 (void *)&sc->sc_battery); 712#endif /* notyet */ 713 /* 714 * restart next A/D polling if change polling timming. 715 */ 716 if (sc->sc_battery.nextpoll != hz*vrpiu_ad_poll_interval) 717 callout_reset(&sc->sc_adpoll, sc->sc_battery.nextpoll, 718 vrpiu_start_powerstate, sc); 719 if (bootverbose) 720 vrgiu_diff_io(); 721 722} 723 724static void 725vrpiu_power(why, arg) 726 int why; 727 void *arg; 728{ 729 struct vrpiu_softc *sc = arg; 730 731 switch (why) { 732 case PWR_STANDBY: 733 case PWR_SUSPEND: 734 break; 735 case PWR_RESUME: 736 callout_reset(&sc->sc_adpoll, hz, 737 vrpiu_start_powerstate, sc); 738 break; 739 } 740} 741 742#ifdef DEBUG 743void 744vrpiu_dump_cntreg(cnt) 745 unsigned int cnt; 746{ 747 printf("%s", (cnt & PIUCNT_PENSTC) ? "Touch" : "Release"); 748 printf(" state="); 749 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_CmdScan) 750 printf("CmdScan"); 751 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_IntervalNextScan) 752 printf("IntervalNextScan"); 753 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_PenDataScan) 754 printf("PenDataScan"); 755 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_WaitPenTouch) 756 printf("WaitPenTouch"); 757 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_RFU) 758 printf("???"); 759 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_ADPortScan) 760 printf("ADPortScan"); 761 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Standby) 762 printf("Standby"); 763 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Disable) 764 printf("Disable"); 765 if (cnt & PIUCNT_PADATSTOP) 766 printf(" AutoStop"); 767 if (cnt & PIUCNT_PADATSTART) 768 printf(" AutoStart"); 769 if (cnt & PIUCNT_PADSCANSTOP) 770 printf(" Stop"); 771 if (cnt & PIUCNT_PADSCANSTART) 772 printf(" Start"); 773 if (cnt & PIUCNT_PADSCANTYPE) 774 printf(" ScanPressure"); 775 if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_ADCONVERTER) 776 printf(" A/D"); 777 if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_COORDINATE) 778 printf(" Coordinate"); 779 if (cnt & PIUCNT_PIUSEQEN) 780 printf(" SeqEn"); 781 if ((cnt & PIUCNT_PIUPWR) == 0) 782 printf(" PowerOff"); 783 if ((cnt & PIUCNT_PADRST) == 0) 784 printf(" Reset"); 785 printf("\n"); 786} 787#endif 788