1 /* $NetBSD: ucbtp.c,v 1.4 2000/05/22 17:17:45 uch Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 UCHIYAMA Yasushi. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end 31 * Touch panel part. 32 */ 33 #define UCBTPDEBUG 34 35 #include "opt_tx39_debug.h" 36 #include "opt_use_poll.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/device.h> 41 42 #include <machine/bus.h> 43 #include <machine/intr.h> 44 #include <machine/bootinfo.h> /* bootinfo */ 45 46 #include <dev/wscons/wsconsio.h> 47 #include <dev/wscons/wsmousevar.h> 48 49 #include <hpcmips/dev/tpcalibvar.h> 50 51 #include <hpcmips/tx/tx39var.h> 52 #include <hpcmips/tx/tx39sibvar.h> 53 #include <hpcmips/tx/tx39sibreg.h> 54 #include <hpcmips/tx/tx39icureg.h> 55 56 #include <hpcmips/dev/ucb1200var.h> 57 #include <hpcmips/dev/ucb1200reg.h> 58 59 #include <hpcmips/tx/txsnd.h> 60 #include <hpcmips/dev/video_subr.h> /* debug */ 61 62 #ifdef UCBTPDEBUG 63 int ucbtp_debug = 0; 64 #define DPRINTF(arg) if (ucbtp_debug) printf arg; 65 #define DPRINTFN(n, arg) if (ucbtp_debug > (n)) printf arg; 66 #else 67 #define DPRINTF(arg) 68 #define DPRINTFN(n, arg) 69 #endif 70 71 enum ucbts_stat { 72 UCBTS_STAT_DISABLE, 73 UCBTS_STAT_RELEASE, 74 UCBTS_STAT_TOUCH, 75 UCBTS_STAT_DRAG, 76 }; 77 78 #define UCBTS_POSX 1 79 #define UCBTS_POSY 2 80 #define UCBTS_PRESS 3 81 82 #define UCBTS_PRESS_THRESHOLD 80 83 #define UCBTS_TAP_THRESHOLD 5 84 85 enum ucbadc_state { 86 /* 0 */ UCBADC_IDLE, 87 /* 1 */ UCBADC_ADC_INIT, 88 /* 2 */ UCBADC_ADC_FINI, 89 /* 3 */ UCBADC_MEASUMENT_INIT, 90 /* 4 */ UCBADC_MEASUMENT_FINI, 91 /* 5 */ UCBADC_ADC_ENABLE, 92 /* 6 */ UCBADC_ADC_START0, 93 /* 7 */ UCBADC_ADC_START1, 94 /* 8 */ UCBADC_ADC_DATAREAD, 95 /* 9 */ UCBADC_ADC_DATAREAD_WAIT, 96 /*10 */ UCBADC_ADC_DISABLE, 97 /*11 */ UCBADC_ADC_INTRMODE, 98 /*12 */ UCBADC_ADC_INPUT, 99 /*13 */ UCBADC_INTR_ACK0, 100 /*14 */ UCBADC_INTR_ACK1, 101 /*15 */ UCBADC_INTR_ACK2, 102 /*16 */ UCBADC_REGREAD, 103 /*17 */ UCBADC_REGWRITE 104 }; 105 106 struct ucbtp_softc { 107 struct device sc_dev; 108 struct device *sc_sib; /* parent (TX39 SIB module) */ 109 struct device *sc_ucb; /* parent (UCB1200 module) */ 110 tx_chipset_tag_t sc_tc; 111 112 enum ucbts_stat sc_stat; 113 int sc_polling; 114 int sc_polling_finish; 115 void *sc_pollh; 116 117 struct tpcalib_softc sc_tpcalib; 118 int sc_calibrated; 119 120 /* measurement value */ 121 int sc_x, sc_y, sc_p; 122 int sc_ox, sc_oy; 123 int sc_xy_reverse; /* some platform pin connect interchanged */ 124 125 /* 126 * touch panel state machine 127 */ 128 void *sm_ih; /* TX39 SIB subframe 0 interrupt handler */ 129 130 int sm_addr; /* UCB1200 register address */ 131 u_int32_t sm_reg; /* UCB1200 register data & TX39 SIB header */ 132 int sm_tmpreg; 133 #define UCBADC_RETRY_DEFAULT 200 134 int sm_retry; /* retry counter */ 135 136 enum ucbadc_state sm_state; 137 int sm_measurement; /* X, Y, Pressure */ 138 #define UCBADC_MEASUREMENT_X 0 139 #define UCBADC_MEASUREMENT_Y 1 140 #define UCBADC_MEASUREMENT_PRESSURE 2 141 int sm_returnstate; 142 143 int sm_read_state, sm_write_state; 144 int sm_writing; /* writing state flag */ 145 u_int32_t sm_write_val; /* temporary buffer */ 146 147 int sm_rw_retry; /* retry counter for r/w */ 148 149 /* wsmouse */ 150 struct device *sc_wsmousedev; 151 }; 152 153 int ucbtp_match __P((struct device*, struct cfdata*, void*)); 154 void ucbtp_attach __P((struct device*, struct device*, void*)); 155 156 int ucbtp_sibintr __P((void*)); 157 int ucbtp_poll __P((void*)); 158 int ucbtp_adc_async __P((void*)); 159 int ucbtp_input __P((struct ucbtp_softc*)); 160 int ucbtp_busy __P((void*)); 161 162 int ucbtp_enable __P((void*)); 163 int ucbtp_ioctl __P((void*, u_long, caddr_t, int, struct proc*)); 164 void ucbtp_disable __P((void*)); 165 166 struct cfattach ucbtp_ca = { 167 sizeof(struct ucbtp_softc), ucbtp_match, ucbtp_attach 168 }; 169 170 const struct wsmouse_accessops ucbtp_accessops = { 171 ucbtp_enable, 172 ucbtp_ioctl, 173 ucbtp_disable, 174 }; 175 176 /* 177 * XXX currently no calibration method. this is temporary hack. 178 */ 179 #include <machine/platid.h> 180 181 struct wsmouse_calibcoords *calibration_sample_lookup __P((void)); 182 int ucbtp_calibration __P((struct ucbtp_softc*)); 183 184 struct calibration_sample_table { 185 platid_t cst_platform; 186 struct wsmouse_calibcoords cst_sample; 187 } calibration_sample_table[] = { 188 {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_8XX}}, /* uch machine */ 189 { 0, 0, 639, 239, 5, 190 {{ 507, 510, 320, 120 }, 191 { 898, 757, 40, 40 }, 192 { 900, 255, 40, 200 }, 193 { 109, 249, 600, 200 }, 194 { 110, 753, 600, 40 }}}}, 195 196 {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_2010}}, /* uch machine */ 197 { 0, 0, 639, 239, 5, 198 {{ 506, 487, 320, 120 }, 199 { 880, 250, 40, 40 }, 200 { 880, 718, 40, 200 }, 201 { 140, 726, 600, 200 }, 202 { 137, 250, 600, 40 }}}}, 203 204 {{{PLATID_WILD, PLATID_MACH_SHARP_MOBILON_HC4100}}, /* uch machine */ 205 { 0, 0, 639, 239, 5, 206 {{ 497, 501, 320, 120 }, 207 { 752, 893, 40, 40 }, 208 { 242, 891, 40, 200 }, 209 { 241, 115, 600, 200 }, 210 { 747, 101, 600, 40 }}}}, 211 212 {{{PLATID_WILD, PLATID_MACH_SHARP_TELIOS_HCAJ1}}, /* uch machine */ 213 { 0, 0, 799, 479, 5, 214 {{ 850, 150, 1, 1 }, 215 { 850, 880, 1, 479 }, 216 { 850, 880, 1, 479 }, 217 { 85, 880, 799, 479 }, 218 { 85, 150, 799, 1 }}}}, 219 220 {{{PLATID_UNKNOWN, PLATID_UNKNOWN}}, 221 { 0, 0, 639, 239, 5, 222 {{0, 0, 0, 0}, 223 {0, 0, 0, 0}, 224 {0, 0, 0, 0}, 225 {0, 0, 0, 0}, 226 {0, 0, 0, 0}}}}, 227 }; 228 229 struct wsmouse_calibcoords * 230 calibration_sample_lookup() 231 { 232 struct calibration_sample_table *tab; 233 platid_mask_t mask; 234 235 for (tab = calibration_sample_table; 236 tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) { 237 238 mask = PLATID_DEREF(&tab->cst_platform); 239 240 if (platid_match(&platid, &mask)) { 241 return (&tab->cst_sample); 242 } 243 } 244 245 return (0); 246 } 247 248 int 249 ucbtp_calibration(sc) 250 struct ucbtp_softc *sc; 251 { 252 struct wsmouse_calibcoords *cs; 253 254 if (sc->sc_tc->tc_videot) 255 video_calibration_pattern(sc->sc_tc->tc_videot); /* debug */ 256 257 tpcalib_init(&sc->sc_tpcalib); 258 259 if (!(cs = calibration_sample_lookup())) { 260 DPRINTF(("no calibration data")); 261 return (1); 262 } 263 264 sc->sc_calibrated = 265 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 266 (caddr_t)cs, 0, 0) == 0 ? 1 : 0; 267 268 if (!sc->sc_calibrated) 269 printf("not "); 270 printf("calibrated"); 271 272 return (0); 273 } 274 275 int 276 ucbtp_match(parent, cf, aux) 277 struct device *parent; 278 struct cfdata *cf; 279 void *aux; 280 { 281 return (1); 282 } 283 284 void 285 ucbtp_attach(parent, self, aux) 286 struct device *parent; 287 struct device *self; 288 void *aux; 289 { 290 struct ucb1200_attach_args *ucba = aux; 291 struct ucbtp_softc *sc = (void*)self; 292 struct wsmousedev_attach_args wsmaa; 293 tx_chipset_tag_t tc; 294 295 tc = sc->sc_tc = ucba->ucba_tc; 296 sc->sc_sib = ucba->ucba_sib; 297 sc->sc_ucb = ucba->ucba_ucb; 298 299 printf(": "); 300 /* touch panel interrupt */ 301 tx_intr_establish(tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT), 302 IST_EDGE, IPL_TTY, ucbtp_sibintr, sc); 303 304 /* attempt to calibrate touch panel */ 305 ucbtp_calibration(sc); 306 #ifdef TX392X /* hack for Telios HC-VJ1C */ 307 sc->sc_xy_reverse = 1; 308 #endif 309 310 printf("\n"); 311 312 wsmaa.accessops = &ucbtp_accessops; 313 wsmaa.accesscookie = sc; 314 315 ucb1200_state_install(parent, ucbtp_busy, self, UCB1200_TP_MODULE); 316 317 /* 318 * attach the wsmouse 319 */ 320 sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint); 321 } 322 323 int 324 ucbtp_busy(arg) 325 void *arg; 326 { 327 struct ucbtp_softc *sc = arg; 328 329 return (sc->sm_state != UCBADC_IDLE); 330 } 331 332 int 333 ucbtp_poll(arg) 334 void *arg; 335 { 336 struct ucbtp_softc *sc = arg; 337 338 if (!ucb1200_state_idle(sc->sc_ucb)) /* subframe0 busy */ 339 return (POLL_CONT); 340 341 if (sc->sc_polling_finish) { 342 sc->sc_polling_finish = 0; 343 return (POLL_END); 344 } 345 346 /* execute A-D converter */ 347 sc->sm_state = UCBADC_ADC_INIT; 348 ucbtp_adc_async(sc); 349 350 return (POLL_CONT); 351 } 352 353 int 354 ucbtp_sibintr(arg) 355 void *arg; 356 { 357 struct ucbtp_softc *sc = arg; 358 359 sc->sc_stat = UCBTS_STAT_TOUCH; 360 361 /* click! */ 362 tx_sound_click(sc->sc_tc); 363 364 /* invoke touch panel polling */ 365 if (!sc->sc_polling) { 366 sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE, 367 ucbtp_poll, sc); 368 if (!sc->sc_pollh) { 369 printf("%s: can't poll\n", sc->sc_dev.dv_xname); 370 } 371 } 372 373 /* don't acknoledge interrupt until polling finish */ 374 375 return (0); 376 } 377 378 #define REGWRITE(addr, reg, ret) ( \ 379 sc->sm_addr = (addr), \ 380 sc->sm_reg = (reg), \ 381 sc->sm_returnstate = (ret), \ 382 sc->sm_state = UCBADC_REGWRITE) 383 #define REGREAD(addr, ret) ( \ 384 sc->sm_addr = (addr), \ 385 sc->sm_returnstate = (ret), \ 386 sc->sm_state = UCBADC_REGREAD) 387 388 int 389 ucbtp_adc_async(arg) 390 void *arg; 391 { 392 struct ucbtp_softc *sc = arg; 393 tx_chipset_tag_t tc = sc->sc_tc; 394 txreg_t reg; 395 u_int16_t reg16; 396 397 DPRINTFN(9, ("state: %d\n", sc->sm_state)); 398 399 switch (sc->sm_state) { 400 default: 401 panic("ucbtp_adc: invalid state %d", sc->sm_state); 402 /* NOTREACHED */ 403 break; 404 405 case UCBADC_IDLE: 406 /* nothing to do */ 407 break; 408 409 case UCBADC_ADC_INIT: 410 sc->sc_polling++; 411 sc->sc_stat = UCBTS_STAT_DRAG; 412 /* enable heart beat of this state machine */ 413 sc->sm_ih = tx_intr_establish( 414 tc, 415 MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT), 416 IST_EDGE, IPL_TTY, ucbtp_adc_async, sc); 417 418 sc->sm_state = UCBADC_MEASUMENT_INIT; 419 break; 420 421 case UCBADC_ADC_FINI: 422 /* disable heart beat of this state machine */ 423 tx_intr_disestablish(tc, sc->sm_ih); 424 sc->sm_state = UCBADC_IDLE; 425 break; 426 427 case UCBADC_MEASUMENT_INIT: 428 switch (sc->sm_measurement) { 429 default: 430 panic("unknown measurement spec."); 431 /* NOTREACHED */ 432 break; 433 case UCBADC_MEASUREMENT_X: 434 REGWRITE(UCB1200_TSCTRL_REG, 435 UCB1200_TSCTRL_XPOSITION, 436 UCBADC_ADC_ENABLE); 437 break; 438 case UCBADC_MEASUREMENT_Y: 439 REGWRITE(UCB1200_TSCTRL_REG, 440 UCB1200_TSCTRL_YPOSITION, 441 UCBADC_ADC_ENABLE); 442 break; 443 case UCBADC_MEASUREMENT_PRESSURE: 444 REGWRITE(UCB1200_TSCTRL_REG, 445 UCB1200_TSCTRL_PRESSURE, 446 UCBADC_ADC_ENABLE); 447 break; 448 } 449 break; 450 451 case UCBADC_MEASUMENT_FINI: 452 switch (sc->sm_measurement) { 453 case UCBADC_MEASUREMENT_X: 454 sc->sm_measurement = UCBADC_MEASUREMENT_Y; 455 sc->sm_state = UCBADC_MEASUMENT_INIT; 456 break; 457 case UCBADC_MEASUREMENT_Y: 458 sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE; 459 sc->sm_state = UCBADC_MEASUMENT_INIT; 460 break; 461 case UCBADC_MEASUREMENT_PRESSURE: 462 sc->sm_measurement = UCBADC_MEASUREMENT_X; 463 /* measument complete. pass down to wsmouse_input */ 464 sc->sm_state = UCBADC_ADC_INPUT; 465 break; 466 } 467 break; 468 469 case UCBADC_ADC_ENABLE: 470 switch (sc->sm_measurement) { 471 case UCBADC_MEASUREMENT_PRESSURE: 472 /* FALLTHROUGH */ 473 case UCBADC_MEASUREMENT_X: 474 sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET( 475 UCB1200_ADCCTRL_ENABLE, 476 UCB1200_ADCCTRL_INPUT_TSPX); 477 REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg, 478 UCBADC_ADC_START0); 479 break; 480 case UCBADC_MEASUREMENT_Y: 481 sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET( 482 UCB1200_ADCCTRL_ENABLE, 483 UCB1200_ADCCTRL_INPUT_TSPY); 484 REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg, 485 UCBADC_ADC_START0); 486 break; 487 } 488 break; 489 490 case UCBADC_ADC_START0: 491 REGWRITE(UCB1200_ADCCTRL_REG, 492 sc->sm_tmpreg | UCB1200_ADCCTRL_START, 493 UCBADC_ADC_START1); 494 break; 495 496 case UCBADC_ADC_START1: 497 REGWRITE(UCB1200_ADCCTRL_REG, 498 sc->sm_tmpreg, 499 UCBADC_ADC_DATAREAD); 500 sc->sm_retry = UCBADC_RETRY_DEFAULT; 501 break; 502 503 case UCBADC_ADC_DATAREAD: 504 REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT); 505 break; 506 507 case UCBADC_ADC_DATAREAD_WAIT: 508 reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg); 509 if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) && 510 --sc->sm_retry > 0) { 511 sc->sm_state = UCBADC_ADC_DATAREAD; 512 } else { 513 if (sc->sm_retry <= 0) { 514 printf("dataread failed\n"); 515 sc->sm_state = UCBADC_ADC_FINI; 516 break; 517 } 518 519 switch (sc->sm_measurement) { 520 case UCBADC_MEASUREMENT_X: 521 sc->sc_x = UCB1200_ADCDATA(reg16); 522 DPRINTFN(9, ("x=%d\n", sc->sc_x)); 523 break; 524 case UCBADC_MEASUREMENT_Y: 525 sc->sc_y = UCB1200_ADCDATA(reg16); 526 DPRINTFN(9, ("y=%d\n", sc->sc_y)); 527 break; 528 case UCBADC_MEASUREMENT_PRESSURE: 529 sc->sc_p = UCB1200_ADCDATA(reg16); 530 DPRINTFN(9, ("p=%d\n", sc->sc_p)); 531 break; 532 } 533 534 sc->sm_state = UCBADC_ADC_DISABLE; 535 } 536 537 break; 538 539 case UCBADC_ADC_DISABLE: 540 REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE); 541 542 break; 543 case UCBADC_ADC_INTRMODE: 544 REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT, 545 UCBADC_MEASUMENT_FINI); 546 break; 547 548 case UCBADC_ADC_INPUT: 549 if (ucbtp_input(sc) == 0) 550 sc->sm_state = UCBADC_ADC_FINI; 551 else 552 sc->sm_state = UCBADC_INTR_ACK0; 553 break; 554 555 case UCBADC_INTR_ACK0: 556 REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1); 557 break; 558 559 case UCBADC_INTR_ACK1: 560 REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2); 561 break; 562 563 case UCBADC_INTR_ACK2: 564 sc->sc_polling_finish = 1; 565 REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI); 566 break; 567 568 /* 569 * UCB1200 register access state 570 */ 571 case UCBADC_REGREAD: 572 /* 573 * In : sc->sm_addr 574 * Out : sc->sm_reg (with SIBtag) 575 */ 576 #define TXSIB_REGREAD_INIT 0 577 #define TXSIB_REGREAD_READ 1 578 switch (sc->sm_read_state) { 579 case TXSIB_REGREAD_INIT: 580 reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr); 581 tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg); 582 sc->sm_rw_retry = UCBADC_RETRY_DEFAULT; 583 sc->sm_read_state = TXSIB_REGREAD_READ; 584 break; 585 case TXSIB_REGREAD_READ: 586 reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG); 587 if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) && 588 --sc->sm_rw_retry > 0) { 589 break; 590 } 591 592 if (sc->sm_rw_retry <= 0) { 593 printf("sf0read: command failed\n"); 594 sc->sm_state = UCBADC_ADC_FINI; 595 } else { 596 sc->sm_reg = reg; 597 sc->sm_read_state = TXSIB_REGREAD_INIT; 598 DPRINTFN(9, ("%08x\n", reg)); 599 if (sc->sm_writing) 600 sc->sm_state = UCBADC_REGWRITE; 601 else 602 sc->sm_state = sc->sm_returnstate; 603 } 604 break; 605 } 606 break; 607 608 case UCBADC_REGWRITE: 609 /* 610 * In : sc->sm_addr, sc->sm_reg (lower 16bit only) 611 */ 612 #define TXSIB_REGWRITE_INIT 0 613 #define TXSIB_REGWRITE_WRITE 1 614 switch (sc->sm_write_state) { 615 case TXSIB_REGWRITE_INIT: 616 sc->sm_writing = 1; 617 sc->sm_write_state = TXSIB_REGWRITE_WRITE; 618 sc->sm_state = UCBADC_REGREAD; 619 620 sc->sm_write_val = sc->sm_reg; 621 break; 622 case TXSIB_REGWRITE_WRITE: 623 sc->sm_writing = 0; 624 sc->sm_write_state = TXSIB_REGWRITE_INIT; 625 sc->sm_state = sc->sm_returnstate; 626 627 reg = sc->sm_reg; 628 reg |= TX39_SIBSF0_WRITE; 629 TX39_SIBSF0_REGDATA_CLR(reg); 630 reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val); 631 tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg); 632 break; 633 } 634 break; 635 } 636 637 return (0); 638 } 639 640 int 641 ucbtp_input(sc) 642 struct ucbtp_softc *sc; 643 { 644 int rx, ry, x, y, p; 645 646 rx = sc->sc_x; 647 ry = sc->sc_y; 648 p = sc->sc_p; 649 650 if (!sc->sc_calibrated) { 651 DPRINTFN(2, ("x=%4d y=%4d p=%4d\n", rx, ry, p)); 652 DPRINTF(("ucbtp_input: no calibration data\n")); 653 } 654 655 if (p < UCBTS_PRESS_THRESHOLD || rx == 0x3ff || ry == 0x3ff || 656 rx == 0 || ry == 0) { 657 sc->sc_stat = UCBTS_STAT_RELEASE; 658 if (sc->sc_polling < UCBTS_TAP_THRESHOLD) { 659 DPRINTFN(2, ("TAP!\n")); 660 /* button 0 DOWN */ 661 wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0); 662 /* button 0 UP */ 663 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0); 664 } else { 665 wsmouse_input(sc->sc_wsmousedev, 0, 666 sc->sc_ox, sc->sc_oy, 0, 667 WSMOUSE_INPUT_ABSOLUTE_X | 668 WSMOUSE_INPUT_ABSOLUTE_Y); 669 670 DPRINTFN(2, ("RELEASE\n")); 671 } 672 sc->sc_polling = 0; 673 674 return (1); 675 } 676 677 if (sc->sc_xy_reverse) 678 tpcalib_trans(&sc->sc_tpcalib, ry, rx, &x, &y); 679 else 680 tpcalib_trans(&sc->sc_tpcalib, rx, ry, &x, &y); 681 682 DPRINTFN(2, ("x: %4d->%4d y: %4d->%4d pressure=%4d\n", 683 rx, x, ry, y, p)); 684 685 /* debug draw */ 686 if (sc->sc_tc->tc_videot) { 687 if (sc->sc_polling == 1) 688 video_dot(sc->sc_tc->tc_videot, x, y); 689 else 690 video_line(sc->sc_tc->tc_videot, sc->sc_ox, 691 sc->sc_oy, x, y); 692 } 693 694 sc->sc_ox = x, sc->sc_oy = y; 695 696 wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0, 697 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 698 699 return (0); 700 } 701 702 /* 703 * access ops. 704 */ 705 706 int 707 ucbtp_enable(v) 708 void *v; 709 { 710 /* not yet */ 711 return (0); 712 } 713 714 void 715 ucbtp_disable(v) 716 void *v; 717 { 718 /* not yet */ 719 } 720 721 int 722 ucbtp_ioctl(v, cmd, data, flag, p) 723 void *v; 724 u_long cmd; 725 caddr_t data; 726 int flag; 727 struct proc *p; 728 { 729 struct ucbtp_softc *sc = v; 730 731 DPRINTF(("%s(%d): ucbtp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd)); 732 733 switch (cmd) { 734 case WSMOUSEIO_GTYPE: 735 *(u_int *)data = WSMOUSE_TYPE_TPANEL; 736 break; 737 738 case WSMOUSEIO_SRES: 739 printf("%s(%d): WSMOUSRIO_SRES is not supported", 740 __FILE__, __LINE__); 741 break; 742 743 case WSMOUSEIO_SCALIBCOORDS: 744 case WSMOUSEIO_GCALIBCOORDS: 745 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p); 746 747 default: 748 return (-1); 749 } 750 751 return (0); 752 } 753