1 /* $NetBSD: j720ssp.c,v 1.21 2003/10/27 17:17:42 mycroft Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /*- 40 * Copyright (c) 1990 The Regents of the University of California. 41 * All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * William Jolitz and Don Ahn. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)pccons.c 5.11 (Berkeley) 5/21/91 71 */ 72 73 #include <sys/cdefs.h> 74 __KERNEL_RCSID(0, "$NetBSD: j720ssp.c,v 1.21 2003/10/27 17:17:42 mycroft Exp $"); 75 76 #include "apm.h" 77 78 #include <sys/param.h> 79 #include <sys/systm.h> 80 #include <sys/device.h> 81 #include <sys/kernel.h> 82 #include <sys/malloc.h> 83 #include <sys/ioctl.h> 84 #include <sys/kthread.h> 85 #include <sys/lock.h> 86 87 #include <machine/bus.h> 88 #include <machine/config_hook.h> 89 #include <machine/bootinfo.h> 90 #include <machine/apmvar.h> 91 92 #include <hpcarm/dev/sed1356var.h> 93 94 #include <arm/sa11x0/sa11x0_var.h> 95 #include <arm/sa11x0/sa11x0_gpioreg.h> 96 #include <arm/sa11x0/sa11x0_ppcreg.h> 97 #include <arm/sa11x0/sa11x0_sspreg.h> 98 99 #include <dev/wscons/wsconsio.h> 100 #include <dev/wscons/wskbdvar.h> 101 #include <dev/wscons/wsksymdef.h> 102 #include <dev/wscons/wsksymvar.h> 103 #include <dev/wscons/wsmousevar.h> 104 #include <dev/hpc/tpcalibvar.h> 105 106 extern const struct wscons_keydesc j720kbd_keydesctab[]; 107 108 struct j720ssp_softc { 109 struct device sc_dev; 110 111 bus_space_tag_t sc_iot; 112 bus_space_handle_t sc_gpioh; 113 bus_space_handle_t sc_ssph; 114 115 struct device *sc_wskbddev; 116 struct device *sc_wsmousedev; 117 struct tpcalib_softc sc_tpcalib; 118 119 void *sc_kbdsi; 120 void *sc_tpsi; 121 int sc_enabled; 122 123 struct proc *sc_ssp_kthread; 124 int sc_ssp_status; 125 struct simplelock sc_ssp_status_lock; 126 }; 127 /* Values for struct softc's sc_ssp_status */ 128 #define J720_SSP_STATUS_NONE 0 129 #define J720_SSP_STATUS_TP 1 130 #define J720_SSP_STATUS_KBD 2 131 132 void j720ssp_create_kthread __P((void *)); 133 void j720ssp_kthread __P((void *)); 134 int j720kbd_intr __P((void *)); 135 int j720tp_intr __P((void *)); 136 void j720kbd_poll __P((void *)); 137 int j720tp_poll __P((void *)); 138 139 int j720lcdparam __P((void *, int, long, void *)); 140 static void j720kbd_read __P((struct j720ssp_softc *, char *)); 141 static int j720ssp_readwrite __P((struct j720ssp_softc *, int, 142 int, int *, int)); 143 144 int j720sspprobe __P((struct device *, struct cfdata *, void *)); 145 void j720sspattach __P((struct device *, struct device *, void *)); 146 147 int j720kbd_submatch __P((struct device *, struct cfdata *, void *)); 148 int j720tp_submatch __P((struct device *, struct cfdata *, void *)); 149 int apm_submatch __P((struct device *, struct cfdata *, void *)); 150 151 int j720kbd_enable __P((void *, int)); 152 void j720kbd_set_leds __P((void *, int)); 153 int j720kbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 154 155 int j720lcdpower(void *, int, long, void *); 156 int hpcarm_apm_getpower __P((struct apm_power_info *, void *)); 157 158 CFATTACH_DECL(j720ssp, sizeof(struct j720ssp_softc), 159 j720sspprobe, j720sspattach, NULL, NULL); 160 161 const struct wskbd_accessops j720kbd_accessops = { 162 j720kbd_enable, 163 j720kbd_set_leds, 164 j720kbd_ioctl, 165 }; 166 167 void j720kbd_cngetc __P((void *, u_int *, int *)); 168 void j720kbd_cnpollc __P((void *, int)); 169 void j720kbd_cnbell __P((void *, u_int, u_int, u_int)); 170 171 const struct wskbd_consops j720kbd_consops = { 172 j720kbd_cngetc, 173 j720kbd_cnpollc, 174 j720kbd_cnbell, 175 }; 176 177 const struct wskbd_mapdata j720kbd_keymapdata = { 178 j720kbd_keydesctab, 179 #ifdef J720KBD_LAYOUT 180 J720KBD_LAYOUT, 181 #else 182 KB_US, 183 #endif 184 }; 185 186 static int j720tp_enable __P((void *)); 187 static int j720tp_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 188 static void j720tp_disable __P((void *)); 189 190 const struct wsmouse_accessops j720tp_accessops = { 191 j720tp_enable, 192 j720tp_ioctl, 193 j720tp_disable, 194 }; 195 196 static int j720ssp_powerstate = 1; 197 198 static struct j720ssp_softc j720kbdcons_sc; 199 static int j720kbdcons_initstate = 0; 200 201 #define DEBUG 202 #ifdef DEBUG 203 int j720sspwaitcnt; 204 int j720sspwaittime; 205 extern int gettick(void); 206 #endif 207 208 #define BIT_INVERT(x) do { \ 209 (x) = ((((x) & 0xf0) >> 4) | (((x) & 0x0f) << 4)); \ 210 (x) = ((((x) & 0xcc) >> 2) | (((x) & 0x33) << 2)); \ 211 (x) = ((((x) & 0xaa) >> 1) | (((x) & 0x55) << 1)); \ 212 } while(0) 213 214 215 int 216 j720sspprobe(parent, cf, aux) 217 struct device *parent; 218 struct cfdata *cf; 219 void *aux; 220 { 221 return (1); 222 } 223 224 void 225 j720sspattach(parent, self, aux) 226 struct device *parent; 227 struct device *self; 228 void *aux; 229 { 230 struct j720ssp_softc *sc = (void *)self; 231 struct sa11x0_softc *psc = (void *)parent; 232 struct sa11x0_attach_args *sa = aux; 233 struct wskbddev_attach_args kbd_args; 234 struct wsmousedev_attach_args mouse_args; 235 #if NAPM > 0 236 struct apm_attach_args apm_args; 237 #endif 238 239 printf("\n"); 240 241 sc->sc_iot = psc->sc_iot; 242 sc->sc_gpioh = psc->sc_gpioh; 243 if (bus_space_map(sc->sc_iot, sa->sa_addr, sa->sa_size, 0, 244 &sc->sc_ssph)) { 245 printf("%s: unable to map SSP registers\n", 246 sc->sc_dev.dv_xname); 247 return; 248 } 249 250 sc->sc_ssp_status = J720_SSP_STATUS_NONE; 251 simple_lock_init(&sc->sc_ssp_status_lock); 252 kthread_create(j720ssp_create_kthread, sc); 253 254 sc->sc_enabled = 0; 255 256 kbd_args.console = 0; 257 258 kbd_args.keymap = &j720kbd_keymapdata; 259 260 kbd_args.accessops = &j720kbd_accessops; 261 kbd_args.accesscookie = sc; 262 263 /* Do console initialization */ 264 if (! (bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) { 265 j720kbdcons_sc = *sc; 266 kbd_args.console = 1; 267 268 wskbd_cnattach(&j720kbd_consops, NULL, &j720kbd_keymapdata); 269 j720kbdcons_initstate = 1; 270 } 271 272 /* 273 * Attach the wskbd, saving a handle to it. 274 * XXX XXX XXX 275 */ 276 sc->sc_wskbddev = config_found_sm(self, &kbd_args, wskbddevprint, 277 j720kbd_submatch); 278 279 #ifdef DEBUG 280 /* Zero the stat counters */ 281 j720sspwaitcnt = 0; 282 j720sspwaittime = 0; 283 #endif 284 285 if (j720kbdcons_initstate == 1) 286 j720kbd_enable(sc, 1); 287 288 mouse_args.accessops = &j720tp_accessops; 289 mouse_args.accesscookie = sc; 290 291 sc->sc_wsmousedev = config_found_sm(self, &mouse_args, 292 wsmousedevprint, j720tp_submatch); 293 tpcalib_init(&sc->sc_tpcalib); 294 295 /* XXX fill in "default" calibrate param */ 296 { 297 static const struct wsmouse_calibcoords j720_default_calib = { 298 0, 0, 639, 239, 299 4, 300 { { 988, 80, 0, 0 }, 301 { 88, 84, 639, 0 }, 302 { 988, 927, 0, 239 }, 303 { 88, 940, 639, 239 } } }; 304 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 305 (caddr_t)&j720_default_calib, 0, 0); 306 } 307 308 j720tp_disable(sc); 309 310 /* Setup touchpad interrupt */ 311 sa11x0_intr_establish(0, 9, 1, IPL_BIO, j720tp_intr, sc); 312 313 /* LCD control is on the same bus */ 314 config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, 315 CONFIG_HOOK_SHARE, j720lcdparam, sc); 316 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS, 317 CONFIG_HOOK_SHARE, j720lcdparam, sc); 318 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS_MAX, 319 CONFIG_HOOK_SHARE, j720lcdparam, sc); 320 321 config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, 322 CONFIG_HOOK_SHARE, j720lcdparam, sc); 323 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST, 324 CONFIG_HOOK_SHARE, j720lcdparam, sc); 325 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST_MAX, 326 CONFIG_HOOK_SHARE, j720lcdparam, sc); 327 328 #if NAPM > 0 329 /* attach APM emulation */ 330 apm_args.aaa_magic = APM_ATTACH_ARGS_MAGIC; /* magic number */ 331 (void)config_found_sm(self, &apm_args, NULL, apm_submatch); 332 #endif 333 334 return; 335 } 336 337 void 338 j720ssp_create_kthread(arg) 339 void *arg; 340 { 341 struct j720ssp_softc *sc = arg; 342 343 if (kthread_create1(j720ssp_kthread, sc, 344 &sc->sc_ssp_kthread, "j720ssp")) 345 panic("j720ssp_create_kthread"); 346 347 return; 348 } 349 350 void 351 j720ssp_kthread(arg) 352 void *arg; 353 { 354 struct j720ssp_softc *sc = arg; 355 int ssp_status; 356 357 while (1) { 358 simple_lock(&sc->sc_ssp_status_lock); 359 ssp_status = sc->sc_ssp_status; 360 sc->sc_ssp_status &= ~J720_SSP_STATUS_KBD; 361 simple_unlock(&sc->sc_ssp_status_lock); 362 363 if (ssp_status & J720_SSP_STATUS_KBD) 364 j720kbd_poll(sc); 365 366 if (ssp_status & J720_SSP_STATUS_TP) { 367 if (j720tp_poll(sc) == 0) { 368 simple_lock(&sc->sc_ssp_status_lock); 369 sc->sc_ssp_status &= ~J720_SSP_STATUS_TP; 370 simple_unlock(&sc->sc_ssp_status_lock); 371 } 372 tsleep(&sc->sc_ssp_kthread, PRIBIO, "j720ssp", hz / 25); 373 } else 374 tsleep(&sc->sc_ssp_kthread, PRIBIO, "j720ssp", 0); 375 } 376 377 /* NOTREACHED */ 378 } 379 380 381 int 382 j720kbd_submatch(parent, cf, aux) 383 struct device *parent; 384 struct cfdata *cf; 385 void *aux; 386 { 387 if (strcmp(cf->cf_name, "wskbd") == 0) 388 return (1); 389 return (0); 390 } 391 392 int 393 j720tp_submatch(parent, cf, aux) 394 struct device *parent; 395 struct cfdata *cf; 396 void *aux; 397 { 398 if (strcmp(cf->cf_name, "wsmouse") == 0) 399 return (1); 400 return (0); 401 } 402 403 int 404 apm_submatch(parent, cf, aux) 405 struct device *parent; 406 struct cfdata *cf; 407 void *aux; 408 { 409 if (strcmp(cf->cf_name, "apm") == 0) 410 return (1); 411 return (0); 412 } 413 414 int 415 j720kbd_enable(v, on) 416 void *v; 417 int on; 418 { 419 struct j720ssp_softc *sc = v; 420 421 if (! sc->sc_enabled) { 422 sc->sc_enabled = 1; 423 424 sa11x0_intr_establish(0, 0, 1, IPL_BIO, j720kbd_intr, sc); 425 } 426 /* XXX */ 427 return (0); 428 } 429 430 void 431 j720kbd_set_leds(v, on) 432 void *v; 433 int on; 434 { 435 /* XXX */ 436 return; 437 } 438 439 int 440 j720kbd_ioctl(v, cmd, data, flag, p) 441 void *v; 442 u_long cmd; 443 caddr_t data; 444 int flag; 445 struct proc *p; 446 { 447 switch (cmd) { 448 case WSKBDIO_GTYPE: 449 *(int *)data = WSKBD_TYPE_HPC_KBD; 450 return 0; 451 } 452 453 return (EPASSTHROUGH); 454 } 455 456 int 457 j720kbd_intr(arg) 458 void *arg; 459 { 460 struct j720ssp_softc *sc = arg; 461 462 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_EDR, 1); 463 464 simple_lock(&sc->sc_ssp_status_lock); 465 sc->sc_ssp_status |= J720_SSP_STATUS_KBD; 466 simple_unlock(&sc->sc_ssp_status_lock); 467 468 wakeup(&sc->sc_ssp_kthread); 469 470 return (1); 471 } 472 473 int 474 j720tp_intr(arg) 475 void *arg; 476 { 477 struct j720ssp_softc *sc = arg; 478 479 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_EDR, 1 << 9); 480 481 simple_lock(&sc->sc_ssp_status_lock); 482 sc->sc_ssp_status |= J720_SSP_STATUS_TP; 483 simple_unlock(&sc->sc_ssp_status_lock); 484 485 j720tp_disable(sc); 486 wakeup(&sc->sc_ssp_kthread); 487 488 return (1); 489 } 490 491 void 492 j720kbd_poll(arg) 493 void *arg; 494 { 495 struct j720ssp_softc *sc = arg; 496 int s, type, value; 497 char buf[9], *p; 498 499 j720kbd_read(sc, buf); 500 501 for(p = buf; *p; p++) { 502 type = *p & 0x80 ? WSCONS_EVENT_KEY_UP : 503 WSCONS_EVENT_KEY_DOWN; 504 value = *p & 0x7f; 505 s = spltty(); 506 wskbd_input(sc->sc_wskbddev, type, value); 507 splx(s); 508 if (type == WSCONS_EVENT_KEY_DOWN && 509 value == 0x7f) { 510 j720ssp_powerstate = ! j720ssp_powerstate; 511 config_hook_call(CONFIG_HOOK_POWERCONTROL, 512 CONFIG_HOOK_POWERCONTROL_LCDLIGHT, 513 (void *)j720ssp_powerstate); 514 } 515 } 516 517 return; 518 } 519 520 void 521 j720kbd_read(sc, buf) 522 struct j720ssp_softc *sc; 523 char *buf; 524 { 525 int data, count; 526 #ifdef DEBUG 527 u_int32_t oscr; 528 529 oscr = gettick(); 530 #endif 531 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 532 533 /* send scan keycode command */ 534 if (j720ssp_readwrite(sc, 1, 0x900, &data, 100) < 0 || 535 data != 0x88) 536 goto out; 537 538 /* read numbers of scancode available */ 539 if (j720ssp_readwrite(sc, 0, 0x8800, &data, 100) < 0) 540 goto out; 541 BIT_INVERT(data); 542 count = data; 543 544 for(; count; count--) { 545 if (j720ssp_readwrite(sc, 0, 0x8800, &data, 100) < 0) 546 goto out; 547 BIT_INVERT(data); 548 *buf++ = data; 549 } 550 *buf = 0; 551 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 552 553 #ifdef DEBUG 554 oscr = (u_int32_t)gettick() - oscr; 555 j720sspwaitcnt++; 556 j720sspwaittime += oscr; 557 #endif 558 559 return; 560 561 out: 562 *buf = 0; 563 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 564 565 /* reset SSP */ 566 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 567 delay(100); 568 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 569 570 printf("j720kbd_read: error %x\n", data); 571 return; 572 } 573 574 int 575 j720tp_poll(arg) 576 void *arg; 577 { 578 struct j720ssp_softc *sc = arg; 579 int buf[8], data, i, x, y; 580 581 /* 582 * If touch panel is not touched anymore, 583 * stop polling and re-enable interrupt 584 */ 585 if (bus_space_read_4(sc->sc_iot, 586 sc->sc_gpioh, SAGPIO_PLR) & (1 << 9)) { 587 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0); 588 j720tp_enable(sc); 589 return 0; 590 } 591 592 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 593 594 /* send read touchpanel command */ 595 if (j720ssp_readwrite(sc, 1, 0x500, &data, 100) < 0 || 596 data != 0x88) 597 goto out; 598 599 for(i = 0; i < 8; i++) { 600 if (j720ssp_readwrite(sc, 0, 0x8800, &data, 100) < 0) 601 goto out; 602 BIT_INVERT(data); 603 buf[i] = data; 604 } 605 606 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 607 608 buf[6] <<= 8; 609 buf[7] <<= 8; 610 for(i = 0; i < 3; i++) { 611 buf[i] |= buf[6] & 0x300; 612 buf[6] >>= 2; 613 buf[i + 3] |= buf[7] & 0x300; 614 buf[7] >>= 2; 615 } 616 #if 0 617 printf("j720tp_poll: %d %d %d %d %d %d\n", buf[0], buf[1], buf[2], 618 buf[3], buf[4], buf[5]); 619 #endif 620 621 /* XXX buf[1], buf[2], ... should also be used */ 622 tpcalib_trans(&sc->sc_tpcalib, buf[1], buf[4], &x, &y); 623 wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0, 624 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 625 626 return 1; 627 628 out: 629 *buf = 0; 630 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 631 632 /* reset SSP */ 633 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 634 delay(100); 635 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 636 printf("j720tp_poll: error %x\n", data); 637 638 return 0; 639 } 640 641 static int 642 j720tp_enable(arg) 643 void *arg; 644 { 645 struct j720ssp_softc *sc = arg; 646 int er, s; 647 648 s = splhigh(); 649 er = bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER); 650 er |= 1 << 9; 651 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER, er); 652 splx(s); 653 654 return (0); 655 } 656 657 static void 658 j720tp_disable(arg) 659 void *arg; 660 { 661 struct j720ssp_softc *sc = arg; 662 int er, s; 663 664 s = splhigh(); 665 er = bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER); 666 er &= ~(1 << 9); 667 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER, er); 668 splx(s); 669 } 670 671 static int 672 j720tp_ioctl(arg, cmd, data, flag, p) 673 void *arg; 674 u_long cmd; 675 caddr_t data; 676 int flag; 677 struct proc *p; 678 { 679 struct j720ssp_softc *sc = arg; 680 681 switch (cmd) { 682 case WSMOUSEIO_GTYPE: 683 *(u_int *)data = WSMOUSE_TYPE_TPANEL; 684 return (0); 685 686 case WSMOUSEIO_SCALIBCOORDS: 687 case WSMOUSEIO_GCALIBCOORDS: 688 case WSMOUSEIO_GETID: 689 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p); 690 691 default: 692 return (EPASSTHROUGH); 693 } 694 } 695 696 int 697 j720lcdparam(ctx, type, id, msg) 698 void *ctx; 699 int type; 700 long id; 701 void *msg; 702 { 703 struct j720ssp_softc *sc = ctx; 704 int i, s; 705 u_int32_t data[2], len; 706 707 switch (type) { 708 case CONFIG_HOOK_GET: 709 switch (id) { 710 case CONFIG_HOOK_BRIGHTNESS_MAX: 711 case CONFIG_HOOK_CONTRAST_MAX: 712 *(int *)msg = 255; 713 return 1; 714 case CONFIG_HOOK_BRIGHTNESS: 715 data[0] = 0x6b00; 716 data[1] = 0x8800; 717 len = 2; 718 break; 719 case CONFIG_HOOK_CONTRAST: 720 data[0] = 0x2b00; 721 data[1] = 0x8800; 722 len = 2; 723 break; 724 default: 725 return 0; 726 } 727 break; 728 729 case CONFIG_HOOK_SET: 730 switch (id) { 731 case CONFIG_HOOK_BRIGHTNESS: 732 if (*(int *)msg >= 0) { 733 data[0] = 0xcb00; 734 data[1] = *(int *)msg; 735 BIT_INVERT(data[1]); 736 data[1] <<= 8; 737 len = 2; 738 } else { 739 /* XXX hack */ 740 data[0] = 0xfb00; 741 len = 1; 742 } 743 break; 744 case CONFIG_HOOK_CONTRAST: 745 data[0] = 0x8b00; 746 data[1] = *(int *)msg; 747 BIT_INVERT(data[1]); 748 data[1] <<= 8; 749 len = 2; 750 break; 751 default: 752 return 0; 753 } 754 755 default: 756 return 0; 757 } 758 759 s = splbio(); 760 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 761 762 for (i = 0; i < len; i++) { 763 if (j720ssp_readwrite(sc, 1, data[i], &data[i], 500) < 0) 764 goto out; 765 } 766 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 767 splx(s); 768 769 if (type == CONFIG_HOOK_SET) 770 return 1; 771 772 BIT_INVERT(data[1]); 773 *(int *)msg = data[1]; 774 775 return 1; 776 777 out: 778 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 779 780 /* reset SSP */ 781 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 782 delay(100); 783 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 784 splx(s); 785 return 0; 786 } 787 788 static int 789 j720ssp_readwrite(sc, drainfifo, in, out, wait) 790 struct j720ssp_softc *sc; 791 int drainfifo; 792 int in; 793 int *out; 794 int wait; 795 { 796 int timo; 797 798 timo = 100000; 799 while(bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PLR) & 0x400) 800 if (--timo == 0) { 801 printf("timo0\n"); 802 return -1; 803 } 804 if (drainfifo) { 805 while(bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_SR) & 806 SR_RNE) 807 bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_DR); 808 #if 1 809 delay(wait); 810 #endif 811 } 812 813 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_DR, in); 814 815 delay(wait); 816 timo = 100000; 817 while(! (bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_SR) & SR_RNE)) 818 if (--timo == 0) { 819 printf("timo1\n"); 820 return -1; 821 } 822 823 *out = bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_DR); 824 825 return 0; 826 } 827 828 #if 0 829 int 830 j720kbd_cnattach(void) 831 { 832 /* XXX defer initialization till j720sspattach */ 833 834 return (0); 835 } 836 #endif 837 838 /* ARGSUSED */ 839 void 840 j720kbd_cngetc(v, type, data) 841 void *v; 842 u_int *type; 843 int *data; 844 { 845 char buf[9]; 846 847 if (j720kbdcons_initstate < 1) 848 return; 849 850 for (;;) { 851 j720kbd_read(&j720kbdcons_sc, buf); 852 853 if (buf[0] != 0) { 854 /* XXX we are discarding buffer contents */ 855 *type = buf[0] & 0x80 ? WSCONS_EVENT_KEY_UP : 856 WSCONS_EVENT_KEY_DOWN; 857 *data = buf[0] & 0x7f; 858 return; 859 } 860 } 861 } 862 863 void 864 j720kbd_cnpollc(v, on) 865 void *v; 866 int on; 867 { 868 #if 0 869 /* XXX */ 870 struct j720kbd_internal *t = v; 871 872 pckbc_set_poll(t->t_kbctag, t->t_kbcslot, on); 873 #endif 874 } 875 876 void 877 j720kbd_cnbell(v, pitch, period, volume) 878 void *v; 879 u_int pitch; 880 u_int period; 881 u_int volume; 882 { 883 } 884 885 int 886 j720lcdpower(ctx, type, id, msg) 887 void *ctx; 888 int type; 889 long id; 890 void *msg; 891 { 892 struct sed1356_softc *sc = ctx; 893 struct sa11x0_softc *psc = sc->sc_parent; 894 int val; 895 u_int32_t reg; 896 897 if (type != CONFIG_HOOK_POWERCONTROL || 898 id != CONFIG_HOOK_POWERCONTROL_LCDLIGHT) 899 return 0; 900 901 sed1356_init_brightness(sc, 0); 902 sed1356_init_contrast(sc, 0); 903 904 if (msg) { 905 bus_space_write_1(sc->sc_iot, sc->sc_regh, 0x1f0, 0); 906 907 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 908 reg |= 0x1; 909 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 910 delay(50000); 911 912 val = sc->sc_contrast; 913 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val); 914 delay(100000); 915 916 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 917 reg |= 0x4; 918 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 919 920 val = sc->sc_brightness; 921 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 922 923 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 924 reg |= 0x2; 925 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 926 } else { 927 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 928 reg &= ~0x2; 929 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 930 reg &= ~0x4; 931 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 932 delay(100000); 933 934 val = -2; 935 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 936 937 bus_space_write_1(sc->sc_iot, sc->sc_regh, 0x1f0, 1); 938 939 delay(100000); 940 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 941 reg &= ~0x1; 942 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 943 } 944 return 1; 945 } 946 947 int 948 hpcarm_apm_getpower(api, parent) 949 struct apm_power_info *api; 950 void *parent; 951 { 952 int data, pmdata[3], i; 953 struct j720ssp_softc *sc = (struct j720ssp_softc *)parent; 954 955 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 956 957 if (j720ssp_readwrite(sc, 1, 0x300, &data, 100) < 0 || data != 0x88) 958 goto out; 959 960 for (i = 0; i < 3; i++) { 961 if (j720ssp_readwrite(sc, 0, 0x8800, &pmdata[i], 500) < 0) 962 goto out; 963 BIT_INVERT(pmdata[i]); 964 } 965 966 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 967 968 bzero(api, sizeof(struct apm_power_info)); 969 api->ac_state = APM_AC_UNKNOWN; 970 971 /* 972 * pmdata[0] is the main battery level 973 * pmdata[1] is the backup battery level 974 * pmdata[2] tells which battery is present 975 */ 976 switch(pmdata[2]) { 977 case 14: /* backup battery present */ 978 case 2: /* backup battery absent */ 979 api->battery_state = APM_BATT_CHARGING; 980 api->minutes_left = (pmdata[0] * 840) / 170; 981 api->battery_life = (pmdata[0] * 100) / 170; 982 api->nbattery = 1; 983 break; 984 case 15: /* backup battery present */ 985 case 3: /* backup battery absent */ 986 api->battery_state = APM_BATT_ABSENT; 987 api->battery_life = 0; 988 api->nbattery = 0; 989 break; 990 default: 991 api->battery_state = APM_BATT_UNKNOWN; 992 break; 993 } 994 995 return 0; 996 997 out: 998 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 999 1000 /* reset SSP */ 1001 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 1002 delay(100); 1003 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 1004 1005 printf("hpcarm_apm_getpower: error %x\n", data); 1006 return EIO; 1007 } 1008