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