1 /* $NetBSD: j6x0tp.c,v 1.26 2023/12/20 14:50:02 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2003 Valeriy E. Ushakov 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __KERNEL_RCSID(0, "$NetBSD: j6x0tp.c,v 1.26 2023/12/20 14:50:02 thorpej Exp $"); 32 33 #include <sys/param.h> 34 #include <sys/kernel.h> 35 #include <sys/device.h> 36 #include <sys/systm.h> 37 #include <sys/callout.h> 38 39 #include "opt_j6x0tp.h" 40 41 #include <dev/wscons/wsconsio.h> 42 #include <dev/wscons/wsmousevar.h> 43 #include <dev/wscons/wskbdvar.h> 44 #include <dev/wscons/wsksymvar.h> 45 #include <dev/wscons/wsksymdef.h> 46 #include <dev/hpc/hpctpanelvar.h> 47 48 #include <machine/platid.h> 49 #include <machine/platid_mask.h> 50 51 #include <machine/intr.h> 52 53 #include <sh3/exception.h> 54 #include <sh3/intcreg.h> 55 #include <sh3/pfcreg.h> 56 #include <sh3/adcreg.h> 57 58 #include <sh3/dev/adcvar.h> 59 60 61 #if 0 /* XXX: disabled in favor of local version that uses printf_nolog */ 62 #define DPRINTF_ENABLE 63 #define DPRINTF_DEBUG j6x0tp_debug 64 #define DPRINTF_LEVEL 0 65 #include <machine/debug.h> 66 #else 67 #ifdef J6X0TP_DEBUG 68 volatile int j6x0tp_debug = 0; 69 #define DPRINTF_PRINTF printf_nolog 70 #define DPRINTF(arg) if (j6x0tp_debug) DPRINTF_PRINTF arg 71 #define DPRINTFN(n, arg) if (j6x0tp_debug > (n)) DPRINTF_PRINTF arg 72 #else 73 #define DPRINTF(arg) ((void)0) 74 #define DPRINTFN(n, arg) ((void)0) 75 #endif 76 #endif 77 78 79 /* 80 * PFC bits pertinent to Jornada 6x0 touchpanel 81 */ 82 #define PHDR_TP_PEN_DOWN 0x08 83 84 #define SCPDR_TP_SCAN_ENABLE 0x20 85 #define SCPDR_TP_SCAN_Y 0x02 86 #define SCPDR_TP_SCAN_X 0x01 87 88 /* 89 * A/D converter channels to get x/y from 90 */ 91 #define ADC_CHANNEL_TP_Y 1 92 #define ADC_CHANNEL_TP_X 2 93 94 /* 95 * Default (read: my device :) raw X/Y values for framebuffer edges. 96 * XXX: defopt these? 97 */ 98 #define J6X0TP_FB_LEFT 38 99 #define J6X0TP_FB_RIGHT 950 100 #define J6X0TP_FB_TOP 80 101 #define J6X0TP_FB_BOTTOM 900 102 103 /* 104 * Bottom of the n'th hard icon (n = 1..4) 105 */ 106 #define J6X0TP_HARD_ICON_MAX_Y(n) \ 107 (J6X0TP_FB_TOP + ((J6X0TP_FB_BOTTOM - J6X0TP_FB_TOP) / 4) * (n)) 108 109 110 struct j6x0tp_softc { 111 device_t sc_dev; 112 113 #define J6X0TP_WSMOUSE_ENABLED 0x01 114 #define J6X0TP_WSKBD_ENABLED 0x02 115 int sc_enabled; 116 117 int sc_hard_icon; 118 119 struct callout sc_touch_ch; 120 121 device_t sc_wsmousedev; 122 device_t sc_wskbddev; 123 124 struct tpcalib_softc sc_tpcalib; /* calibration info for wsmouse */ 125 }; 126 127 128 /* config machinery */ 129 static int j6x0tp_match(device_t, cfdata_t, void *); 130 static void j6x0tp_attach(device_t, device_t, void *); 131 132 /* wsmouse accessops */ 133 static int j6x0tp_wsmouse_enable(void *); 134 static int j6x0tp_wsmouse_ioctl(void *, u_long, void *, int, lwp_t *); 135 static void j6x0tp_wsmouse_disable(void *); 136 137 /* wskbd accessops */ 138 static int j6x0tp_wskbd_enable(void *, int); 139 static void j6x0tp_wskbd_set_leds(void *, int); 140 static int j6x0tp_wskbd_ioctl(void *, u_long, void *, int, lwp_t *); 141 142 /* internal driver routines */ 143 static void j6x0tp_enable(struct j6x0tp_softc *); 144 static void j6x0tp_disable(struct j6x0tp_softc *); 145 static int j6x0tp_enable_child(struct j6x0tp_softc *, int, int); 146 static int j6x0tp_intr(void *); 147 static void j6x0tp_start_polling(void *); 148 static void j6x0tp_stop_polling(struct j6x0tp_softc *); 149 static void j6x0tp_callout_wsmouse(void *); 150 static void j6x0tp_callout_wskbd(void *); 151 static void j6x0tp_wsmouse_input(struct j6x0tp_softc *, int, int); 152 static void j6x0tp_get_raw_xy(int *, int *); 153 static int j6x0tp_get_hard_icon(int, int); 154 155 156 static const struct wsmouse_accessops j6x0tp_accessops = { 157 j6x0tp_wsmouse_enable, 158 j6x0tp_wsmouse_ioctl, 159 j6x0tp_wsmouse_disable 160 }; 161 162 static const struct wsmouse_calibcoords j6x0tp_default_calib = { 163 0, 0, 639, 239, 164 4, 165 {{ J6X0TP_FB_LEFT, J6X0TP_FB_TOP, 0, 0 }, 166 { J6X0TP_FB_RIGHT, J6X0TP_FB_TOP, 639, 0 }, 167 { J6X0TP_FB_LEFT, J6X0TP_FB_BOTTOM, 0, 239 }, 168 { J6X0TP_FB_RIGHT, J6X0TP_FB_BOTTOM, 639, 239 }} 169 }; 170 171 static const struct wskbd_accessops j6x0tp_wskbd_accessops = { 172 j6x0tp_wskbd_enable, 173 j6x0tp_wskbd_set_leds, 174 j6x0tp_wskbd_ioctl 175 }; 176 177 178 #ifndef J6X0TP_SETTINGS_ICON_KEYSYM 179 #define J6X0TP_SETTINGS_ICON_KEYSYM KS_Home 180 #endif 181 #ifndef J6X0TP_PGUP_ICON_KEYSYM 182 #define J6X0TP_PGUP_ICON_KEYSYM KS_Prior 183 #endif 184 #ifndef J6X0TP_PGDN_ICON_KEYSYM 185 #define J6X0TP_PGDN_ICON_KEYSYM KS_Next 186 #endif 187 #ifndef J6X0TP_SWITCH_ICON_KEYSYM 188 #define J6X0TP_SWITCH_ICON_KEYSYM KS_End 189 #endif 190 191 static const keysym_t j6x0tp_wskbd_keydesc[] = { 192 KS_KEYCODE(1), J6X0TP_SETTINGS_ICON_KEYSYM, 193 KS_KEYCODE(2), J6X0TP_PGUP_ICON_KEYSYM, 194 KS_KEYCODE(3), J6X0TP_PGDN_ICON_KEYSYM, 195 KS_KEYCODE(4), J6X0TP_SWITCH_ICON_KEYSYM 196 }; 197 198 static const struct wscons_keydesc j6x0tp_wskbd_keydesctab[] = { 199 { KB_US, 0, 200 sizeof(j6x0tp_wskbd_keydesc)/sizeof(keysym_t), 201 j6x0tp_wskbd_keydesc 202 }, 203 {0, 0, 0, 0} 204 }; 205 206 static const struct wskbd_mapdata j6x0tp_wskbd_keymapdata = { 207 j6x0tp_wskbd_keydesctab, KB_US 208 }; 209 210 211 CFATTACH_DECL_NEW(j6x0tp, sizeof(struct j6x0tp_softc), 212 j6x0tp_match, j6x0tp_attach, NULL, NULL); 213 214 215 static int 216 j6x0tp_match(device_t parent, cfdata_t cf, void *aux) 217 { 218 219 /* 220 * XXX: platid_mask_MACH_HP_LX also matches 360LX. It's not 221 * confirmed whether touch panel in 360LX is connected this 222 * way. We may need to regroup platid masks. 223 */ 224 if (!platid_match(&platid, &platid_mask_MACH_HP_JORNADA_6XX) 225 && !platid_match(&platid, &platid_mask_MACH_HP_LX)) 226 return (0); 227 228 if (strcmp(cf->cf_name, "j6x0tp") != 0) 229 return (0); 230 231 return (1); 232 } 233 234 235 static void 236 j6x0tp_attach(device_t parent, device_t self, void *aux) 237 { 238 struct j6x0tp_softc *sc; 239 struct wsmousedev_attach_args wsma; 240 struct wskbddev_attach_args wska; 241 242 aprint_naive("\n"); 243 aprint_normal("\n"); 244 245 sc = device_private(self); 246 sc->sc_dev = self; 247 248 sc->sc_enabled = 0; 249 sc->sc_hard_icon = 0; 250 251 /* touch-panel as a pointing device */ 252 wsma.accessops = &j6x0tp_accessops; 253 wsma.accesscookie = sc; 254 255 sc->sc_wsmousedev = config_found(self, &wsma, wsmousedevprint, 256 CFARGS(.iattr = "wsmousedev")); 257 if (sc->sc_wsmousedev == NULL) 258 return; 259 260 /* on-screen "hard icons" as a keyboard device */ 261 wska.console = 0; 262 wska.keymap = &j6x0tp_wskbd_keymapdata; 263 wska.accessops = &j6x0tp_wskbd_accessops; 264 wska.accesscookie = sc; 265 266 sc->sc_wskbddev = config_found(self, &wska, wskbddevprint, 267 CFARGS(.iattr = "wskbddev")); 268 269 /* init calibration, set default parameters */ 270 tpcalib_init(&sc->sc_tpcalib); 271 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 272 (void *)__UNCONST(&j6x0tp_default_calib), 0, 0); 273 274 /* used when in polling mode */ 275 callout_init(&sc->sc_touch_ch, 0); 276 277 /* establish interrupt handler, but disable until opened */ 278 intc_intr_establish(SH7709_INTEVT2_IRQ3, IST_EDGE, IPL_TTY, 279 j6x0tp_intr, sc); 280 intc_intr_disable(SH7709_INTEVT2_IRQ3); 281 282 if (!pmf_device_register(self, NULL, NULL)) 283 aprint_error_dev(self, "unable to establish power handler\n"); 284 } 285 286 287 /* 288 * Enable touch panel: we start in interrupt mode. 289 * Must be called as spltty(). 290 */ 291 static void 292 j6x0tp_enable(struct j6x0tp_softc *sc) 293 { 294 295 DPRINTFN(2, ("%s: enable\n", device_xname(sc->sc_dev))); 296 intc_intr_enable(SH7709_INTEVT2_IRQ3); 297 } 298 299 300 /* 301 * Disable touch panel: disable interrupt, cancel pending callout. 302 * Must be called as spltty(). 303 */ 304 static void 305 j6x0tp_disable(struct j6x0tp_softc *sc) 306 { 307 308 DPRINTFN(2, ("%s: disable\n", device_xname(sc->sc_dev))); 309 intc_intr_disable(SH7709_INTEVT2_IRQ3); 310 callout_stop(&sc->sc_touch_ch); 311 } 312 313 314 static int 315 j6x0tp_enable_child(struct j6x0tp_softc *sc, int child, int on) 316 { 317 int s = spltty(); 318 319 if (on) { 320 if (!sc->sc_enabled) 321 j6x0tp_enable(sc); 322 sc->sc_enabled |= child; 323 } else { 324 sc->sc_enabled &= ~child; 325 if (!sc->sc_enabled) 326 j6x0tp_disable(sc); 327 } 328 329 splx(s); 330 return (0); 331 } 332 333 334 static int 335 j6x0tp_wsmouse_enable(void *arg) 336 { 337 struct j6x0tp_softc *sc = arg; 338 339 DPRINTFN(1, ("%s: wsmouse enable\n", device_xname(sc->sc_dev))); 340 return (j6x0tp_enable_child(sc, J6X0TP_WSMOUSE_ENABLED, 1)); 341 } 342 343 344 static void 345 j6x0tp_wsmouse_disable(void *arg) 346 { 347 struct j6x0tp_softc *sc = arg; 348 349 DPRINTFN(1, ("%s: wsmouse disable\n", device_xname(sc->sc_dev))); 350 j6x0tp_enable_child(sc, J6X0TP_WSMOUSE_ENABLED, 0); 351 } 352 353 354 static int 355 j6x0tp_wskbd_enable(void *arg, int on) 356 { 357 struct j6x0tp_softc *sc = arg; 358 359 DPRINTFN(1, ("%s: wskbd %sable\n", device_xname(sc->sc_dev), 360 on ? "en" : "dis")); 361 return (j6x0tp_enable_child(sc, J6X0TP_WSKBD_ENABLED, on)); 362 } 363 364 365 static int 366 j6x0tp_intr(void *arg) 367 { 368 struct j6x0tp_softc *sc = arg; 369 370 uint8_t irr0; 371 uint8_t phdr, touched; 372 unsigned int steady, tremor_timeout; 373 374 irr0 = _reg_read_1(SH7709_IRR0); 375 if ((irr0 & IRR0_IRQ3) == 0) { 376 #ifdef DIAGNOSTIC 377 printf("%s: irr0 %02x?\n", device_xname(sc->sc_dev), irr0); 378 #endif 379 return (0); 380 } 381 382 if (!sc->sc_enabled) { 383 DPRINTFN(1, ("%s: intr: !sc_enabled\n", 384 device_xname(sc->sc_dev))); 385 intc_intr_disable(SH7709_INTEVT2_IRQ3); 386 goto served; 387 } 388 389 390 /* 391 * Number of times the "touched" bit should be read 392 * consecutively. 393 */ 394 # define TREMOR_THRESHOLD 0x300 395 396 steady = 0; 397 tremor_timeout = TREMOR_THRESHOLD * 16; /* XXX: arbitrary */ 398 touched = PHDR_TP_PEN_DOWN; /* we start with "touched" state */ 399 400 do { 401 phdr = _reg_read_1(SH7709_PHDR); 402 403 if ((phdr & PHDR_TP_PEN_DOWN) == touched) 404 ++steady; 405 else { 406 steady = 0; 407 touched = phdr & PHDR_TP_PEN_DOWN; 408 } 409 410 if (--tremor_timeout == 0) { 411 DPRINTF(("%s: tremor timeout!\n", 412 device_xname(sc->sc_dev))); 413 goto served; 414 } 415 } while (steady < TREMOR_THRESHOLD); 416 417 if (touched) { 418 intc_intr_disable(SH7709_INTEVT2_IRQ3); 419 420 /* 421 * ADC readings are not stable yet, so schedule 422 * callout instead of accessing ADC from the interrupt 423 * handler only to immediately delay(). 424 */ 425 callout_reset(&sc->sc_touch_ch, hz/32, 426 j6x0tp_start_polling, sc); 427 } else 428 DPRINTFN(1, ("%s: tremor\n", device_xname(sc->sc_dev))); 429 served: 430 /* clear the interrupt (XXX: protect access?) */ 431 _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ3); 432 433 return (1); 434 } 435 436 437 /* 438 * Called from the interrupt handler at spltty() upon first touch. 439 * Decide if we are going to report this touch as a mouse click/drag 440 * or as a key press. 441 */ 442 static void 443 j6x0tp_start_polling(void *arg) 444 { 445 struct j6x0tp_softc *sc = arg; 446 uint8_t phdr; 447 int do_mouse, do_kbd; 448 int rawx, rawy; 449 int icon; 450 451 phdr = _reg_read_1(SH7709_PHDR); 452 if ((phdr & PHDR_TP_PEN_DOWN) == 0) { 453 DPRINTFN(2, ("%s: start: pen is not down\n", 454 device_xname(sc->sc_dev))); 455 j6x0tp_stop_polling(sc); 456 } 457 458 j6x0tp_get_raw_xy(&rawx, &rawy); 459 DPRINTFN(2, ("%s: start: %4d %4d -> ", 460 device_xname(sc->sc_dev), rawx, rawy)); 461 462 do_mouse = sc->sc_enabled & J6X0TP_WSMOUSE_ENABLED; 463 #ifdef J6X0TP_WSMOUSE_EXCLUSIVE 464 if (do_mouse) 465 do_kbd = 0; 466 else 467 #endif 468 do_kbd = sc->sc_enabled & J6X0TP_WSKBD_ENABLED; 469 470 icon = 0; 471 if (do_kbd) 472 icon = j6x0tp_get_hard_icon(rawx, rawy); 473 474 if (icon != 0) { 475 DPRINTFN(2, ("icon %d\n", icon)); 476 sc->sc_hard_icon = icon; 477 wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_DOWN, icon); 478 callout_reset(&sc->sc_touch_ch, hz/32, 479 j6x0tp_callout_wskbd, sc); 480 } else if (do_mouse) { 481 DPRINTFN(2, ("mouse\n")); 482 j6x0tp_wsmouse_input(sc, rawx, rawy); 483 callout_reset(&sc->sc_touch_ch, hz/32, 484 j6x0tp_callout_wsmouse, sc); 485 } else { 486 DPRINTFN(2, ("ignore\n")); 487 j6x0tp_stop_polling(sc); 488 } 489 } 490 491 492 /* 493 * Re-enable touch panel interrupt. 494 * Called as spltty() when polling code detects pen-up. 495 */ 496 static void 497 j6x0tp_stop_polling(struct j6x0tp_softc *sc) 498 { 499 uint8_t irr0; 500 501 DPRINTFN(2, ("%s: stop\n", device_xname(sc->sc_dev))); 502 503 /* clear pending interrupt signal before re-enabling the interrupt */ 504 irr0 = _reg_read_1(SH7709_IRR0); 505 if ((irr0 & IRR0_IRQ3) != 0) 506 _reg_write_1(SH7709_IRR0, irr0 & ~IRR0_IRQ3); 507 508 intc_intr_enable(SH7709_INTEVT2_IRQ3); 509 } 510 511 512 /* 513 * We are reporting this touch as a keyboard event. 514 * Poll touch screen waiting for pen-up. 515 */ 516 static void 517 j6x0tp_callout_wskbd(void *arg) 518 { 519 struct j6x0tp_softc *sc = arg; 520 uint8_t phdr; 521 int s; 522 523 s = spltty(); 524 525 if (!sc->sc_enabled) { 526 DPRINTFN(1, ("%s: wskbd callout: !sc_enabled\n", 527 device_xname(sc->sc_dev))); 528 splx(s); 529 return; 530 } 531 532 phdr = _reg_read_1(SH7709_PHDR); 533 if ((phdr & PHDR_TP_PEN_DOWN) != 0) { 534 /* 535 * Pen is still down, continue polling. Wskbd's 536 * auto-repeat takes care of repeating the key. 537 */ 538 callout_schedule(&sc->sc_touch_ch, hz/32); 539 } else { 540 wskbd_input(sc->sc_wskbddev, 541 WSCONS_EVENT_KEY_UP, sc->sc_hard_icon); 542 j6x0tp_stop_polling(sc); 543 } 544 splx(s); 545 } 546 547 548 /* 549 * We are reporting this touch as a mouse click/drag. 550 */ 551 static void 552 j6x0tp_callout_wsmouse(void *arg) 553 { 554 struct j6x0tp_softc *sc = arg; 555 uint8_t phdr; 556 int rawx, rawy; 557 int s; 558 559 s = spltty(); 560 561 if (!sc->sc_enabled) { 562 DPRINTFN(1, ("%s: wsmouse callout: !sc_enabled\n", 563 device_xname(sc->sc_dev))); 564 splx(s); 565 return; 566 } 567 568 phdr = _reg_read_1(SH7709_PHDR); 569 if ((phdr & PHDR_TP_PEN_DOWN) != 0) { 570 j6x0tp_get_raw_xy(&rawx, &rawy); 571 j6x0tp_wsmouse_input(sc, rawx, rawy); /* mouse dragged */ 572 callout_schedule(&sc->sc_touch_ch, hz/32); 573 } else { 574 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0, /* button up */ 575 WSMOUSE_INPUT_DELTA); 576 j6x0tp_stop_polling(sc); 577 } 578 splx(s); 579 } 580 581 582 /* 583 * Report mouse click/drag. 584 */ 585 static void 586 j6x0tp_wsmouse_input(struct j6x0tp_softc *sc, int rawx, int rawy) 587 { 588 int x, y; 589 590 tpcalib_trans(&sc->sc_tpcalib, rawx, rawy, &x, &y); 591 592 DPRINTFN(3, ("%s: %4d %4d -> %3d %3d\n", 593 device_xname(sc->sc_dev), rawx, rawy, x, y)); 594 595 wsmouse_input(sc->sc_wsmousedev, 596 1, /* button */ 597 x, y, 0, 0, 598 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 599 } 600 601 602 /* 603 * Read raw X/Y coordinates from the ADC. 604 * XXX: protect accesses to SCPDR? 605 */ 606 static void 607 j6x0tp_get_raw_xy(int *rawxp, int *rawyp) 608 { 609 uint8_t scpdr; 610 611 /* Y axis */ 612 scpdr = _reg_read_1(SH7709_SCPDR); 613 scpdr |= SCPDR_TP_SCAN_ENABLE; 614 scpdr &= ~SCPDR_TP_SCAN_Y; /* pull low to scan */ 615 _reg_write_1(SH7709_SCPDR, scpdr); 616 delay(10); 617 618 *rawyp = adc_sample_channel(ADC_CHANNEL_TP_Y); 619 620 /* X axis */ 621 scpdr = _reg_read_1(SH7709_SCPDR); 622 scpdr |= SCPDR_TP_SCAN_Y; 623 scpdr &= ~SCPDR_TP_SCAN_X; /* pull low to scan */ 624 _reg_write_1(SH7709_SCPDR, scpdr); 625 delay(10); 626 627 *rawxp = adc_sample_channel(ADC_CHANNEL_TP_X); 628 629 /* restore SCPDR */ 630 scpdr = _reg_read_1(SH7709_SCPDR); 631 scpdr |= SCPDR_TP_SCAN_X; 632 scpdr &= ~SCPDR_TP_SCAN_ENABLE; 633 _reg_write_1(SH7709_SCPDR, scpdr); 634 } 635 636 637 /* 638 * Check if the (rawx, rawy) is inside one of the 4 hard icons. 639 * Return the icon number 1..4, or 0 if not inside an icon. 640 */ 641 static int 642 j6x0tp_get_hard_icon(int rawx, int rawy) 643 { 644 if (rawx <= J6X0TP_FB_RIGHT) 645 return (0); 646 647 if (rawy < J6X0TP_HARD_ICON_MAX_Y(1)) 648 return (1); 649 else if (rawy < J6X0TP_HARD_ICON_MAX_Y(2)) 650 return (2); 651 else if (rawy < J6X0TP_HARD_ICON_MAX_Y(3)) 652 return (3); 653 else 654 return (4); 655 } 656 657 658 static int 659 j6x0tp_wsmouse_ioctl(void *arg, u_long cmd, void *data, int flag, lwp_t *l) 660 { 661 struct j6x0tp_softc *sc = arg; 662 663 return hpc_tpanel_ioctl(&sc->sc_tpcalib, cmd, data, flag, l); 664 } 665 666 667 static int 668 j6x0tp_wskbd_ioctl(void *arg, u_long cmd, void *data, int flag, lwp_t *l) 669 { 670 /* struct j6x0tp_softc *sc = arg; */ 671 672 switch (cmd) { 673 case WSKBDIO_GTYPE: 674 *(int *)data = WSKBD_TYPE_HPC_BTN; /* may be use new type? */ 675 return (0); 676 677 case WSKBDIO_GETLEDS: 678 *(int *)data = 0; 679 return (0); 680 681 default: 682 return (EPASSTHROUGH); 683 } 684 } 685 686 687 static void 688 j6x0tp_wskbd_set_leds(void *arg, int leds) 689 { 690 691 /* nothing to do*/ 692 return; 693 } 694