vrpiu.c revision 1.11
1/* $NetBSD: vrpiu.c,v 1.11 2001/02/22 18:38:05 uch 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_700A, 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 { NULL, /* samples got on my MC-R500 */ 216 { 0, 0, 639, 239, 217 5, 218 { { 502, 486, 320, 120 }, 219 { 55, 109, 0, 0 }, 220 { 54, 913, 0, 239 }, 221 { 973, 924, 639, 239 }, 222 { 975, 123, 639, 0 } } } }, 223 }; 224 for (i = 0; ; i++) { 225 if (calibrations[i].mask == NULL 226 || platid_match(&platid, calibrations[i].mask)) 227 break; 228 } 229 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 230 (caddr_t)&calibrations[i].coords, 0, 0); 231 } 232#endif 233 234 /* install interrupt handler and enable interrupt */ 235 if (!(sc->sc_handler = 236 vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY, 237 vrpiu_intr, sc))) { 238 printf (": can't map interrupt line.\n"); 239 return; 240 } 241 242 /* mask level2 interrupt, stop scan sequencer and mask clock to piu */ 243 vrpiu_tp_disable(sc); 244 245 printf("\n"); 246 247 wsmaa.accessops = &vrpiu_accessops; 248 wsmaa.accesscookie = sc; 249 250 /* 251 * attach the wsmouse 252 */ 253 sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint); 254 255 /* 256 * power management events 257 */ 258 sc->sc_power_hook = powerhook_establish(vrpiu_power, sc); 259 260 /* 261 * init A/D port polling. 262 */ 263 sc->sc_battery.n_values = 3; 264 sc->sc_battery.value[0] = -1; 265 sc->sc_battery.value[1] = -1; 266 sc->sc_battery.value[2] = -1; 267 sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval; 268 callout_init(&sc->sc_adpoll); 269 callout_reset(&sc->sc_adpoll, hz, vrpiu_start_powerstate, sc); 270} 271 272/* 273 * calculate interval value 274 * input: WSMOUSE_RES_MIN - WSMOUSE_RES_MAX 275 * output: value for PIUSIVL_REG 276 */ 277static u_int 278scan_interval(u_int data) 279{ 280 int scale; 281 282 if (data < WSMOUSE_RES_MIN) 283 data = WSMOUSE_RES_MIN; 284 285 if (WSMOUSE_RES_MAX < data) 286 data = WSMOUSE_RES_MAX; 287 288 scale = WSMOUSE_RES_MAX - WSMOUSE_RES_MIN; 289 data += WSMOUSE_RES_MIN; 290 291 return PIUSIVL_SCANINTVAL_MIN + 292 (PIUSIVL_SCANINTVAL_MAX - PIUSIVL_SCANINTVAL_MIN) * 293 (scale - data) / scale; 294} 295 296int 297vrpiu_ad_enable(v) 298 void *v; 299{ 300 struct vrpiu_softc *sc = v; 301 int s; 302 unsigned int cnt; 303 304 DPRINTF(("%s(%d): vrpiu_ad_enable(): interval=0x%03x\n", 305 __FILE__, __LINE__, sc->sc_interval)); 306 if (sc->sc_adstat != VRPIU_AD_STAT_DISABLE) 307 return EBUSY; 308 309 /* supply clock to PIU */ 310 __vrcmu_supply(CMUMSKPIU, 1); 311 312 /* set scan interval */ 313 vrpiu_write(sc, PIUSIVL_REG_W, sc->sc_interval); 314 315 s = spltty(); 316 317 /* clear interrupt status */ 318 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 319 320 /* Disable -> Standby */ 321 cnt = PIUCNT_PIUPWR | 322 PIUCNT_PIUMODE_COORDINATE | 323 PIUCNT_PADATSTART | PIUCNT_PADATSTOP; 324 vrpiu_write(sc, PIUCNT_REG_W, cnt); 325 326 /* Level2 interrupt register setting */ 327 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AD_INTR, 1); 328 329 /* save pen status, touch or release */ 330 cnt = vrpiu_read(sc, PIUCNT_REG_W); 331 332 /* 333 * Enable scan sequencer operation 334 * Standby -> WaitPenTouch 335 */ 336 cnt |= PIUCNT_PIUSEQEN; 337 vrpiu_write(sc, PIUCNT_REG_W, cnt); 338 339 sc->sc_adstat = VRPIU_AD_STAT_ENABLE; 340 341 splx(s); 342 343 return 0; 344} 345 346void 347vrpiu_ad_disable(v) 348 void *v; 349{ 350 struct vrpiu_softc *sc = v; 351 352 DPRINTF(("%s(%d): vrpiu_ad_disable()\n", __FILE__, __LINE__)); 353 354 /* Set level2 interrupt register to mask interrupts */ 355 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AD_INTR, 0); 356 357 sc->sc_adstat = VRPIU_AD_STAT_DISABLE; 358 359 if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE){ 360 /* Disable scan sequencer operation and power off */ 361 vrpiu_write(sc, PIUCNT_REG_W, 0); 362 363 /* mask clock to PIU */ 364 __vrcmu_supply(CMUMSKPIU, 1); 365 } 366} 367 368int 369vrpiu_tp_enable(v) 370 void *v; 371{ 372 struct vrpiu_softc *sc = v; 373 int s; 374 unsigned int cnt; 375 376 DPRINTF(("%s(%d): vrpiu_tp_enable(): interval=0x%03x\n", 377 __FILE__, __LINE__, sc->sc_interval)); 378 if (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE) 379 return EBUSY; 380 381 /* supply clock to PIU */ 382 __vrcmu_supply(CMUMSKPIU, 1); 383 384 /* set scan interval */ 385 vrpiu_write(sc, PIUSIVL_REG_W, sc->sc_interval); 386 387 s = spltty(); 388 389 /* clear interrupt status */ 390 vrpiu_write(sc, PIUINT_REG_W, TP_INTR); 391 392 /* Disable -> Standby */ 393 cnt = PIUCNT_PIUPWR | 394 PIUCNT_PIUMODE_COORDINATE | 395 PIUCNT_PADATSTART | PIUCNT_PADATSTOP; 396 vrpiu_write(sc, PIUCNT_REG_W, cnt); 397 398 /* Level2 interrupt register setting */ 399 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, TP_INTR, 1); 400 401 /* save pen status, touch or release */ 402 cnt = vrpiu_read(sc, PIUCNT_REG_W); 403 404 /* 405 * Enable scan sequencer operation 406 * Standby -> WaitPenTouch 407 */ 408 cnt |= PIUCNT_PIUSEQEN; 409 vrpiu_write(sc, PIUCNT_REG_W, cnt); 410 411 /* transit status DISABLE -> TOUCH or RELEASE */ 412 sc->sc_tpstat = (cnt & PIUCNT_PENSTC) ? 413 VRPIU_TP_STAT_TOUCH : VRPIU_TP_STAT_RELEASE; 414 415 splx(s); 416 417 return 0; 418} 419 420void 421vrpiu_tp_disable(v) 422 void *v; 423{ 424 struct vrpiu_softc *sc = v; 425 426 DPRINTF(("%s(%d): vrpiu_tp_disable()\n", __FILE__, __LINE__)); 427 428 /* Set level2 interrupt register to mask interrupts */ 429 vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, TP_INTR, 0); 430 431 sc->sc_tpstat = VRPIU_TP_STAT_DISABLE; 432 433 if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE){ 434 /* Disable scan sequencer operation and power off */ 435 vrpiu_write(sc, PIUCNT_REG_W, 0); 436 437 /* mask clock to PIU */ 438 __vrcmu_supply(CMUMSKPIU, 1); 439 } 440} 441 442int 443vrpiu_tp_ioctl(v, cmd, data, flag, p) 444 void *v; 445 u_long cmd; 446 caddr_t data; 447 int flag; 448 struct proc *p; 449{ 450 struct vrpiu_softc *sc = v; 451 452 DPRINTF(("%s(%d): vrpiu_tp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd)); 453 454 switch (cmd) { 455 case WSMOUSEIO_GTYPE: 456 *(u_int *)data = WSMOUSE_TYPE_TPANEL; 457 break; 458 459 case WSMOUSEIO_SRES: 460 { 461 int tp_enable; 462 int ad_enable; 463 464 tp_enable = (sc->sc_tpstat != VRPIU_TP_STAT_DISABLE); 465 ad_enable = (sc->sc_adstat != VRPIU_AD_STAT_DISABLE); 466 467 if (tp_enable) 468 vrpiu_tp_disable(sc); 469 if (ad_enable) 470 vrpiu_ad_disable(sc); 471 472 sc->sc_interval = scan_interval(*(u_int *)data); 473 DPRINTF(("%s(%d): WSMOUSEIO_SRES: *data=%d, interval=0x%03x\n", 474 __FILE__, __LINE__, *(u_int *)data, sc->sc_interval)); 475 476 if (sc->sc_interval < PIUSIVL_SCANINTVAL_MIN) 477 sc->sc_interval = PIUSIVL_SCANINTVAL_MIN; 478 479 if (PIUSIVL_SCANINTVAL_MAX < sc->sc_interval) 480 sc->sc_interval = PIUSIVL_SCANINTVAL_MAX; 481 482 if (tp_enable) 483 vrpiu_tp_enable(sc); 484 if (ad_enable) 485 vrpiu_ad_enable(sc); 486 } 487 break; 488 489 case WSMOUSEIO_SCALIBCOORDS: 490 case WSMOUSEIO_GCALIBCOORDS: 491 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p); 492 493 default: 494 return (-1); 495 } 496 return (0); 497} 498 499/* 500 * PIU AD interrupt handler. 501 */ 502void 503vrpiu_ad_intr(sc) 504 struct vrpiu_softc *sc; 505{ 506 unsigned int i; 507 unsigned int intrstat; 508 509 intrstat = vrpiu_read(sc, PIUINT_REG_W); 510 511 if (sc->sc_adstat == VRPIU_AD_STAT_DISABLE) { 512 /* 513 * the device isn't enabled. just clear interrupt. 514 */ 515 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 516 return; 517 } 518 519 if (intrstat & PIUINT_PADADPINTR) { 520 sc->sc_battery.value[0] = (unsigned int)vrpiu_read(sc, PIUAB(0)); 521 sc->sc_battery.value[1] = (unsigned int)vrpiu_read(sc, PIUAB(1)); 522 sc->sc_battery.value[2] = (unsigned int)vrpiu_read(sc, PIUAB(2)); 523 } 524 525 if (intrstat & PIUINT_PADADPINTR) { 526 for (i = 0; i < 3; i++) { 527 if (sc->sc_battery.value[i] & PIUAB_VALID) 528 sc->sc_battery.value[i] &= PIUAB_PADDATA_MASK; 529 else 530 sc->sc_battery.value[i] = 0; 531 } 532 vrpiu_calc_powerstate(sc); 533 } 534 vrpiu_write(sc, PIUINT_REG_W, AD_INTR); 535 536 return; 537} 538/* 539 * PIU TP interrupt handler. 540 */ 541void 542vrpiu_tp_intr(sc) 543 struct vrpiu_softc *sc; 544{ 545 unsigned int cnt, i; 546 unsigned int intrstat, page; 547 int tpx0, tpx1, tpy0, tpy1; 548 int x, y, xraw, yraw; 549 550 intrstat = vrpiu_read(sc, PIUINT_REG_W); 551 552 if (sc->sc_tpstat == VRPIU_TP_STAT_DISABLE) { 553 /* 554 * the device isn't enabled. just clear interrupt. 555 */ 556 vrpiu_write(sc, PIUINT_REG_W, intrstat & TP_INTR); 557 return; 558 } 559 560 page = (intrstat & PIUINT_OVP) ? 1 : 0; 561 if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) { 562 tpx0 = vrpiu_read(sc, PIUPB(page, 0)); 563 tpx1 = vrpiu_read(sc, PIUPB(page, 1)); 564 tpy0 = vrpiu_read(sc, PIUPB(page, 2)); 565 tpy1 = vrpiu_read(sc, PIUPB(page, 3)); 566 } 567 568 if (intrstat & PIUINT_PADDLOSTINTR) { 569 page = page ? 0 : 1; 570 for (i = 0; i < 4; i++) 571 vrpiu_read(sc, PIUPB(page, i)); 572 } 573 574 cnt = vrpiu_read(sc, PIUCNT_REG_W); 575#ifdef DEBUG 576 if (vrpiu_debug) 577 vrpiu_dump_cntreg(cnt); 578#endif 579 580 /* clear interrupt status */ 581 vrpiu_write(sc, PIUINT_REG_W, intrstat & TP_INTR); 582 583#if 0 584 DPRINTF(("vrpiu_intr: OVP=%d", page)); 585 if (intrstat & PIUINT_PADCMDINTR) 586 DPRINTF((" CMD")); 587 if (intrstat & PIUINT_PADADPINTR) 588 DPRINTF((" A/D")); 589 if (intrstat & PIUINT_PADPAGE1INTR) 590 DPRINTF((" PAGE1")); 591 if (intrstat & PIUINT_PADPAGE0INTR) 592 DPRINTF((" PAGE0")); 593 if (intrstat & PIUINT_PADDLOSTINTR) 594 DPRINTF((" DLOST")); 595 if (intrstat & PIUINT_PENCHGINTR) 596 DPRINTF((" PENCHG")); 597 DPRINTF(("\n")); 598#endif 599 if (intrstat & (PIUINT_PADPAGE0INTR | PIUINT_PADPAGE1INTR)) { 600 /* 601 * just ignore scan data if status isn't Touch. 602 */ 603 if (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH) { 604 /* reset tp scan timeout */ 605 callout_reset(&sc->sc_tptimeout, VRPIU_TP_SCAN_TIMEOUT, 606 vrpiu_tp_timeout, sc); 607 608 if (!((tpx0 & PIUPB_VALID) && (tpx1 & PIUPB_VALID) && 609 (tpy0 & PIUPB_VALID) && (tpy1 & PIUPB_VALID))) { 610 printf("vrpiu: internal error, data is not valid!\n"); 611 } else { 612 tpx0 &= PIUPB_PADDATA_MASK; 613 tpx1 &= PIUPB_PADDATA_MASK; 614 tpy0 &= PIUPB_PADDATA_MASK; 615 tpy1 &= PIUPB_PADDATA_MASK; 616#define ISVALID(n, c, m) ((c) - (m) < (n) && (n) < (c) + (m)) 617 if (ISVALID(tpx0 + tpx1, 1024, 200) && 618 ISVALID(tpy0 + tpy1, 1024, 200)) { 619#if 0 620 DPRINTF(("%04x %04x %04x %04x\n", 621 tpx0, tpx1, tpy0, tpy1)); 622 DPRINTF(("%3d %3d (%4d %4d)->", tpx0, tpy0, 623 tpx0 + tpx1, tpy0 + tpy1)); 624#endif 625 xraw = tpy1 * 1024 / (tpy0 + tpy1); 626 yraw = tpx1 * 1024 / (tpx0 + tpx1); 627 DPRINTF(("%3d %3d", xraw, yraw)); 628 629 tpcalib_trans(&sc->sc_tpcalib, xraw, yraw, &x, &y); 630 631 DPRINTF(("->%4d %4d", x, y)); 632 wsmouse_input(sc->sc_wsmousedev, 633 1, /* button 0 down */ 634 x, /* x */ 635 y, /* y */ 636 0, /* z */ 637 WSMOUSE_INPUT_ABSOLUTE_X | 638 WSMOUSE_INPUT_ABSOLUTE_Y); 639 DPRINTF(("\n")); 640 } 641 } 642 } 643 } 644 645 if (cnt & PIUCNT_PENSTC) { 646 if (sc->sc_tpstat == VRPIU_TP_STAT_RELEASE) { 647 /* 648 * pen touch 649 */ 650 DPRINTF(("PEN TOUCH\n")); 651 sc->sc_tpstat = VRPIU_TP_STAT_TOUCH; 652 /* 653 * We should not report button down event while 654 * we don't know where it occur. 655 */ 656 657 /* set tp scan timeout */ 658 callout_reset(&sc->sc_tptimeout, VRPIU_TP_SCAN_TIMEOUT, 659 vrpiu_tp_timeout, sc); 660 } 661 } else { 662 vrpiu_tp_up(sc); 663 } 664 665 if (intrstat & PIUINT_PADDLOSTINTR) { 666 cnt |= PIUCNT_PIUSEQEN; 667 vrpiu_write(sc, PIUCNT_REG_W, cnt); 668 } 669 670 return; 671} 672 673void 674vrpiu_tp_up(sc) 675 struct vrpiu_softc *sc; 676{ 677 if (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH) { 678 /* 679 * pen release 680 */ 681 DPRINTF(("RELEASE\n")); 682 sc->sc_tpstat = VRPIU_TP_STAT_RELEASE; 683 684 /* clear tp scan timeout */ 685 callout_stop(&sc->sc_tptimeout); 686 687 /* button 0 UP */ 688 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0); 689 } 690} 691 692/* touch panel timeout handler */ 693void 694vrpiu_tp_timeout(v) 695 void *v; 696{ 697 struct vrpiu_softc *sc = (struct vrpiu_softc *)v; 698 699#ifdef VRPIUDEBUG 700 { 701 unsigned int cnt = vrpiu_read(sc, PIUCNT_REG_W); 702 DPRINTF(("TIMEOUT: stat=%s reg=%s\n", 703 (sc->sc_tpstat == VRPIU_TP_STAT_TOUCH)?"touch":"release", 704 (cnt & PIUCNT_PENSTC)?"touch":"release")); 705 } 706#endif 707 vrpiu_tp_up(sc); 708} 709 710/* 711 * PIU interrupt handler. 712 */ 713int 714vrpiu_intr(arg) 715 void *arg; 716{ 717 struct vrpiu_softc *sc = arg; 718 719 vrpiu_ad_intr(sc); 720 vrpiu_tp_intr(sc); 721 722 return 0; 723} 724 725void 726vrpiu_start_powerstate(v) 727 void *v; 728{ 729 int mask; 730 struct vrpiu_softc *sc = (struct vrpiu_softc *)v; 731 732 vrpiu_ad_enable(sc); 733 mask = vrpiu_read(sc, PIUAMSK_REG_W); 734 mask &= 0xff8f; /* XXX */ 735 vrpiu_write(sc, PIUAMSK_REG_W, mask); 736 vrpiu_write(sc, PIUASCN_REG_W, PIUACN_ADPSSTART); 737 /* 738 * restart next A/D polling 739 */ 740 callout_reset(&sc->sc_adpoll, hz*vrpiu_ad_poll_interval, 741 vrpiu_start_powerstate, sc); 742} 743 744void 745vrpiu_calc_powerstate(sc) 746 struct vrpiu_softc *sc; 747{ 748 extern void vrgiu_diff_io __P((void)); 749 vrpiu_ad_disable(sc); 750 VPRINTF(("vrpiu:AD: %d, %d, %d\n", 751 sc->sc_battery.value[0], 752 sc->sc_battery.value[1], 753 sc->sc_battery.value[2])); 754 sc->sc_battery.nextpoll = hz*vrpiu_ad_poll_interval; 755#ifdef notyet 756 config_hook_call(CONFIG_HOOK_SET, 757 CONFIG_HOOK_BATTERYVAL, 758 (void *)&sc->sc_battery); 759#endif /* notyet */ 760 /* 761 * restart next A/D polling if change polling timming. 762 */ 763 if (sc->sc_battery.nextpoll != hz*vrpiu_ad_poll_interval) 764 callout_reset(&sc->sc_adpoll, sc->sc_battery.nextpoll, 765 vrpiu_start_powerstate, sc); 766 if (bootverbose) 767 vrgiu_diff_io(); 768 769} 770 771static void 772vrpiu_power(why, arg) 773 int why; 774 void *arg; 775{ 776 struct vrpiu_softc *sc = arg; 777 778 switch (why) { 779 case PWR_STANDBY: 780 case PWR_SUSPEND: 781 break; 782 case PWR_RESUME: 783 callout_reset(&sc->sc_adpoll, hz, 784 vrpiu_start_powerstate, sc); 785 break; 786 } 787} 788 789#ifdef DEBUG 790void 791vrpiu_dump_cntreg(cnt) 792 unsigned int cnt; 793{ 794 printf("%s", (cnt & PIUCNT_PENSTC) ? "Touch" : "Release"); 795 printf(" state="); 796 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_CmdScan) 797 printf("CmdScan"); 798 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_IntervalNextScan) 799 printf("IntervalNextScan"); 800 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_PenDataScan) 801 printf("PenDataScan"); 802 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_WaitPenTouch) 803 printf("WaitPenTouch"); 804 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_RFU) 805 printf("???"); 806 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_ADPortScan) 807 printf("ADPortScan"); 808 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Standby) 809 printf("Standby"); 810 if ((cnt & PIUCNT_PADSTATE_MASK) == PIUCNT_PADSTATE_Disable) 811 printf("Disable"); 812 if (cnt & PIUCNT_PADATSTOP) 813 printf(" AutoStop"); 814 if (cnt & PIUCNT_PADATSTART) 815 printf(" AutoStart"); 816 if (cnt & PIUCNT_PADSCANSTOP) 817 printf(" Stop"); 818 if (cnt & PIUCNT_PADSCANSTART) 819 printf(" Start"); 820 if (cnt & PIUCNT_PADSCANTYPE) 821 printf(" ScanPressure"); 822 if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_ADCONVERTER) 823 printf(" A/D"); 824 if ((cnt & PIUCNT_PIUMODE_MASK) == PIUCNT_PIUMODE_COORDINATE) 825 printf(" Coordinate"); 826 if (cnt & PIUCNT_PIUSEQEN) 827 printf(" SeqEn"); 828 if ((cnt & PIUCNT_PIUPWR) == 0) 829 printf(" PowerOff"); 830 if ((cnt & PIUCNT_PADRST) == 0) 831 printf(" Reset"); 832 printf("\n"); 833} 834#endif 835