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