1 1.18 thorpej /* $NetBSD: psh3tp.c,v 1.18 2023/12/20 14:50:02 thorpej Exp $ */ 2 1.1 kiyohara /* 3 1.1 kiyohara * Copyright (c) 2005 KIYOHARA Takashi 4 1.1 kiyohara * All rights reserved. 5 1.1 kiyohara * 6 1.1 kiyohara * Redistribution and use in source and binary forms, with or without 7 1.1 kiyohara * modification, are permitted provided that the following conditions 8 1.1 kiyohara * are met: 9 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright 10 1.1 kiyohara * notice, this list of conditions and the following disclaimer. 11 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the 13 1.1 kiyohara * documentation and/or other materials provided with the distribution. 14 1.1 kiyohara * 15 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.1 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 kiyohara * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 kiyohara * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 1.1 kiyohara * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 1.1 kiyohara * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 kiyohara * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 kiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 1.1 kiyohara * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 1.1 kiyohara * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 1.1 kiyohara * POSSIBILITY OF SUCH DAMAGE. 26 1.1 kiyohara * 27 1.1 kiyohara */ 28 1.1 kiyohara 29 1.1 kiyohara #include <sys/cdefs.h> 30 1.1 kiyohara 31 1.7 kiyohara #include <sys/types.h> 32 1.1 kiyohara #include <sys/param.h> 33 1.7 kiyohara #include <sys/device.h> 34 1.7 kiyohara #include <sys/errno.h> 35 1.1 kiyohara #include <sys/kernel.h> 36 1.1 kiyohara #include <sys/systm.h> 37 1.1 kiyohara #include <sys/callout.h> 38 1.1 kiyohara 39 1.1 kiyohara #include "opt_psh3tp.h" 40 1.1 kiyohara 41 1.1 kiyohara #include <dev/wscons/wsconsio.h> 42 1.1 kiyohara #include <dev/wscons/wsmousevar.h> 43 1.1 kiyohara #include <dev/hpc/hpctpanelvar.h> 44 1.1 kiyohara 45 1.1 kiyohara #include <machine/platid.h> 46 1.1 kiyohara #include <machine/platid_mask.h> 47 1.1 kiyohara 48 1.1 kiyohara #include <machine/intr.h> 49 1.1 kiyohara 50 1.1 kiyohara #include <sh3/exception.h> 51 1.1 kiyohara #include <sh3/intcreg.h> 52 1.1 kiyohara #include <sh3/pfcreg.h> 53 1.1 kiyohara #include <sh3/adcreg.h> 54 1.1 kiyohara 55 1.1 kiyohara #include <sh3/dev/adcvar.h> 56 1.1 kiyohara 57 1.1 kiyohara 58 1.1 kiyohara #ifdef PSH3TP_DEBUG 59 1.1 kiyohara volatile int psh3tp_debug = 4; 60 1.1 kiyohara #define DPRINTF_PRINTF printf_nolog 61 1.1 kiyohara #define DPRINTF(arg) if (psh3tp_debug) DPRINTF_PRINTF arg 62 1.1 kiyohara #define DPRINTFN(n, arg) if (psh3tp_debug > (n)) DPRINTF_PRINTF arg 63 1.1 kiyohara #else 64 1.1 kiyohara #define DPRINTF(arg) ((void)0) 65 1.1 kiyohara #define DPRINTFN(n, arg) ((void)0) 66 1.1 kiyohara #endif 67 1.1 kiyohara 68 1.1 kiyohara 69 1.1 kiyohara /* 70 1.1 kiyohara * PFC bits pertinent to PERSONA HPW-50PA touch-panel 71 1.1 kiyohara */ 72 1.1 kiyohara #define PHDR_TP_PEN_UP 0x40 73 1.1 kiyohara #define SCPDR_TP_SCAN_ENABLE 0x20 74 1.1 kiyohara #define SCPDR_TP_SCAN_DISABLE 0x01 75 1.1 kiyohara #define SCPDR_TP_SCAN_X 0x06 76 1.1 kiyohara #define SCPDR_TP_SCAN_Y 0x09 77 1.1 kiyohara 78 1.1 kiyohara /* 79 1.1 kiyohara * A/D converter channels to get x/y from 80 1.1 kiyohara */ 81 1.1 kiyohara #define ADC_CHANNEL_TP_X 1 82 1.1 kiyohara #define ADC_CHANNEL_TP_Y 0 83 1.1 kiyohara 84 1.1 kiyohara /* 85 1.1 kiyohara * Default (read: my device) raw X/Y values for framebuffer edges. 86 1.1 kiyohara */ 87 1.1 kiyohara #define PSH3TP_FB_RIGHT 56 88 1.1 kiyohara #define PSH3TP_FB_LEFT 969 89 1.1 kiyohara #define PSH3TP_FB_TOP 848 90 1.1 kiyohara #define PSH3TP_FB_BOTTOM 121 91 1.1 kiyohara 92 1.1 kiyohara 93 1.1 kiyohara struct psh3tp_softc { 94 1.12 kiyohara device_t sc_dev; 95 1.1 kiyohara 96 1.1 kiyohara #define PSH3TP_WSMOUSE_ENABLED 0x01 97 1.1 kiyohara int sc_enabled; 98 1.1 kiyohara struct callout sc_touch_ch; 99 1.12 kiyohara device_t sc_wsmousedev; 100 1.1 kiyohara struct tpcalib_softc sc_tpcalib; /* calibration info for wsmouse */ 101 1.1 kiyohara }; 102 1.1 kiyohara 103 1.1 kiyohara 104 1.1 kiyohara /* config machinery */ 105 1.12 kiyohara static int psh3tp_match(device_t, struct cfdata *, void *); 106 1.12 kiyohara static void psh3tp_attach(device_t, device_t, void *); 107 1.1 kiyohara 108 1.1 kiyohara /* wsmouse accessops */ 109 1.1 kiyohara static int psh3tp_wsmouse_enable(void *); 110 1.9 christos static int psh3tp_wsmouse_ioctl(void *, u_long, void *, int, struct lwp *); 111 1.1 kiyohara static void psh3tp_wsmouse_disable(void *); 112 1.1 kiyohara 113 1.1 kiyohara /* internal driver routines */ 114 1.1 kiyohara static void psh3tp_enable(struct psh3tp_softc *); 115 1.1 kiyohara static void psh3tp_disable(struct psh3tp_softc *); 116 1.1 kiyohara static int psh3tp_set_enable(struct psh3tp_softc *, int, int); 117 1.1 kiyohara static int psh3tp_intr(void *); 118 1.1 kiyohara static void psh3tp_start_polling(void *); 119 1.1 kiyohara static void psh3tp_stop_polling(struct psh3tp_softc *); 120 1.1 kiyohara static void psh3tp_callout_wsmouse(void *); 121 1.1 kiyohara static void psh3tp_wsmouse_input(struct psh3tp_softc *, int, int); 122 1.1 kiyohara static void psh3tp_get_raw_xy(int *, int *); 123 1.1 kiyohara 124 1.1 kiyohara 125 1.1 kiyohara const struct wsmouse_accessops psh3tp_accessops = { 126 1.1 kiyohara psh3tp_wsmouse_enable, 127 1.1 kiyohara psh3tp_wsmouse_ioctl, 128 1.1 kiyohara psh3tp_wsmouse_disable 129 1.1 kiyohara }; 130 1.1 kiyohara 131 1.1 kiyohara static const struct wsmouse_calibcoords psh3tp_default_calib = { 132 1.1 kiyohara 0, 0, 639, 239, 133 1.1 kiyohara 4, 134 1.1 kiyohara {{ PSH3TP_FB_LEFT, PSH3TP_FB_TOP, 0, 0 }, 135 1.1 kiyohara { PSH3TP_FB_RIGHT, PSH3TP_FB_TOP, 639, 0 }, 136 1.1 kiyohara { PSH3TP_FB_LEFT, PSH3TP_FB_BOTTOM, 0, 239 }, 137 1.1 kiyohara { PSH3TP_FB_RIGHT, PSH3TP_FB_BOTTOM, 639, 239 }} 138 1.1 kiyohara }; 139 1.1 kiyohara 140 1.1 kiyohara 141 1.12 kiyohara CFATTACH_DECL_NEW(psh3tp, sizeof(struct psh3tp_softc), 142 1.1 kiyohara psh3tp_match, psh3tp_attach, NULL, NULL); 143 1.1 kiyohara 144 1.1 kiyohara 145 1.7 kiyohara /* ARGSUSED */ 146 1.1 kiyohara static int 147 1.12 kiyohara psh3tp_match(device_t parent __unused, struct cfdata *cf, void *aux __unused) 148 1.1 kiyohara { 149 1.1 kiyohara 150 1.1 kiyohara if (!platid_match(&platid, &platid_mask_MACH_HITACHI_PERSONA)) 151 1.7 kiyohara return 0; 152 1.1 kiyohara 153 1.1 kiyohara if (strcmp(cf->cf_name, "psh3tp") != 0) 154 1.7 kiyohara return 0; 155 1.1 kiyohara 156 1.7 kiyohara return 1; 157 1.1 kiyohara } 158 1.1 kiyohara 159 1.1 kiyohara 160 1.1 kiyohara /* 161 1.1 kiyohara * Attach the touch panel driver and its wsmouse child. 162 1.1 kiyohara * 163 1.1 kiyohara * Note that we have to use submatch to distinguish between child because 164 1.1 kiyohara * wsmouse_match matches unconditionally. 165 1.1 kiyohara */ 166 1.7 kiyohara /* ARGSUSED */ 167 1.1 kiyohara static void 168 1.12 kiyohara psh3tp_attach(device_t parent __unused, device_t self, void *aux __unused) 169 1.1 kiyohara { 170 1.7 kiyohara struct psh3tp_softc *sc = device_private(self); 171 1.1 kiyohara struct wsmousedev_attach_args wsma; 172 1.1 kiyohara 173 1.7 kiyohara aprint_naive("\n"); 174 1.7 kiyohara aprint_normal("\n"); 175 1.1 kiyohara 176 1.12 kiyohara sc->sc_dev = self; 177 1.1 kiyohara sc->sc_enabled = 0; 178 1.1 kiyohara 179 1.1 kiyohara /* touch-panel as a pointing device */ 180 1.1 kiyohara wsma.accessops = &psh3tp_accessops; 181 1.1 kiyohara wsma.accesscookie = sc; 182 1.1 kiyohara 183 1.16 thorpej sc->sc_wsmousedev = config_found( 184 1.17 thorpej self, &wsma, wsmousedevprint, CFARGS_NONE); 185 1.1 kiyohara if (sc->sc_wsmousedev == NULL) 186 1.1 kiyohara return; 187 1.1 kiyohara 188 1.1 kiyohara /* init calibration, set default parameters */ 189 1.1 kiyohara tpcalib_init(&sc->sc_tpcalib); 190 1.2 uwe tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 191 1.9 christos (void *)__UNCONST(&psh3tp_default_calib), 0, 0); 192 1.1 kiyohara 193 1.1 kiyohara /* used when in polling mode */ 194 1.10 ad callout_init(&sc->sc_touch_ch, 0); 195 1.1 kiyohara 196 1.1 kiyohara /* establish interrupt handler, but disable until opened */ 197 1.1 kiyohara intc_intr_establish(SH7709_INTEVT2_IRQ2, 198 1.1 kiyohara IST_EDGE, IPL_TTY, psh3tp_intr, sc); 199 1.1 kiyohara intc_intr_disable(SH7709_INTEVT2_IRQ2); 200 1.13 kiyohara 201 1.13 kiyohara if (!pmf_device_register(self, NULL, NULL)) 202 1.13 kiyohara aprint_error_dev(self, "unable to establish power handler\n"); 203 1.1 kiyohara } 204 1.1 kiyohara 205 1.1 kiyohara 206 1.1 kiyohara /* 207 1.1 kiyohara * Enable touch panel: we start in interrupt mode. 208 1.1 kiyohara * Must be called at spltty(). 209 1.1 kiyohara */ 210 1.7 kiyohara /* ARGSUSED */ 211 1.1 kiyohara static void 212 1.7 kiyohara psh3tp_enable(struct psh3tp_softc *sc __unused) 213 1.1 kiyohara { 214 1.1 kiyohara 215 1.15 chs DPRINTFN(2, ("%s: enable\n", device_xname(sc->sc_dev))); 216 1.1 kiyohara intc_intr_enable(SH7709_INTEVT2_IRQ2); 217 1.1 kiyohara } 218 1.1 kiyohara 219 1.1 kiyohara 220 1.1 kiyohara /* 221 1.1 kiyohara * Disable touch panel: disable interrupt, cancel pending callout. 222 1.1 kiyohara * Must be called at spltty(). 223 1.1 kiyohara */ 224 1.1 kiyohara static void 225 1.1 kiyohara psh3tp_disable(struct psh3tp_softc *sc) 226 1.1 kiyohara { 227 1.1 kiyohara 228 1.15 chs DPRINTFN(2, ("%s: disable\n", device_xname(sc->sc_dev))); 229 1.1 kiyohara intc_intr_disable(SH7709_INTEVT2_IRQ2); 230 1.1 kiyohara callout_stop(&sc->sc_touch_ch); 231 1.1 kiyohara } 232 1.1 kiyohara 233 1.1 kiyohara 234 1.1 kiyohara static int 235 1.1 kiyohara psh3tp_set_enable(struct psh3tp_softc *sc, int on, int child) 236 1.1 kiyohara { 237 1.1 kiyohara int s = spltty(); 238 1.1 kiyohara 239 1.1 kiyohara if (on) { 240 1.1 kiyohara if (!sc->sc_enabled) 241 1.1 kiyohara psh3tp_enable(sc); 242 1.1 kiyohara sc->sc_enabled |= child; 243 1.1 kiyohara } else { 244 1.1 kiyohara sc->sc_enabled &= ~child; 245 1.1 kiyohara if (!sc->sc_enabled) 246 1.1 kiyohara psh3tp_disable(sc); 247 1.1 kiyohara } 248 1.1 kiyohara 249 1.1 kiyohara splx(s); 250 1.7 kiyohara return 0; 251 1.1 kiyohara } 252 1.1 kiyohara 253 1.1 kiyohara 254 1.1 kiyohara static int 255 1.14 tsutsui psh3tp_wsmouse_enable(void *cookie) 256 1.1 kiyohara { 257 1.14 tsutsui struct psh3tp_softc *sc = (struct psh3tp_softc *)cookie; 258 1.1 kiyohara 259 1.15 chs DPRINTFN(1, ("%s: wsmouse enable\n", device_xname(sc->sc_dev))); 260 1.7 kiyohara return psh3tp_set_enable(sc, 1, PSH3TP_WSMOUSE_ENABLED); 261 1.1 kiyohara } 262 1.1 kiyohara 263 1.1 kiyohara 264 1.1 kiyohara static void 265 1.14 tsutsui psh3tp_wsmouse_disable(void *cookie) 266 1.1 kiyohara { 267 1.14 tsutsui struct psh3tp_softc *sc = (struct psh3tp_softc *)cookie; 268 1.1 kiyohara 269 1.15 chs DPRINTFN(1, ("%s: wsmouse disable\n", device_xname(sc->sc_dev))); 270 1.1 kiyohara psh3tp_set_enable(sc, 0, PSH3TP_WSMOUSE_ENABLED); 271 1.1 kiyohara } 272 1.1 kiyohara 273 1.1 kiyohara 274 1.1 kiyohara static int 275 1.14 tsutsui psh3tp_intr(void *arg) 276 1.1 kiyohara { 277 1.14 tsutsui struct psh3tp_softc *sc = (struct psh3tp_softc *)arg; 278 1.1 kiyohara 279 1.1 kiyohara uint8_t irr0; 280 1.1 kiyohara uint8_t phdr, touched; 281 1.1 kiyohara unsigned int steady, tremor_timeout; 282 1.1 kiyohara 283 1.1 kiyohara irr0 = _reg_read_1(SH7709_IRR0); 284 1.1 kiyohara if ((irr0 & IRR0_IRQ2) == 0) { 285 1.1 kiyohara #ifdef DIAGNOSTIC 286 1.15 chs printf("%s: irr0 %02x?\n", device_xname(sc->sc_dev), irr0); 287 1.1 kiyohara #endif 288 1.7 kiyohara return 0; 289 1.1 kiyohara } 290 1.1 kiyohara 291 1.1 kiyohara if (!sc->sc_enabled) { 292 1.15 chs DPRINTFN(1, ("%s: intr: !sc_enabled\n", device_xname(sc->sc_dev))); 293 1.1 kiyohara intc_intr_disable(SH7709_INTEVT2_IRQ2); 294 1.1 kiyohara goto served; 295 1.1 kiyohara } 296 1.1 kiyohara 297 1.1 kiyohara /* 298 1.1 kiyohara * Number of times the "touched" bit should be read 299 1.1 kiyohara * consecutively. 300 1.1 kiyohara */ 301 1.1 kiyohara #define TREMOR_THRESHOLD 0x300 302 1.1 kiyohara steady = 0; 303 1.1 kiyohara tremor_timeout = TREMOR_THRESHOLD * 16; /* XXX: arbitrary */ 304 1.8 thorpej touched = true; /* we start with "touched" state */ 305 1.1 kiyohara 306 1.1 kiyohara do { 307 1.1 kiyohara uint8_t state; 308 1.1 kiyohara 309 1.1 kiyohara phdr = _reg_read_1(SH7709_PHDR); 310 1.1 kiyohara state = ((phdr & PHDR_TP_PEN_UP) != PHDR_TP_PEN_UP); 311 1.1 kiyohara 312 1.1 kiyohara if (state == touched) 313 1.1 kiyohara ++steady; 314 1.1 kiyohara else { 315 1.1 kiyohara steady = 0; 316 1.1 kiyohara touched = state; 317 1.1 kiyohara } 318 1.1 kiyohara 319 1.1 kiyohara if (--tremor_timeout == 0) { 320 1.15 chs DPRINTF(("%s: tremor timeout!\n", 321 1.15 chs device_xname(sc->sc_dev))); 322 1.1 kiyohara goto served; 323 1.1 kiyohara } 324 1.1 kiyohara } while (steady < TREMOR_THRESHOLD); 325 1.1 kiyohara 326 1.1 kiyohara if (touched) { 327 1.1 kiyohara intc_intr_disable(SH7709_INTEVT2_IRQ2); 328 1.1 kiyohara 329 1.1 kiyohara /* 330 1.1 kiyohara * ADC readings are not stable yet, so schedule 331 1.1 kiyohara * callout instead of accessing ADC from the interrupt 332 1.1 kiyohara * handler only to immediately delay(). 333 1.1 kiyohara */ 334 1.1 kiyohara callout_reset(&sc->sc_touch_ch, 335 1.1 kiyohara hz/32, psh3tp_start_polling, sc); 336 1.1 kiyohara } else 337 1.15 chs DPRINTFN(1, ("%s: tremor\n", device_xname(sc->sc_dev))); 338 1.1 kiyohara served: 339 1.1 kiyohara /* clear the interrupt */ 340 1.1 kiyohara _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ2); 341 1.1 kiyohara 342 1.7 kiyohara return 1; 343 1.1 kiyohara } 344 1.1 kiyohara 345 1.1 kiyohara 346 1.1 kiyohara /* 347 1.1 kiyohara * Called from the interrupt handler at spltty() upon first touch. 348 1.1 kiyohara * Decide if we are going to report this touch as a mouse click/drag. 349 1.1 kiyohara */ 350 1.1 kiyohara static void 351 1.14 tsutsui psh3tp_start_polling(void *arg) 352 1.1 kiyohara { 353 1.14 tsutsui struct psh3tp_softc *sc = (struct psh3tp_softc *)arg; 354 1.1 kiyohara uint8_t phdr; 355 1.1 kiyohara int rawx, rawy; 356 1.1 kiyohara 357 1.1 kiyohara phdr = _reg_read_1(SH7709_PHDR); 358 1.1 kiyohara if ((phdr & PHDR_TP_PEN_UP) == PHDR_TP_PEN_UP) { 359 1.1 kiyohara DPRINTFN(2, ("%s: start: pen is not down\n", 360 1.15 chs device_xname(sc->sc_dev))); 361 1.1 kiyohara psh3tp_stop_polling(sc); 362 1.1 kiyohara return; 363 1.1 kiyohara } 364 1.1 kiyohara 365 1.1 kiyohara psh3tp_get_raw_xy(&rawx, &rawy); 366 1.1 kiyohara DPRINTFN(2, ("%s: start: %4d %4d -> ", 367 1.15 chs device_xname(sc->sc_dev), rawx, rawy)); 368 1.1 kiyohara 369 1.1 kiyohara if (sc->sc_enabled & PSH3TP_WSMOUSE_ENABLED) { 370 1.1 kiyohara DPRINTFN(2, ("mouse\n")); 371 1.1 kiyohara psh3tp_wsmouse_input(sc, rawx, rawy); 372 1.1 kiyohara callout_reset(&sc->sc_touch_ch, 373 1.1 kiyohara hz/32, psh3tp_callout_wsmouse, sc); 374 1.1 kiyohara } else { 375 1.1 kiyohara DPRINTFN(2, ("ignore\n")); 376 1.1 kiyohara psh3tp_stop_polling(sc); 377 1.1 kiyohara } 378 1.1 kiyohara } 379 1.1 kiyohara 380 1.1 kiyohara 381 1.1 kiyohara /* 382 1.1 kiyohara * Re-enable touch panel interrupt. 383 1.1 kiyohara * Called at spltty() when polling code detects pen-up. 384 1.1 kiyohara */ 385 1.7 kiyohara /* ARGSUSED */ 386 1.1 kiyohara static void 387 1.7 kiyohara psh3tp_stop_polling(struct psh3tp_softc *sc __unused) 388 1.1 kiyohara { 389 1.1 kiyohara uint8_t irr0; 390 1.1 kiyohara 391 1.15 chs DPRINTFN(2, ("%s: stop\n", device_xname(sc->sc_dev))); 392 1.1 kiyohara 393 1.1 kiyohara /* clear pending interrupt signal before re-enabling the interrupt */ 394 1.1 kiyohara irr0 = _reg_read_1(SH7709_IRR0); 395 1.1 kiyohara if ((irr0 & IRR0_IRQ2) != 0) 396 1.1 kiyohara _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ2); 397 1.1 kiyohara 398 1.1 kiyohara intc_intr_enable(SH7709_INTEVT2_IRQ2); 399 1.1 kiyohara } 400 1.1 kiyohara 401 1.1 kiyohara 402 1.1 kiyohara /* 403 1.1 kiyohara * We are reporting this touch as a mouse click/drag. 404 1.1 kiyohara */ 405 1.1 kiyohara static void 406 1.14 tsutsui psh3tp_callout_wsmouse(void *arg) 407 1.1 kiyohara { 408 1.14 tsutsui struct psh3tp_softc *sc = (struct psh3tp_softc *)arg; 409 1.1 kiyohara uint8_t phdr; 410 1.1 kiyohara int rawx, rawy; 411 1.1 kiyohara int s; 412 1.1 kiyohara 413 1.1 kiyohara s = spltty(); 414 1.1 kiyohara 415 1.1 kiyohara if (!sc->sc_enabled) { 416 1.1 kiyohara DPRINTFN(1, ("%s: wsmouse callout: !sc_enabled\n", 417 1.15 chs device_xname(sc->sc_dev))); 418 1.1 kiyohara splx(s); 419 1.1 kiyohara return; 420 1.1 kiyohara } 421 1.1 kiyohara 422 1.1 kiyohara phdr = _reg_read_1(SH7709_PHDR); 423 1.1 kiyohara if ((phdr & PHDR_TP_PEN_UP) != PHDR_TP_PEN_UP) { 424 1.1 kiyohara psh3tp_get_raw_xy(&rawx, &rawy); 425 1.1 kiyohara psh3tp_wsmouse_input(sc, rawx, rawy); /* mouse dragged */ 426 1.1 kiyohara callout_schedule(&sc->sc_touch_ch, hz/32); 427 1.1 kiyohara } else { 428 1.1 kiyohara wsmouse_input( /* button up */ 429 1.6 plunky sc->sc_wsmousedev, 0, 0, 0, 0, 0, WSMOUSE_INPUT_DELTA); 430 1.1 kiyohara psh3tp_stop_polling(sc); 431 1.1 kiyohara } 432 1.1 kiyohara splx(s); 433 1.1 kiyohara } 434 1.1 kiyohara 435 1.1 kiyohara 436 1.1 kiyohara /* 437 1.1 kiyohara * Report mouse click/drag. 438 1.1 kiyohara */ 439 1.1 kiyohara static void 440 1.1 kiyohara psh3tp_wsmouse_input(struct psh3tp_softc *sc, int rawx, int rawy) 441 1.1 kiyohara { 442 1.1 kiyohara int x, y; 443 1.1 kiyohara 444 1.1 kiyohara tpcalib_trans(&sc->sc_tpcalib, rawx, rawy, &x, &y); 445 1.1 kiyohara 446 1.1 kiyohara DPRINTFN(3, ("%s: %4d %4d -> %3d %3d\n", 447 1.15 chs device_xname(sc->sc_dev), rawx, rawy, x, y)); 448 1.1 kiyohara 449 1.1 kiyohara wsmouse_input(sc->sc_wsmousedev, 450 1.1 kiyohara 1, /* button */ 451 1.6 plunky x, y, 0, 0, 452 1.1 kiyohara WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 453 1.1 kiyohara } 454 1.1 kiyohara 455 1.1 kiyohara 456 1.1 kiyohara /* 457 1.1 kiyohara * Read raw X/Y coordinates from the ADC. 458 1.1 kiyohara */ 459 1.1 kiyohara static void 460 1.1 kiyohara psh3tp_get_raw_xy(int *rawxp, int *rawyp) 461 1.1 kiyohara { 462 1.1 kiyohara uint8_t scpdr; 463 1.1 kiyohara 464 1.1 kiyohara /* X axis */ 465 1.1 kiyohara scpdr = _reg_read_1(SH7709_SCPDR); 466 1.1 kiyohara scpdr &= ~SCPDR_TP_SCAN_DISABLE; 467 1.1 kiyohara scpdr |= (SCPDR_TP_SCAN_ENABLE | SCPDR_TP_SCAN_X); 468 1.1 kiyohara _reg_write_1(SH7709_SCPDR, scpdr); 469 1.1 kiyohara delay(40); 470 1.1 kiyohara 471 1.1 kiyohara *rawxp = adc_sample_channel(ADC_CHANNEL_TP_X); 472 1.1 kiyohara 473 1.1 kiyohara /* Y axis */ 474 1.1 kiyohara scpdr = _reg_read_1(SH7709_SCPDR); 475 1.1 kiyohara scpdr &= ~SCPDR_TP_SCAN_X; 476 1.1 kiyohara scpdr |= (SCPDR_TP_SCAN_ENABLE | SCPDR_TP_SCAN_Y); 477 1.1 kiyohara _reg_write_1(SH7709_SCPDR, scpdr); 478 1.1 kiyohara delay(40); 479 1.1 kiyohara 480 1.1 kiyohara *rawyp = adc_sample_channel(ADC_CHANNEL_TP_Y); 481 1.1 kiyohara 482 1.1 kiyohara /* restore SCPDR */ 483 1.1 kiyohara scpdr = _reg_read_1(SH7709_SCPDR); 484 1.1 kiyohara scpdr &= ~(SCPDR_TP_SCAN_ENABLE | SCPDR_TP_SCAN_Y); 485 1.1 kiyohara scpdr |= SCPDR_TP_SCAN_DISABLE; 486 1.1 kiyohara _reg_write_1(SH7709_SCPDR, scpdr); 487 1.1 kiyohara } 488 1.1 kiyohara 489 1.1 kiyohara 490 1.1 kiyohara static int 491 1.14 tsutsui psh3tp_wsmouse_ioctl(void *cookie, u_long cmd, void *data, int flag, 492 1.7 kiyohara struct lwp *l) 493 1.1 kiyohara { 494 1.14 tsutsui struct psh3tp_softc *sc = (struct psh3tp_softc *)cookie; 495 1.1 kiyohara 496 1.7 kiyohara return hpc_tpanel_ioctl(&sc->sc_tpcalib, cmd, data, flag, l); 497 1.1 kiyohara } 498