1 1.22 thorpej /* $NetBSD: zkbd.c,v 1.22 2021/08/07 16:19:08 thorpej Exp $ */ 2 1.1 ober /* $OpenBSD: zaurus_kbd.c,v 1.28 2005/12/21 20:36:03 deraadt Exp $ */ 3 1.1 ober 4 1.1 ober /* 5 1.1 ober * Copyright (c) 2005 Dale Rahn <drahn (at) openbsd.org> 6 1.1 ober * 7 1.1 ober * Permission to use, copy, modify, and distribute this software for any 8 1.1 ober * purpose with or without fee is hereby granted, provided that the above 9 1.1 ober * copyright notice and this permission notice appear in all copies. 10 1.1 ober * 11 1.1 ober * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 1.1 ober * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 1.1 ober * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 1.1 ober * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 1.1 ober * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 1.1 ober * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 1.1 ober * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 1.1 ober */ 19 1.1 ober 20 1.1 ober #include <sys/cdefs.h> 21 1.22 thorpej __KERNEL_RCSID(0, "$NetBSD: zkbd.c,v 1.22 2021/08/07 16:19:08 thorpej Exp $"); 22 1.1 ober 23 1.1 ober #include "opt_wsdisplay_compat.h" 24 1.1 ober #if 0 /* XXX */ 25 1.1 ober #include "apm.h" 26 1.1 ober #endif 27 1.15 tsutsui #include "lcdctl.h" 28 1.1 ober 29 1.1 ober #include <sys/param.h> 30 1.1 ober #include <sys/systm.h> 31 1.1 ober #include <sys/device.h> 32 1.20 thorpej #include <sys/kmem.h> 33 1.1 ober #include <sys/kernel.h> 34 1.1 ober #include <sys/proc.h> 35 1.1 ober #include <sys/signalvar.h> 36 1.1 ober #include <sys/callout.h> 37 1.1 ober 38 1.1 ober #include <arm/xscale/pxa2x0reg.h> 39 1.1 ober #include <arm/xscale/pxa2x0_gpio.h> 40 1.1 ober 41 1.1 ober #include <dev/wscons/wsconsio.h> 42 1.1 ober #include <dev/wscons/wskbdvar.h> 43 1.1 ober #include <dev/wscons/wsksymdef.h> 44 1.1 ober #include <dev/wscons/wsksymvar.h> 45 1.1 ober 46 1.12 nonaka #include <zaurus/zaurus/zaurus_var.h> 47 1.1 ober #include <zaurus/dev/zkbdmap.h> 48 1.15 tsutsui #if NLCDCTL > 0 49 1.15 tsutsui #include <zaurus/dev/lcdctlvar.h> 50 1.15 tsutsui #endif 51 1.1 ober 52 1.1 ober static const int gpio_sense_pins_c3000[] = { 53 1.1 ober 12, 54 1.1 ober 17, 55 1.1 ober 91, 56 1.1 ober 34, 57 1.1 ober 36, 58 1.1 ober 38, 59 1.1 ober 39, 60 1.1 ober -1 61 1.1 ober }; 62 1.1 ober 63 1.1 ober static const int gpio_strobe_pins_c3000[] = { 64 1.1 ober 88, 65 1.1 ober 23, 66 1.1 ober 24, 67 1.1 ober 25, 68 1.1 ober 26, 69 1.1 ober 27, 70 1.1 ober 52, 71 1.1 ober 103, 72 1.1 ober 107, 73 1.1 ober -1, 74 1.1 ober 108, 75 1.1 ober 114 76 1.1 ober }; 77 1.1 ober 78 1.18 nonaka static const int stuck_keys_c3000[] = { 79 1.18 nonaka 1, 7, 15, 22, 23, 31, 39, 47, 80 1.18 nonaka 53, 55, 60, 63, 66, 67, 69, 71, 81 1.18 nonaka 72, 73, 74, 75, 76, 77, 78, 79, 82 1.18 nonaka 82, 85, 86, 87, 90, 91, 92, 94, 83 1.18 nonaka 95 84 1.18 nonaka }; 85 1.18 nonaka 86 1.16 tsutsui static const int gpio_sense_pins_c860[] = { 87 1.16 tsutsui 58, 88 1.16 tsutsui 59, 89 1.16 tsutsui 60, 90 1.16 tsutsui 61, 91 1.16 tsutsui 62, 92 1.16 tsutsui 63, 93 1.16 tsutsui 64, 94 1.16 tsutsui 65 95 1.16 tsutsui }; 96 1.16 tsutsui 97 1.16 tsutsui static const int gpio_strobe_pins_c860[] = { 98 1.16 tsutsui 66, 99 1.16 tsutsui 67, 100 1.16 tsutsui 68, 101 1.16 tsutsui 69, 102 1.16 tsutsui 70, 103 1.16 tsutsui 71, 104 1.16 tsutsui 72, 105 1.16 tsutsui 73, 106 1.16 tsutsui 74, 107 1.16 tsutsui 75, 108 1.16 tsutsui 76, 109 1.16 tsutsui 77 110 1.16 tsutsui }; 111 1.16 tsutsui 112 1.18 nonaka static const int stuck_keys_c860[] = { 113 1.18 nonaka 0, 1, 47, 53, 55, 60, 63, 66, 114 1.18 nonaka 67, 69, 71, 72, 73, 74, 76, 77, 115 1.18 nonaka 78, 79, 80, 81, 82, 83, 85, 86, 116 1.18 nonaka 87, 88, 89, 90, 91, 92, 94, 95 117 1.1 ober }; 118 1.1 ober 119 1.1 ober #define REP_DELAY1 400 120 1.1 ober #define REP_DELAYN 100 121 1.1 ober 122 1.1 ober struct zkbd_softc { 123 1.8 nonaka device_t sc_dev; 124 1.1 ober 125 1.1 ober const int *sc_sense_array; 126 1.1 ober const int *sc_strobe_array; 127 1.16 tsutsui const int *sc_stuck_keys; 128 1.1 ober int sc_nsense; 129 1.1 ober int sc_nstrobe; 130 1.16 tsutsui int sc_nstuck; 131 1.1 ober 132 1.1 ober short sc_onkey_pin; 133 1.1 ober short sc_sync_pin; 134 1.1 ober short sc_swa_pin; 135 1.1 ober short sc_swb_pin; 136 1.1 ober char *sc_okeystate; 137 1.1 ober char *sc_keystate; 138 1.1 ober char sc_hinge; /* 0=open, 1=nonsense, 2=backwards, 3=closed */ 139 1.1 ober char sc_maxkbdcol; 140 1.1 ober 141 1.1 ober struct callout sc_roll_to; 142 1.1 ober 143 1.1 ober /* console stuff */ 144 1.1 ober int sc_polling; 145 1.1 ober int sc_pollUD; 146 1.1 ober int sc_pollkey; 147 1.1 ober 148 1.1 ober /* wskbd bits */ 149 1.17 chs device_t sc_wskbddev; 150 1.16 tsutsui struct wskbd_mapdata *sc_keymapdata; 151 1.1 ober int sc_rawkbd; 152 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 153 1.1 ober const char *sc_xt_keymap; 154 1.1 ober struct callout sc_rawrepeat_ch; 155 1.1 ober #define MAXKEYS 20 156 1.1 ober char sc_rep[MAXKEYS]; 157 1.1 ober int sc_nrep; 158 1.1 ober #endif 159 1.1 ober }; 160 1.1 ober 161 1.2 peter static struct zkbd_softc *zkbd_sc; 162 1.1 ober 163 1.8 nonaka static int zkbd_match(device_t, cfdata_t, void *); 164 1.8 nonaka static void zkbd_attach(device_t, device_t, void *); 165 1.1 ober 166 1.8 nonaka CFATTACH_DECL_NEW(zkbd, sizeof(struct zkbd_softc), 167 1.1 ober zkbd_match, zkbd_attach, NULL, NULL); 168 1.1 ober 169 1.18 nonaka static int zkbd_irq_c3000(void *v); 170 1.18 nonaka static int zkbd_irq_c860(void *v); 171 1.1 ober static void zkbd_poll(void *v); 172 1.1 ober static int zkbd_on(void *v); 173 1.1 ober static int zkbd_sync(void *v); 174 1.1 ober static int zkbd_hinge(void *v); 175 1.11 dyoung static bool zkbd_resume(device_t dv, const pmf_qual_t *); 176 1.1 ober 177 1.1 ober int zkbd_modstate; 178 1.1 ober 179 1.1 ober static int zkbd_enable(void *, int); 180 1.1 ober static void zkbd_set_leds(void *, int); 181 1.3 christos static int zkbd_ioctl(void *, u_long, void *, int, struct lwp *); 182 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 183 1.1 ober static void zkbd_rawrepeat(void *v); 184 1.1 ober #endif 185 1.1 ober 186 1.2 peter static struct wskbd_accessops zkbd_accessops = { 187 1.1 ober zkbd_enable, 188 1.1 ober zkbd_set_leds, 189 1.1 ober zkbd_ioctl, 190 1.1 ober }; 191 1.1 ober 192 1.1 ober static void zkbd_cngetc(void *, u_int *, int *); 193 1.1 ober static void zkbd_cnpollc(void *, int); 194 1.1 ober 195 1.2 peter static struct wskbd_consops zkbd_consops = { 196 1.1 ober zkbd_cngetc, 197 1.1 ober zkbd_cnpollc, 198 1.1 ober }; 199 1.1 ober 200 1.2 peter static struct wskbd_mapdata zkbd_keymapdata = { 201 1.1 ober zkbd_keydesctab, 202 1.1 ober KB_US, 203 1.1 ober }; 204 1.1 ober 205 1.16 tsutsui static struct wskbd_mapdata zkbd_keymapdata_c860 = { 206 1.16 tsutsui zkbd_keydesctab_c860, 207 1.16 tsutsui KB_US, 208 1.16 tsutsui }; 209 1.16 tsutsui 210 1.1 ober static int 211 1.8 nonaka zkbd_match(device_t parent, cfdata_t cf, void *aux) 212 1.1 ober { 213 1.1 ober 214 1.4 nonaka if (zkbd_sc) 215 1.4 nonaka return 0; 216 1.4 nonaka 217 1.1 ober return 1; 218 1.1 ober } 219 1.1 ober 220 1.1 ober static void 221 1.8 nonaka zkbd_attach(device_t parent, device_t self, void *aux) 222 1.1 ober { 223 1.8 nonaka struct zkbd_softc *sc = device_private(self); 224 1.1 ober struct wskbddev_attach_args a; 225 1.1 ober int pin, i; 226 1.1 ober 227 1.8 nonaka sc->sc_dev = self; 228 1.2 peter zkbd_sc = sc; 229 1.4 nonaka 230 1.8 nonaka aprint_normal("\n"); 231 1.8 nonaka aprint_naive("\n"); 232 1.4 nonaka 233 1.1 ober sc->sc_polling = 0; 234 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 235 1.1 ober sc->sc_rawkbd = 0; 236 1.1 ober #endif 237 1.1 ober 238 1.6 nonaka callout_init(&sc->sc_roll_to, 0); 239 1.6 nonaka callout_setfunc(&sc->sc_roll_to, zkbd_poll, sc); 240 1.6 nonaka #ifdef WSDISPLAY_COMPAT_RAWKBD 241 1.6 nonaka callout_init(&sc->sc_rawrepeat_ch, 0); 242 1.6 nonaka callout_setfunc(&sc->sc_rawrepeat_ch, zkbd_rawrepeat, sc); 243 1.6 nonaka #endif 244 1.6 nonaka 245 1.12 nonaka if (ZAURUS_ISC1000 || ZAURUS_ISC3000) { 246 1.1 ober sc->sc_sense_array = gpio_sense_pins_c3000; 247 1.1 ober sc->sc_strobe_array = gpio_strobe_pins_c3000; 248 1.2 peter sc->sc_nsense = __arraycount(gpio_sense_pins_c3000); 249 1.2 peter sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c3000); 250 1.18 nonaka sc->sc_stuck_keys = stuck_keys_c3000; 251 1.18 nonaka sc->sc_nstuck = __arraycount(stuck_keys_c3000); 252 1.1 ober sc->sc_maxkbdcol = 10; 253 1.1 ober sc->sc_onkey_pin = 95; 254 1.1 ober sc->sc_sync_pin = 16; 255 1.1 ober sc->sc_swa_pin = 97; 256 1.1 ober sc->sc_swb_pin = 96; 257 1.16 tsutsui sc->sc_keymapdata = &zkbd_keymapdata; 258 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 259 1.1 ober sc->sc_xt_keymap = xt_keymap; 260 1.1 ober #endif 261 1.16 tsutsui } else if (ZAURUS_ISC860) { 262 1.16 tsutsui sc->sc_sense_array = gpio_sense_pins_c860; 263 1.16 tsutsui sc->sc_strobe_array = gpio_strobe_pins_c860; 264 1.16 tsutsui sc->sc_nsense = __arraycount(gpio_sense_pins_c860); 265 1.16 tsutsui sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c860); 266 1.18 nonaka sc->sc_stuck_keys = stuck_keys_c860; 267 1.18 nonaka sc->sc_nstuck = __arraycount(stuck_keys_c860); 268 1.16 tsutsui sc->sc_maxkbdcol = 0; 269 1.16 tsutsui sc->sc_onkey_pin = -1; 270 1.16 tsutsui sc->sc_sync_pin = -1; 271 1.16 tsutsui sc->sc_swa_pin = -1; 272 1.16 tsutsui sc->sc_swb_pin = -1; 273 1.16 tsutsui sc->sc_keymapdata = &zkbd_keymapdata_c860; 274 1.16 tsutsui #ifdef WSDISPLAY_COMPAT_RAWKBD 275 1.16 tsutsui sc->sc_xt_keymap = xt_keymap_c860; 276 1.16 tsutsui #endif 277 1.4 nonaka } else { 278 1.4 nonaka /* XXX */ 279 1.4 nonaka return; 280 1.4 nonaka } 281 1.4 nonaka 282 1.9 nonaka if (!pmf_device_register(sc->sc_dev, NULL, zkbd_resume)) 283 1.9 nonaka aprint_error_dev(sc->sc_dev, 284 1.9 nonaka "couldn't establish power handler\n"); 285 1.1 ober 286 1.20 thorpej sc->sc_okeystate = kmem_zalloc(sc->sc_nsense * sc->sc_nstrobe, 287 1.20 thorpej KM_SLEEP); 288 1.20 thorpej sc->sc_keystate = kmem_zalloc(sc->sc_nsense * sc->sc_nstrobe, 289 1.20 thorpej KM_SLEEP); 290 1.1 ober 291 1.1 ober /* set all the strobe bits */ 292 1.1 ober for (i = 0; i < sc->sc_nstrobe; i++) { 293 1.1 ober pin = sc->sc_strobe_array[i]; 294 1.4 nonaka if (pin == -1) 295 1.1 ober continue; 296 1.1 ober pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT); 297 1.1 ober } 298 1.2 peter 299 1.1 ober /* set all the sense bits */ 300 1.1 ober for (i = 0; i < sc->sc_nsense; i++) { 301 1.1 ober pin = sc->sc_sense_array[i]; 302 1.4 nonaka if (pin == -1) 303 1.1 ober continue; 304 1.1 ober pxa2x0_gpio_set_function(pin, GPIO_IN); 305 1.18 nonaka if (ZAURUS_ISC1000 || ZAURUS_ISC3000) { 306 1.18 nonaka pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH, 307 1.18 nonaka IPL_TTY, zkbd_irq_c3000, sc); 308 1.18 nonaka } else if (ZAURUS_ISC860) { 309 1.18 nonaka pxa2x0_gpio_intr_establish(pin, IST_EDGE_RISING, 310 1.18 nonaka IPL_TTY, zkbd_irq_c860, sc); 311 1.18 nonaka } 312 1.1 ober } 313 1.2 peter 314 1.16 tsutsui if (sc->sc_onkey_pin >= 0) 315 1.16 tsutsui pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH, 316 1.16 tsutsui IPL_TTY, zkbd_on, sc); 317 1.16 tsutsui if (sc->sc_sync_pin >= 0) 318 1.16 tsutsui pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING, 319 1.16 tsutsui IPL_TTY, zkbd_sync, sc); 320 1.16 tsutsui if (sc->sc_swa_pin >= 0) 321 1.16 tsutsui pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH, 322 1.16 tsutsui IPL_TTY, zkbd_hinge, sc); 323 1.16 tsutsui if (sc->sc_swb_pin >= 0) 324 1.16 tsutsui pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH, 325 1.16 tsutsui IPL_TTY, zkbd_hinge, sc); 326 1.1 ober 327 1.1 ober if (glass_console) { 328 1.16 tsutsui wskbd_cnattach(&zkbd_consops, sc, sc->sc_keymapdata); 329 1.1 ober a.console = 1; 330 1.1 ober } else { 331 1.1 ober a.console = 0; 332 1.1 ober } 333 1.16 tsutsui a.keymap = sc->sc_keymapdata; 334 1.1 ober a.accessops = &zkbd_accessops; 335 1.1 ober a.accesscookie = sc; 336 1.1 ober 337 1.1 ober zkbd_hinge(sc); /* to initialize sc_hinge */ 338 1.1 ober 339 1.22 thorpej sc->sc_wskbddev = config_found(self, &a, wskbddevprint, CFARGS_NONE); 340 1.1 ober } 341 1.1 ober 342 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 343 1.1 ober static void 344 1.1 ober zkbd_rawrepeat(void *v) 345 1.1 ober { 346 1.1 ober struct zkbd_softc *sc = (struct zkbd_softc *)v; 347 1.1 ober int s; 348 1.1 ober 349 1.1 ober s = spltty(); 350 1.1 ober wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep); 351 1.1 ober splx(s); 352 1.1 ober callout_schedule(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000); 353 1.1 ober } 354 1.1 ober #endif 355 1.1 ober 356 1.1 ober /* XXX only deal with keys that can be pressed when display is open? */ 357 1.1 ober /* XXX are some not in the array? */ 358 1.1 ober /* handle keypress interrupt */ 359 1.1 ober static int 360 1.18 nonaka zkbd_irq_c3000(void *v) 361 1.1 ober { 362 1.1 ober 363 1.1 ober zkbd_poll(v); 364 1.1 ober 365 1.1 ober return 1; 366 1.1 ober } 367 1.1 ober 368 1.18 nonaka /* Avoid chattering only for SL-C7x0/860 */ 369 1.18 nonaka static int 370 1.18 nonaka zkbd_irq_c860(void *v) 371 1.18 nonaka { 372 1.18 nonaka struct zkbd_softc *sc = (struct zkbd_softc *)v; 373 1.18 nonaka 374 1.18 nonaka if (!callout_pending(&sc->sc_roll_to)) { 375 1.18 nonaka zkbd_poll(v); 376 1.18 nonaka } 377 1.18 nonaka 378 1.18 nonaka return 1; 379 1.18 nonaka } 380 1.18 nonaka 381 1.1 ober static void 382 1.1 ober zkbd_poll(void *v) 383 1.1 ober { 384 1.1 ober struct zkbd_softc *sc = (struct zkbd_softc *)v; 385 1.2 peter int i, j, col, pin, type, keysdown = 0; 386 1.14 nonaka int stuck; 387 1.1 ober int keystate; 388 1.2 peter int s; 389 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 390 1.14 nonaka int npress = 0, ncbuf = 0, c; 391 1.2 peter char cbuf[MAXKEYS * 2]; 392 1.1 ober #endif 393 1.1 ober 394 1.1 ober s = spltty(); 395 1.1 ober 396 1.1 ober /* discharge all */ 397 1.1 ober for (i = 0; i < sc->sc_nstrobe; i++) { 398 1.1 ober pin = sc->sc_strobe_array[i]; 399 1.4 nonaka if (pin == -1) 400 1.4 nonaka continue; 401 1.4 nonaka pxa2x0_gpio_clear_bit(pin); 402 1.4 nonaka pxa2x0_gpio_set_dir(pin, GPIO_IN); 403 1.1 ober } 404 1.1 ober 405 1.2 peter delay(10); 406 1.2 peter for (col = 0; col < sc->sc_nstrobe; col++) { 407 1.2 peter pin = sc->sc_strobe_array[col]; 408 1.2 peter if (pin == -1) 409 1.1 ober continue; 410 1.1 ober 411 1.1 ober /* activate_col */ 412 1.1 ober pxa2x0_gpio_set_bit(pin); 413 1.1 ober pxa2x0_gpio_set_dir(pin, GPIO_OUT); 414 1.1 ober 415 1.1 ober /* wait activate delay */ 416 1.1 ober delay(10); 417 1.1 ober 418 1.1 ober /* read row */ 419 1.1 ober for (i = 0; i < sc->sc_nsense; i++) { 420 1.1 ober int bit; 421 1.1 ober 422 1.4 nonaka if (sc->sc_sense_array[i] == -1) 423 1.1 ober continue; 424 1.1 ober bit = pxa2x0_gpio_get_bit(sc->sc_sense_array[i]); 425 1.1 ober if (bit && sc->sc_hinge && col < sc->sc_maxkbdcol) 426 1.1 ober continue; 427 1.1 ober sc->sc_keystate[i + (col * sc->sc_nsense)] = bit; 428 1.1 ober } 429 1.1 ober 430 1.1 ober /* reset_col */ 431 1.1 ober pxa2x0_gpio_set_dir(pin, GPIO_IN); 432 1.2 peter 433 1.1 ober /* wait discharge delay */ 434 1.1 ober delay(10); 435 1.1 ober } 436 1.2 peter 437 1.1 ober /* charge all */ 438 1.1 ober for (i = 0; i < sc->sc_nstrobe; i++) { 439 1.1 ober pin = sc->sc_strobe_array[i]; 440 1.4 nonaka if (pin == -1) 441 1.4 nonaka continue; 442 1.4 nonaka pxa2x0_gpio_set_bit(pin); 443 1.4 nonaka pxa2x0_gpio_set_dir(pin, GPIO_OUT); 444 1.1 ober } 445 1.1 ober 446 1.1 ober /* force the irqs to clear as we have just played with them. */ 447 1.2 peter for (i = 0; i < sc->sc_nsense; i++) { 448 1.4 nonaka pin = sc->sc_sense_array[i]; 449 1.4 nonaka if (pin == -1) 450 1.4 nonaka continue; 451 1.4 nonaka pxa2x0_gpio_clear_intr(pin); 452 1.2 peter } 453 1.1 ober 454 1.1 ober /* process after resetting interrupt */ 455 1.1 ober zkbd_modstate = ( 456 1.1 ober (sc->sc_keystate[84] ? (1 << 0) : 0) | /* shift */ 457 1.1 ober (sc->sc_keystate[93] ? (1 << 1) : 0) | /* Fn */ 458 1.1 ober (sc->sc_keystate[14] ? (1 << 2) : 0)); /* 'alt' */ 459 1.1 ober 460 1.2 peter for (i = 0; i < sc->sc_nsense * sc->sc_nstrobe; i++) { 461 1.14 nonaka stuck = 0; 462 1.1 ober /* extend xt_keymap to do this faster. */ 463 1.1 ober /* ignore 'stuck' keys' */ 464 1.16 tsutsui for (j = 0; j < sc->sc_nstuck; j++) { 465 1.16 tsutsui if (sc->sc_stuck_keys[j] == i) { 466 1.2 peter stuck = 1; 467 1.1 ober break; 468 1.1 ober } 469 1.1 ober } 470 1.1 ober if (stuck) 471 1.1 ober continue; 472 1.2 peter 473 1.1 ober keystate = sc->sc_keystate[i]; 474 1.1 ober keysdown |= keystate; /* if any keys held */ 475 1.1 ober 476 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 477 1.14 nonaka if (sc->sc_polling == 0 && sc->sc_rawkbd) { 478 1.14 nonaka if ((keystate) || (sc->sc_okeystate[i] != keystate)) { 479 1.14 nonaka c = sc->sc_xt_keymap[i]; 480 1.1 ober if (c & 0x80) { 481 1.1 ober cbuf[ncbuf++] = 0xe0; 482 1.1 ober } 483 1.1 ober cbuf[ncbuf] = c & 0x7f; 484 1.1 ober 485 1.1 ober if (keystate) { 486 1.1 ober if (c & 0x80) { 487 1.1 ober sc->sc_rep[npress++] = 0xe0; 488 1.1 ober } 489 1.1 ober sc->sc_rep[npress++] = c & 0x7f; 490 1.1 ober } else { 491 1.1 ober cbuf[ncbuf] |= 0x80; 492 1.1 ober } 493 1.1 ober ncbuf++; 494 1.1 ober sc->sc_okeystate[i] = keystate; 495 1.1 ober } 496 1.1 ober } 497 1.1 ober #endif 498 1.1 ober 499 1.14 nonaka if ((!sc->sc_rawkbd) && (sc->sc_okeystate[i] != keystate)) { 500 1.1 ober type = keystate ? WSCONS_EVENT_KEY_DOWN : 501 1.1 ober WSCONS_EVENT_KEY_UP; 502 1.1 ober 503 1.1 ober if (sc->sc_polling) { 504 1.1 ober sc->sc_pollkey = i; 505 1.1 ober sc->sc_pollUD = type; 506 1.1 ober } else { 507 1.1 ober wskbd_input(sc->sc_wskbddev, type, i); 508 1.1 ober } 509 1.1 ober 510 1.1 ober sc->sc_okeystate[i] = keystate; 511 1.1 ober } 512 1.1 ober } 513 1.1 ober 514 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 515 1.14 nonaka if (sc->sc_polling == 0 && sc->sc_rawkbd) { 516 1.1 ober wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf); 517 1.1 ober sc->sc_nrep = npress; 518 1.1 ober if (npress != 0) 519 1.1 ober callout_schedule(&sc->sc_rawrepeat_ch, 520 1.1 ober hz * REP_DELAY1 / 1000); 521 1.1 ober else 522 1.1 ober callout_stop(&sc->sc_rawrepeat_ch); 523 1.1 ober } 524 1.1 ober #endif 525 1.1 ober if (keysdown) 526 1.1 ober callout_schedule(&sc->sc_roll_to, hz * REP_DELAYN / 1000 / 2); 527 1.1 ober else 528 1.1 ober callout_stop(&sc->sc_roll_to); /* always cancel? */ 529 1.1 ober 530 1.1 ober splx(s); 531 1.1 ober } 532 1.1 ober 533 1.1 ober #if NAPM > 0 534 1.1 ober extern int kbd_reset; 535 1.1 ober extern int apm_suspends; 536 1.1 ober static int zkbdondown; /* on key is pressed */ 537 1.1 ober static struct timeval zkbdontv = { 0, 0 }; /* last on key event */ 538 1.1 ober const struct timeval zkbdhalttv = { 3, 0 }; /* 3s for safe shutdown */ 539 1.1 ober const struct timeval zkbdsleeptv = { 0, 250000 }; /* .25s for suspend */ 540 1.1 ober extern int lid_suspend; 541 1.1 ober #endif 542 1.1 ober 543 1.1 ober static int 544 1.1 ober zkbd_on(void *v) 545 1.1 ober { 546 1.1 ober #if NAPM > 0 547 1.1 ober struct zkbd_softc *sc = (struct zkbd_softc *)v; 548 1.16 tsutsui int down; 549 1.16 tsutsui 550 1.16 tsutsui if (sc->sc_onkey_pin < 0) 551 1.16 tsutsui return 1; 552 1.16 tsutsui 553 1.16 tsutsui down = pxa2x0_gpio_get_bit(sc->sc_onkey_pin) ? 1 : 0; 554 1.1 ober 555 1.1 ober /* 556 1.1 ober * Change run mode depending on how long the key is held down. 557 1.1 ober * Ignore the key if it gets pressed while the lid is closed. 558 1.1 ober * 559 1.1 ober * Keys can bounce and we have to work around missed interrupts. 560 1.1 ober * Only the second edge is detected upon exit from sleep mode. 561 1.1 ober */ 562 1.1 ober if (down) { 563 1.1 ober if (sc->sc_hinge == 3) { 564 1.1 ober zkbdondown = 0; 565 1.1 ober } else { 566 1.1 ober microuptime(&zkbdontv); 567 1.1 ober zkbdondown = 1; 568 1.1 ober } 569 1.1 ober } else if (zkbdondown) { 570 1.1 ober if (ratecheck(&zkbdontv, &zkbdhalttv)) { 571 1.1 ober if (kbd_reset == 1) { 572 1.1 ober kbd_reset = 0; 573 1.1 ober psignal(initproc, SIGUSR1); 574 1.1 ober } 575 1.1 ober } else if (ratecheck(&zkbdontv, &zkbdsleeptv)) { 576 1.1 ober apm_suspends++; 577 1.1 ober } 578 1.1 ober zkbdondown = 0; 579 1.1 ober } 580 1.1 ober #endif 581 1.1 ober return 1; 582 1.1 ober } 583 1.1 ober 584 1.1 ober static int 585 1.1 ober zkbd_sync(void *v) 586 1.1 ober { 587 1.1 ober 588 1.1 ober return 1; 589 1.1 ober } 590 1.1 ober 591 1.1 ober static int 592 1.1 ober zkbd_hinge(void *v) 593 1.1 ober { 594 1.1 ober struct zkbd_softc *sc = (struct zkbd_softc *)v; 595 1.16 tsutsui int a, b; 596 1.16 tsutsui 597 1.16 tsutsui if (sc->sc_swa_pin < 0 || sc->sc_swb_pin < 0) 598 1.16 tsutsui return 1; 599 1.16 tsutsui 600 1.16 tsutsui a = pxa2x0_gpio_get_bit(sc->sc_swa_pin) ? 1 : 0; 601 1.16 tsutsui b = pxa2x0_gpio_get_bit(sc->sc_swb_pin) ? 2 : 0; 602 1.1 ober 603 1.1 ober sc->sc_hinge = a | b; 604 1.1 ober 605 1.1 ober if (sc->sc_hinge == 3) { 606 1.1 ober #if NAPM > 0 607 1.1 ober if (lid_suspend) 608 1.1 ober apm_suspends++; 609 1.1 ober #endif 610 1.15 tsutsui #if NLCDCTL > 0 611 1.15 tsutsui lcdctl_blank(true); 612 1.15 tsutsui #endif 613 1.1 ober } else { 614 1.15 tsutsui #if NLCDCTL > 0 615 1.15 tsutsui lcdctl_blank(false); 616 1.15 tsutsui #endif 617 1.1 ober } 618 1.1 ober 619 1.1 ober return 1; 620 1.1 ober } 621 1.1 ober 622 1.1 ober static int 623 1.1 ober zkbd_enable(void *v, int on) 624 1.1 ober { 625 1.1 ober 626 1.1 ober return 0; 627 1.1 ober } 628 1.1 ober 629 1.1 ober void 630 1.1 ober zkbd_set_leds(void *v, int on) 631 1.1 ober { 632 1.1 ober } 633 1.1 ober 634 1.1 ober static int 635 1.3 christos zkbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) 636 1.1 ober { 637 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 638 1.1 ober struct zkbd_softc *sc = (struct zkbd_softc *)v; 639 1.1 ober #endif 640 1.1 ober 641 1.1 ober switch (cmd) { 642 1.1 ober case WSKBDIO_GTYPE: 643 1.1 ober *(int *)data = WSKBD_TYPE_ZAURUS; 644 1.1 ober return 0; 645 1.1 ober 646 1.1 ober case WSKBDIO_SETLEDS: 647 1.1 ober return 0; 648 1.1 ober 649 1.1 ober case WSKBDIO_GETLEDS: 650 1.1 ober *(int *)data = 0; 651 1.1 ober return 0; 652 1.1 ober 653 1.1 ober #ifdef WSDISPLAY_COMPAT_RAWKBD 654 1.1 ober case WSKBDIO_SETMODE: 655 1.1 ober sc->sc_rawkbd = *(int *)data == WSKBD_RAW; 656 1.1 ober callout_stop(&sc->sc_rawrepeat_ch); 657 1.1 ober return 0; 658 1.1 ober #endif 659 1.1 ober 660 1.1 ober } 661 1.2 peter return EPASSTHROUGH; 662 1.1 ober } 663 1.1 ober 664 1.1 ober /* implement polling for zaurus_kbd */ 665 1.1 ober static void 666 1.1 ober zkbd_cngetc(void *v, u_int *type, int *data) 667 1.1 ober { 668 1.2 peter struct zkbd_softc *sc = (struct zkbd_softc *)zkbd_sc; 669 1.1 ober 670 1.1 ober sc->sc_pollkey = -1; 671 1.1 ober sc->sc_pollUD = -1; 672 1.1 ober sc->sc_polling = 1; 673 1.1 ober while (sc->sc_pollkey == -1) { 674 1.2 peter zkbd_poll(sc); 675 1.1 ober DELAY(10000); /* XXX */ 676 1.1 ober } 677 1.1 ober sc->sc_polling = 0; 678 1.1 ober *data = sc->sc_pollkey; 679 1.1 ober *type = sc->sc_pollUD; 680 1.1 ober } 681 1.1 ober 682 1.1 ober static void 683 1.1 ober zkbd_cnpollc(void *v, int on) 684 1.1 ober { 685 1.1 ober } 686 1.1 ober 687 1.9 nonaka static bool 688 1.11 dyoung zkbd_resume(device_t dv, const pmf_qual_t *qual) 689 1.1 ober { 690 1.9 nonaka struct zkbd_softc *sc = device_private(dv); 691 1.9 nonaka 692 1.9 nonaka zkbd_hinge(sc); 693 1.1 ober 694 1.9 nonaka return true; 695 1.1 ober } 696