1 /* $NetBSD: wzero3_kbd.c,v 1.5 2010/05/30 03:17:21 nonaka Exp $ */ 2 3 /* 4 * Copyright (c) 2008, 2009, 2010 NONAKA Kimihiro <nonaka@netbsd.org> 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: wzero3_kbd.c,v 1.5 2010/05/30 03:17:21 nonaka Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/device.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/callout.h> 38 39 #include <dev/sysmon/sysmonvar.h> 40 #include <dev/sysmon/sysmon_taskq.h> 41 42 #include <arm/xscale/pxa2x0cpu.h> 43 #include <arm/xscale/pxa2x0var.h> 44 #include <arm/xscale/pxa2x0_gpio.h> 45 46 #include <machine/bus.h> 47 #include <machine/bootinfo.h> 48 #include <machine/config_hook.h> 49 #include <machine/platid.h> 50 #include <machine/platid_mask.h> 51 52 #include <dev/hpc/hpckbdvar.h> 53 54 #include <arch/hpcarm/dev/wzero3_reg.h> 55 56 #ifdef DEBUG 57 #define DPRINTF(arg) printf arg 58 #else 59 #define DPRINTF(arg) /* nothing */ 60 #endif 61 62 #define CSR_READ1(r) bus_space_read_1(sc->sc_iot, sc->sc_ioh, (r)) 63 #define CSR_WRITE1(r,v) bus_space_write_1(sc->sc_iot, sc->sc_ioh, (r), (v)) 64 #define CSR_READ2(r) bus_space_read_2(sc->sc_iot, sc->sc_ioh, (r)) 65 #define CSR_WRITE2(r,v) bus_space_write_2(sc->sc_iot, sc->sc_ioh, (r), (v)) 66 #define CSR_READ4(r) bus_space_read_4(sc->sc_iot, sc->sc_ioh, (r)) 67 #define CSR_WRITE4(r,v) bus_space_write_4(sc->sc_iot, sc->sc_ioh, (r), (v)) 68 69 /* register */ 70 #define KBDCOL_L (0x00) /* Write */ 71 #define KBDCOL_U (0x04) /* Write */ 72 #define KBDCHARGE (0x08) /* Write */ 73 #define KBDDATA (0x08) /* Read */ 74 #define REGMAPSIZE 0x0c 75 76 #define KEYWAIT 20 /* us */ 77 78 #define WS003SH_NCOLUMN 12 79 #define WS003SH_NROW 7 80 81 struct wzero3kbd_softc { 82 device_t sc_dev; 83 84 bus_space_tag_t sc_iot; 85 bus_space_handle_t sc_ioh; 86 87 int sc_ncolumn; 88 int sc_nrow; 89 uint8_t *sc_okeystat; 90 uint8_t *sc_keystat; 91 92 void *sc_key_ih; 93 void *sc_power_ih; 94 void *sc_reset_ih; 95 96 int sc_key_pin; 97 int sc_power_pin; 98 int sc_reset_pin; 99 100 struct hpckbd_ic_if sc_if; 101 struct hpckbd_if *sc_hpckbd; 102 103 struct sysmon_pswitch sc_smpsw; /* for reset key */ 104 105 int sc_enabled; 106 107 /* polling stuff */ 108 struct callout sc_keyscan_ch; 109 int sc_interval; 110 #define KEY_INTERVAL 50 /* ms */ 111 112 #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5) 113 void *sc_test_ih; 114 int sc_test_pin; 115 int sc_nouse_pin; 116 int sc_nouse_pin2; 117 int sc_nouse_pin3; 118 int sc_bit; 119 #endif 120 }; 121 122 static int wzero3kbd_match(device_t, cfdata_t, void *); 123 static void wzero3kbd_attach(device_t, device_t, void *); 124 125 CFATTACH_DECL_NEW(wzero3kbd, sizeof(struct wzero3kbd_softc), 126 wzero3kbd_match, wzero3kbd_attach, NULL, NULL); 127 128 static int wzero3kbd_intr(void *arg); 129 #if defined(KEYTEST) 130 static int wzero3kbd_intr2(void *arg); 131 #endif 132 #if defined(KEYTEST3) 133 static int wzero3kbd_intr3(void *arg); 134 #endif 135 static void wzero3kbd_tick(void *arg); 136 static int wzero3kbd_power_intr(void *arg); 137 static int wzero3kbd_reset_intr(void *arg); 138 static int wzero3kbd_input_establish(void *arg, struct hpckbd_if *kbdif); 139 static void wzero3kbd_sysmon_reset_event(void *arg); 140 static int wzero3kbd_poll(void *arg); 141 static int wzero3kbd_poll1(void *arg); 142 143 /* 144 * WS003SH/WS004SH/WS007SH keyscan map 145 col#0 col#1 col#2 col#3 col#4 col#5 col#6 col#7 col#8 col#9 col#10 col#11 146 row#0: CTRL 1 3 5 6 7 9 0 BS (none) ROTATE CAMERA 147 row#1: (none) 2 4 r y 8 i o p (none) VOL- VOL+ 148 row#2: TAB q e t g u j k (none) (none) (none) (none) 149 row#3: (none) w s f v h m l (none) (none) SHIFT (none) 150 row#4: CALL a d c b n . (none) ENTER (none) WIN (none) 151 row#5: MAIL z x - SPACE / (none) UP (none) (none) LSOFT FN 152 row#6: IE MOJI (none) OK ACTION , LEFT DOWN RIGHT (none) RSOFT (none) 153 */ 154 155 /* 156 * WS011SH keyscan map 157 col#0 col#1 col#2 col#3 col#4 col#5 col#6 col#7 col#8 col#9 col#10 col#11 158 row#0 Ctrl (none) (none) (none) (none) (none) (none) (none) Del (none) ROTATE (none) 159 row#1 (none) (none) (none) R Y (none) I O P (none) (none) (none) 160 row#2 Tab Q E T G U J K (none) (none) (none) (none) 161 row#3 (none) W S F V H M L (none) (none) Shift (none) 162 row#4 (none) A D C B N . (none) Enter (none) (none) (none) 163 row#5 (none) Z X - Space / (none) UP (none) (none) (none) Fn 164 row#6 (none) MOJI HAN/ZEN OK (none) , LEFT DOWN RIGHT (none) (none) (none) 165 */ 166 167 /* 168 * WS020SH keyscan map 169 col#0 col#1 col#2 col#3 col#4 col#5 col#6 col#7 col#8 col#9 col#10 col#11 170 row#0 Ctrl (none) (none) (none) (none) (none) (none) (none) Del (none) ROTATE (none) 171 row#1 (none) (none) (none) R Y (none) I O P (none) MEDIA (none) 172 row#2 Tab Q E T G U J K (none) (none) (none) (none) 173 row#3 (none) W S F V H M L (none) (none) LShift (none) 174 row#4 (none) A D C B N . (none) Enter (none) RShift (none) 175 row#5 (none) Z X - Space / (none) UP (none) DOWN (none) Fn 176 row#6 (none) MOJI HAN/ZEN OK (none) , LEFT (none) RIGHT (none) (none) (none) 177 */ 178 179 static const struct wzero3kbd_model { 180 platid_mask_t *platid; 181 int key_pin; 182 int power_pin; 183 int reset_pin; 184 int ncolumn; 185 int nrow; 186 } wzero3kbd_table[] = { 187 /* WS003SH */ 188 { 189 &platid_mask_MACH_SHARP_WZERO3_WS003SH, 190 -1, /* XXX */ 191 GPIO_WS003SH_POWER_BUTTON, 192 -1, /* None */ 193 WS003SH_NCOLUMN, 194 WS003SH_NROW, 195 }, 196 /* WS004SH */ 197 { 198 &platid_mask_MACH_SHARP_WZERO3_WS004SH, 199 -1, /* XXX */ 200 GPIO_WS003SH_POWER_BUTTON, 201 -1, /* None */ 202 WS003SH_NCOLUMN, 203 WS003SH_NROW, 204 }, 205 /* WS007SH */ 206 { 207 &platid_mask_MACH_SHARP_WZERO3_WS007SH, 208 -1, /* XXX */ 209 GPIO_WS007SH_POWER_BUTTON, 210 GPIO_WS007SH_RESET_BUTTON, 211 WS003SH_NCOLUMN, 212 WS003SH_NROW, 213 }, 214 /* WS011SH */ 215 { 216 &platid_mask_MACH_SHARP_WZERO3_WS011SH, 217 -1, /* XXX */ 218 GPIO_WS011SH_POWER_BUTTON, 219 GPIO_WS011SH_RESET_BUTTON, 220 WS003SH_NCOLUMN, 221 WS003SH_NROW, 222 }, 223 /* WS020SH */ 224 { 225 &platid_mask_MACH_SHARP_WZERO3_WS020SH, 226 -1, /* XXX */ 227 GPIO_WS020SH_POWER_BUTTON, 228 GPIO_WS020SH_RESET_BUTTON, 229 WS003SH_NCOLUMN, 230 WS003SH_NROW, 231 }, 232 233 { NULL, -1, -1, -1, 0, 0, } 234 }; 235 236 static const struct wzero3kbd_model * 237 wzero3kbd_lookup(void) 238 { 239 const struct wzero3kbd_model *model; 240 241 for (model = wzero3kbd_table; model->platid != NULL; model++) { 242 if (platid_match(&platid, model->platid)) { 243 return model; 244 } 245 } 246 return NULL; 247 } 248 249 static int 250 wzero3kbd_match(struct device *parent, struct cfdata *cf, void *aux) 251 { 252 253 if (strcmp(cf->cf_name, "wzero3kbd") != 0) 254 return 0; 255 if (wzero3kbd_lookup() == NULL) 256 return 0; 257 return 1; 258 } 259 260 static void 261 wzero3kbd_attach(struct device *parent, struct device *self, void *aux) 262 { 263 struct wzero3kbd_softc *sc = device_private(self); 264 struct pxaip_attach_args *pxa = (struct pxaip_attach_args *)aux; 265 struct hpckbd_attach_args haa; 266 const struct wzero3kbd_model *model; 267 268 sc->sc_dev = self; 269 270 model = wzero3kbd_lookup(); 271 if (model == NULL) { 272 aprint_error(": unknown model\n"); 273 return; 274 } 275 276 aprint_normal(": keyboard\n"); 277 aprint_naive("\n"); 278 279 sc->sc_key_pin = model->key_pin; 280 sc->sc_power_pin = model->power_pin; 281 sc->sc_reset_pin = model->reset_pin; 282 sc->sc_ncolumn = model->ncolumn; 283 sc->sc_nrow = model->nrow; 284 285 sc->sc_iot = pxa->pxa_iot; 286 if (bus_space_map(sc->sc_iot, PXA2X0_CS2_START, REGMAPSIZE, 0, 287 &sc->sc_ioh)) { 288 aprint_error_dev(self, "couldn't map registers.\n"); 289 return; 290 } 291 292 sc->sc_okeystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF, 293 M_NOWAIT | M_ZERO); 294 sc->sc_keystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF, 295 M_NOWAIT | M_ZERO); 296 if (sc->sc_okeystat == NULL || sc->sc_keystat == NULL) { 297 aprint_error_dev(self, "couldn't alloc memory.\n"); 298 if (sc->sc_okeystat) 299 free(sc->sc_okeystat, M_DEVBUF); 300 if (sc->sc_keystat) 301 free(sc->sc_keystat, M_DEVBUF); 302 return; 303 } 304 305 sc->sc_if.hii_ctx = sc; 306 sc->sc_if.hii_establish = wzero3kbd_input_establish; 307 sc->sc_if.hii_poll = wzero3kbd_poll; 308 309 /* Attach console if not using serial. */ 310 if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) 311 hpckbd_cnattach(&sc->sc_if); 312 313 /* Install interrupt handler. */ 314 if (sc->sc_key_pin >= 0) { 315 pxa2x0_gpio_set_function(sc->sc_key_pin, GPIO_IN); 316 sc->sc_key_ih = pxa2x0_gpio_intr_establish(sc->sc_key_pin, 317 IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr, sc); 318 if (sc->sc_key_ih == NULL) { 319 aprint_error_dev(sc->sc_dev, 320 "couldn't establish key interrupt\n"); 321 } 322 } else { 323 sc->sc_interval = KEY_INTERVAL / (1000 / hz); 324 if (sc->sc_interval < 1) 325 sc->sc_interval = 1; 326 callout_init(&sc->sc_keyscan_ch, 0); 327 callout_reset(&sc->sc_keyscan_ch, sc->sc_interval, 328 wzero3kbd_tick, sc); 329 } 330 331 /* power key */ 332 if (sc->sc_power_pin >= 0) { 333 pxa2x0_gpio_set_function(sc->sc_power_pin, GPIO_IN); 334 sc->sc_power_ih = pxa2x0_gpio_intr_establish( 335 sc->sc_power_pin, IST_EDGE_BOTH, IPL_TTY, 336 wzero3kbd_power_intr, sc); 337 if (sc->sc_power_ih == NULL) { 338 aprint_error_dev(sc->sc_dev, 339 "couldn't establish power key interrupt\n"); 340 } 341 } 342 343 /* reset button */ 344 if (sc->sc_reset_pin >= 0) { 345 pxa2x0_gpio_set_function(sc->sc_reset_pin, GPIO_IN); 346 sc->sc_reset_ih = pxa2x0_gpio_intr_establish( 347 sc->sc_reset_pin, IST_EDGE_BOTH, IPL_TTY, 348 wzero3kbd_reset_intr, sc); 349 if (sc->sc_reset_ih == NULL) { 350 aprint_error_dev(sc->sc_dev, 351 "couldn't establish reset key interrupt\n"); 352 } 353 354 sc->sc_smpsw.smpsw_name = device_xname(self); 355 sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET; 356 if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) { 357 aprint_error_dev(sc->sc_dev, 358 "unable to register reset event handler\n"); 359 } 360 } 361 362 /* Attach hpckbd. */ 363 haa.haa_ic = &sc->sc_if; 364 config_found(self, &haa, hpckbd_print); 365 366 #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5) 367 sc->sc_test_ih = NULL; 368 sc->sc_test_pin = -1; 369 sc->sc_nouse_pin = -1; 370 sc->sc_nouse_pin2 = -1; 371 sc->sc_nouse_pin3 = -1; 372 sc->sc_bit = 0x01; 373 if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH) 374 || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) { 375 sc->sc_nouse_pin = GPIO_WS003SH_SD_DETECT; /* SD_DETECT */ 376 sc->sc_nouse_pin2 = 86; /* Vsync? */ 377 sc->sc_nouse_pin3 = 89; /* RESET? */ 378 } 379 if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) { 380 sc->sc_nouse_pin = GPIO_WS007SH_SD_DETECT; /* SD_DETECT */ 381 sc->sc_nouse_pin2 = 77; /* Vsync? */ 382 } 383 if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) { 384 sc->sc_nouse_pin = GPIO_WS011SH_SD_DETECT; /* SD_DETECT */ 385 sc->sc_nouse_pin2 = 77; /* Vsync? */ 386 } 387 if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH)) { 388 sc->sc_nouse_pin = GPIO_WS020SH_SD_DETECT; /* SD_DETECT */ 389 sc->sc_nouse_pin2 = 77; /* Vsync? */ 390 } 391 392 #ifdef KEYTEST 393 for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) { 394 if (sc->sc_test_pin != sc->sc_nouse_pin 395 && sc->sc_test_pin != sc->sc_nouse_pin2 396 && sc->sc_test_pin != sc->sc_nouse_pin3 397 && sc->sc_test_pin != sc->sc_key_pin 398 && sc->sc_test_pin != sc->sc_power_pin 399 && sc->sc_test_pin != sc->sc_reset_pin 400 && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin))) 401 break; 402 } 403 if (sc->sc_test_pin < PXA270_GPIO_NPINS) { 404 printf("GPIO_IN: GPIO pin #%d\n", sc->sc_test_pin); 405 sc->sc_test_ih = pxa2x0_gpio_intr_establish(sc->sc_test_pin, 406 IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2, sc); 407 } else { 408 sc->sc_test_pin = -1; 409 } 410 #endif 411 412 #ifdef KEYTEST3 413 { 414 int i; 415 printf("pin: "); 416 for (i = 0; i < PXA270_GPIO_NPINS; i++) { 417 if (i == sc->sc_nouse_pin 418 || i == sc->sc_nouse_pin2 419 || i == sc->sc_nouse_pin3 420 || i == sc->sc_key_pin 421 || i == sc->sc_power_pin 422 || i == sc->sc_reset_pin) 423 continue; 424 425 printf("%d, ", i); 426 if (GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(i))) { 427 pxa2x0_gpio_intr_establish(i, IST_EDGE_BOTH, 428 IPL_TTY, wzero3kbd_intr3, (void *)(long)i); 429 } 430 } 431 } 432 #endif 433 434 #ifdef KEYTEST4 435 for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) { 436 if (sc->sc_test_pin != sc->sc_nouse_pin 437 && sc->sc_test_pin != sc->sc_nouse_pin2 438 && sc->sc_test_pin != sc->sc_nouse_pin3 439 && sc->sc_test_pin != sc->sc_key_pin 440 && sc->sc_test_pin != sc->sc_power_pin 441 && sc->sc_test_pin != sc->sc_reset_pin 442 && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin))) 443 break; 444 } 445 if (sc->sc_test_pin < PXA270_GPIO_NPINS) { 446 printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin); 447 } else { 448 sc->sc_test_pin = -1; 449 } 450 #endif 451 #ifdef KEYTEST5 452 sc->sc_test_pin = 0x00; 453 sc->sc_bit = 0x01; 454 #endif 455 #endif 456 } 457 458 static int 459 wzero3kbd_intr(void *arg) 460 { 461 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 462 463 #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5) 464 printf("wzero3kbd_intr: GPIO pin #%d = %s\n", sc->sc_key_pin, 465 pxa2x0_gpio_get_bit(sc->sc_key_pin) ? "on" : "off"); 466 #endif 467 468 #if defined(KEYTEST4) 469 if (sc->sc_test_pin >= 0) { 470 if (pxa2x0_gpio_get_bit(sc->sc_test_pin)) { 471 printf("GPIO_OUT: GPIO pin #%d: L\n",sc->sc_test_pin); 472 pxa2x0_gpio_clear_bit(sc->sc_test_pin); 473 } else { 474 printf("GPIO_OUT: GPIO pin #%d: H\n", sc->sc_test_pin); 475 pxa2x0_gpio_set_bit(sc->sc_test_pin); 476 } 477 } 478 #endif 479 #if defined(KEYTEST5) 480 printf("CPLD(%#x): value=%#x, mask=%#x\n", 481 sc->sc_test_pin, CSR_READ4(sc->sc_test_pin), sc->sc_bit); 482 if (CSR_READ4(sc->sc_test_pin) & sc->sc_bit) { 483 printf("CPLD_OUT: CPLD: L\n"); 484 CSR_WRITE4(sc->sc_test_pin, 485 CSR_READ4(sc->sc_test_pin) & ~sc->sc_bit); 486 } else { 487 printf("CPLD_OUT: CPLD: H\n"); 488 CSR_WRITE4(sc->sc_test_pin, 489 CSR_READ4(sc->sc_test_pin) | sc->sc_bit); 490 } 491 #endif 492 493 (void) wzero3kbd_poll1(sc); 494 495 pxa2x0_gpio_clear_intr(sc->sc_key_pin); 496 497 return 1; 498 } 499 500 #if defined(KEYTEST) 501 static int 502 wzero3kbd_intr2(void *arg) 503 { 504 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 505 506 printf("wzero3kbd_intr2: GPIO_IN: GPIO pin #%d = %s\n", sc->sc_test_pin, 507 pxa2x0_gpio_get_bit(sc->sc_test_pin) ? "on" : "off"); 508 509 return 1; 510 } 511 #endif 512 513 #if defined(KEYTEST3) 514 static int 515 wzero3kbd_intr3(void *arg) 516 { 517 int pin = (int)arg; 518 519 printf("wzero3kbd_intr3: GPIO pin #%d = %s\n", pin, 520 pxa2x0_gpio_get_bit(pin) ? "on" : "off"); 521 522 return 1; 523 } 524 #endif 525 526 527 static void 528 wzero3kbd_tick(void *arg) 529 { 530 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 531 532 (void) wzero3kbd_poll1(sc); 533 534 callout_schedule(&sc->sc_keyscan_ch, sc->sc_interval); 535 } 536 537 static int 538 wzero3kbd_power_intr(void *arg) 539 { 540 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 541 542 #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) 543 printf("wzero3kbd_power_intr: status = %s\n", 544 pxa2x0_gpio_get_bit(sc->sc_power_pin) ? "on" : "off"); 545 #endif 546 547 #if defined(KEYTEST) 548 if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { 549 if (sc->sc_test_pin >= 0) { 550 int orig_pin = sc->sc_test_pin; 551 pxa2x0_gpio_intr_disestablish(sc->sc_test_ih); 552 sc->sc_test_ih = NULL; 553 554 for (;;) { 555 if (++sc->sc_test_pin >= PXA270_GPIO_NPINS) 556 sc->sc_test_pin = 2; 557 if (sc->sc_test_pin == orig_pin) 558 break; 559 if (sc->sc_test_pin != sc->sc_nouse_pin 560 && sc->sc_test_pin != sc->sc_nouse_pin2 561 && sc->sc_test_pin != sc->sc_nouse_pin3 562 && sc->sc_test_pin != sc->sc_key_pin 563 && sc->sc_test_pin != sc->sc_power_pin 564 && sc->sc_test_pin != sc->sc_reset_pin 565 && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin))) 566 break; 567 } 568 if (sc->sc_test_pin != orig_pin) { 569 printf("GPIO_IN: GPIO pin #%d\n", 570 sc->sc_test_pin); 571 sc->sc_test_ih = 572 pxa2x0_gpio_intr_establish(sc->sc_test_pin, 573 IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2,sc); 574 } else { 575 sc->sc_test_pin = -1; 576 } 577 } 578 } 579 #endif 580 581 #if defined(KEYTEST2) 582 if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { 583 sc->sc_enabled ^= 2; 584 if (sc->sc_enabled & 2) { 585 printf("print col/row\n"); 586 } else { 587 printf("keyscan\n"); 588 } 589 } 590 #endif 591 #if defined(KEYTEST4) 592 if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { 593 if (sc->sc_test_pin >= 0) { 594 int orig_pin = sc->sc_test_pin; 595 for (;;) { 596 if (++sc->sc_test_pin >= PXA270_GPIO_NPINS) 597 sc->sc_test_pin = 2; 598 if (sc->sc_test_pin == orig_pin) 599 break; 600 if (sc->sc_test_pin != sc->sc_nouse_pin 601 && sc->sc_test_pin != sc->sc_nouse_pin2 602 && sc->sc_test_pin != sc->sc_nouse_pin3 603 && sc->sc_test_pin != sc->sc_key_pin 604 && sc->sc_test_pin != sc->sc_power_pin 605 && sc->sc_test_pin != sc->sc_reset_pin 606 && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin))) 607 break; 608 } 609 if (sc->sc_test_pin != orig_pin) { 610 printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin); 611 } else { 612 sc->sc_test_pin = -1; 613 } 614 } 615 } 616 #endif 617 #if defined(KEYTEST5) 618 if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { 619 sc->sc_bit <<= 1; 620 if (sc->sc_bit & ~0xff) { 621 sc->sc_bit = 0x01; 622 sc->sc_test_pin += 0x4; 623 if (sc->sc_test_pin >= 0x20) { 624 sc->sc_test_pin = 0x00; 625 } 626 } 627 printf("CPLD(%#x), mask=%#x\n", sc->sc_test_pin, sc->sc_bit); 628 } 629 #endif 630 631 pxa2x0_gpio_clear_intr(sc->sc_power_pin); 632 633 return 1; 634 } 635 636 static int 637 wzero3kbd_reset_intr(void *arg) 638 { 639 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 640 641 sysmon_task_queue_sched(0, wzero3kbd_sysmon_reset_event, sc); 642 643 pxa2x0_gpio_clear_intr(sc->sc_reset_pin); 644 645 return 1; 646 } 647 648 static int 649 wzero3kbd_input_establish(void *arg, struct hpckbd_if *kbdif) 650 { 651 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 652 653 /* Save hpckbd interface. */ 654 sc->sc_hpckbd = kbdif; 655 sc->sc_enabled = 1; 656 657 return 0; 658 } 659 660 static void 661 wzero3kbd_sysmon_reset_event(void *arg) 662 { 663 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 664 665 sysmon_pswitch_event(&sc->sc_smpsw, PSWITCH_EVENT_PRESSED); 666 } 667 668 static int 669 wzero3kbd_poll(void *arg) 670 { 671 int keydown; 672 673 keydown = wzero3kbd_poll1(arg); 674 675 return keydown; 676 } 677 678 static int 679 wzero3kbd_poll1(void *arg) 680 { 681 struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; 682 int row, col, data; 683 int keycol; 684 int keydown; 685 int i; 686 int s; 687 688 if (!sc->sc_enabled) { 689 DPRINTF(("wzero3kbd_poll: disabled\n")); 690 return 0; 691 } 692 693 s = spltty(); 694 695 for (col = 0; col < sc->sc_ncolumn; col++) { 696 /* deselect column# and charge */ 697 CSR_WRITE1(KBDCOL_L, 0); 698 CSR_WRITE1(KBDCOL_U, 0); 699 CSR_WRITE1(KBDCHARGE, 1); 700 delay(KEYWAIT); 701 CSR_WRITE1(KBDCHARGE, 0); 702 703 /* select scan column# */ 704 keycol = 1 << col; 705 CSR_WRITE1(KBDCOL_L, keycol & 0xff); 706 CSR_WRITE1(KBDCOL_U, keycol >> 8); 707 delay(KEYWAIT); 708 CSR_WRITE1(KBDCHARGE, 0); 709 710 /* read key data */ 711 data = CSR_READ1(KBDDATA); 712 for (row = 0; row < sc->sc_nrow; row++) { 713 #ifdef KEYTEST2 714 if (!(sc->sc_enabled & 2)) { 715 #endif 716 sc->sc_keystat[row + col * sc->sc_nrow] = 717 (data >> row) & 1; 718 #ifdef KEYTEST2 719 } else if (data & (1 << row)) { 720 printf("col = %d, row = %d, idx = %d, data = 0x%02x\n", col, row, row + col * sc->sc_nrow, data); 721 } 722 #endif 723 } 724 } 725 726 /* deselect column# and charge */ 727 CSR_WRITE1(KBDCOL_L, 0); 728 CSR_WRITE1(KBDCOL_U, 0); 729 CSR_WRITE1(KBDCHARGE, 1); 730 delay(KEYWAIT); 731 CSR_WRITE1(KBDCHARGE, 0); 732 733 /* send key scan code */ 734 keydown = 0; 735 for (i = 0; i < sc->sc_nrow * sc->sc_ncolumn; i++) { 736 if (sc->sc_keystat[i] == sc->sc_okeystat[i]) 737 continue; 738 739 keydown |= sc->sc_keystat[i]; 740 hpckbd_input(sc->sc_hpckbd, sc->sc_keystat[i], i); 741 sc->sc_okeystat[i] = sc->sc_keystat[i]; 742 } 743 744 splx(s); 745 746 return keydown; 747 } 748