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