1 /* $NetBSD: j720ssp.c,v 1.28 2005/12/11 12:17:32 christos 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.28 2005/12/11 12:17:32 christos 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/hpctpanelvar.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_enable __P((void *, int)); 148 void j720kbd_set_leds __P((void *, int)); 149 int j720kbd_ioctl __P((void *, u_long, caddr_t, int, struct lwp *)); 150 151 int j720lcdpower(void *, int, long, void *); 152 int hpcarm_apm_getpower __P((struct apm_power_info *, void *)); 153 154 CFATTACH_DECL(j720ssp, sizeof(struct j720ssp_softc), 155 j720sspprobe, j720sspattach, NULL, NULL); 156 157 const struct wskbd_accessops j720kbd_accessops = { 158 j720kbd_enable, 159 j720kbd_set_leds, 160 j720kbd_ioctl, 161 }; 162 163 void j720kbd_cngetc __P((void *, u_int *, int *)); 164 void j720kbd_cnpollc __P((void *, int)); 165 void j720kbd_cnbell __P((void *, u_int, u_int, u_int)); 166 167 const struct wskbd_consops j720kbd_consops = { 168 j720kbd_cngetc, 169 j720kbd_cnpollc, 170 j720kbd_cnbell, 171 }; 172 173 const struct wskbd_mapdata j720kbd_keymapdata = { 174 j720kbd_keydesctab, 175 #ifdef J720KBD_LAYOUT 176 J720KBD_LAYOUT, 177 #else 178 KB_US, 179 #endif 180 }; 181 182 static int j720tp_enable __P((void *)); 183 static int j720tp_ioctl __P((void *, u_long, caddr_t, int, struct lwp *)); 184 static void j720tp_disable __P((void *)); 185 186 const struct wsmouse_accessops j720tp_accessops = { 187 j720tp_enable, 188 j720tp_ioctl, 189 j720tp_disable, 190 }; 191 192 static int j720ssp_powerstate = 1; 193 194 static struct j720ssp_softc j720kbdcons_sc; 195 static int j720kbdcons_initstate = 0; 196 197 #ifdef DEBUG 198 int j720sspwaitcnt; 199 int j720sspwaittime; 200 extern int gettick(void); 201 #endif 202 203 #define BIT_INVERT(x) do { \ 204 (x) = ((((x) & 0xf0) >> 4) | (((x) & 0x0f) << 4)); \ 205 (x) = ((((x) & 0xcc) >> 2) | (((x) & 0x33) << 2)); \ 206 (x) = ((((x) & 0xaa) >> 1) | (((x) & 0x55) << 1)); \ 207 } while(0) 208 209 210 int 211 j720sspprobe(parent, cf, aux) 212 struct device *parent; 213 struct cfdata *cf; 214 void *aux; 215 { 216 return (1); 217 } 218 219 void 220 j720sspattach(parent, self, aux) 221 struct device *parent; 222 struct device *self; 223 void *aux; 224 { 225 struct j720ssp_softc *sc = (void *)self; 226 struct sa11x0_softc *psc = (void *)parent; 227 struct sa11x0_attach_args *sa = aux; 228 struct wskbddev_attach_args kbd_args; 229 struct wsmousedev_attach_args mouse_args; 230 #if NAPM > 0 231 struct apm_attach_args apm_args; 232 #endif 233 234 printf("\n"); 235 236 sc->sc_iot = psc->sc_iot; 237 sc->sc_gpioh = psc->sc_gpioh; 238 if (bus_space_map(sc->sc_iot, sa->sa_addr, sa->sa_size, 0, 239 &sc->sc_ssph)) { 240 printf("%s: unable to map SSP registers\n", 241 sc->sc_dev.dv_xname); 242 return; 243 } 244 245 sc->sc_ssp_status = J720_SSP_STATUS_NONE; 246 simple_lock_init(&sc->sc_ssp_status_lock); 247 kthread_create(j720ssp_create_kthread, sc); 248 249 sc->sc_enabled = 0; 250 251 kbd_args.console = 0; 252 253 kbd_args.keymap = &j720kbd_keymapdata; 254 255 kbd_args.accessops = &j720kbd_accessops; 256 kbd_args.accesscookie = sc; 257 258 /* Do console initialization */ 259 if (! (bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) { 260 j720kbdcons_sc = *sc; 261 kbd_args.console = 1; 262 263 wskbd_cnattach(&j720kbd_consops, NULL, &j720kbd_keymapdata); 264 j720kbdcons_initstate = 1; 265 } 266 267 /* 268 * Attach the wskbd, saving a handle to it. 269 * XXX XXX XXX 270 */ 271 sc->sc_wskbddev = config_found_ia(self, "wskbddev", &kbd_args, 272 wskbddevprint); 273 274 #ifdef DEBUG 275 /* Zero the stat counters */ 276 j720sspwaitcnt = 0; 277 j720sspwaittime = 0; 278 #endif 279 280 if (j720kbdcons_initstate == 1) 281 j720kbd_enable(sc, 1); 282 283 mouse_args.accessops = &j720tp_accessops; 284 mouse_args.accesscookie = sc; 285 286 sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &mouse_args, 287 wsmousedevprint); 288 tpcalib_init(&sc->sc_tpcalib); 289 290 /* XXX fill in "default" calibrate param */ 291 { 292 static const struct wsmouse_calibcoords j720_default_calib = { 293 0, 0, 639, 239, 294 4, 295 { { 988, 80, 0, 0 }, 296 { 88, 84, 639, 0 }, 297 { 988, 927, 0, 239 }, 298 { 88, 940, 639, 239 } } }; 299 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 300 __UNCONST(&j720_default_calib), 0, 0); 301 } 302 303 j720tp_disable(sc); 304 305 /* Setup touchpad interrupt */ 306 sa11x0_intr_establish(0, 9, 1, IPL_BIO, j720tp_intr, sc); 307 308 /* LCD control is on the same bus */ 309 config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, 310 CONFIG_HOOK_SHARE, j720lcdparam, sc); 311 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS, 312 CONFIG_HOOK_SHARE, j720lcdparam, sc); 313 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_BRIGHTNESS_MAX, 314 CONFIG_HOOK_SHARE, j720lcdparam, sc); 315 316 config_hook(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, 317 CONFIG_HOOK_SHARE, j720lcdparam, sc); 318 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST, 319 CONFIG_HOOK_SHARE, j720lcdparam, sc); 320 config_hook(CONFIG_HOOK_GET, CONFIG_HOOK_CONTRAST_MAX, 321 CONFIG_HOOK_SHARE, j720lcdparam, sc); 322 323 #if NAPM > 0 324 /* attach APM emulation */ 325 apm_args.aaa_magic = APM_ATTACH_ARGS_MAGIC; /* magic number */ 326 (void)config_found_ia(self, "j720sspapm", &apm_args, NULL); 327 #endif 328 329 return; 330 } 331 332 void 333 j720ssp_create_kthread(arg) 334 void *arg; 335 { 336 struct j720ssp_softc *sc = arg; 337 338 if (kthread_create1(j720ssp_kthread, sc, 339 &sc->sc_ssp_kthread, "j720ssp")) 340 panic("j720ssp_create_kthread"); 341 342 return; 343 } 344 345 void 346 j720ssp_kthread(arg) 347 void *arg; 348 { 349 struct j720ssp_softc *sc = arg; 350 int ssp_status; 351 352 while (1) { 353 simple_lock(&sc->sc_ssp_status_lock); 354 ssp_status = sc->sc_ssp_status; 355 sc->sc_ssp_status &= ~J720_SSP_STATUS_KBD; 356 simple_unlock(&sc->sc_ssp_status_lock); 357 358 if (ssp_status & J720_SSP_STATUS_KBD) 359 j720kbd_poll(sc); 360 361 if (ssp_status & J720_SSP_STATUS_TP) { 362 if (j720tp_poll(sc) == 0) { 363 simple_lock(&sc->sc_ssp_status_lock); 364 sc->sc_ssp_status &= ~J720_SSP_STATUS_TP; 365 simple_unlock(&sc->sc_ssp_status_lock); 366 } 367 tsleep(&sc->sc_ssp_kthread, PRIBIO, "j720ssp", hz / 25); 368 } else 369 tsleep(&sc->sc_ssp_kthread, PRIBIO, "j720ssp", 0); 370 } 371 372 /* NOTREACHED */ 373 } 374 375 int 376 j720kbd_enable(v, on) 377 void *v; 378 int on; 379 { 380 struct j720ssp_softc *sc = v; 381 382 if (! sc->sc_enabled) { 383 sc->sc_enabled = 1; 384 385 sa11x0_intr_establish(0, 0, 1, IPL_BIO, j720kbd_intr, sc); 386 } 387 /* XXX */ 388 return (0); 389 } 390 391 void 392 j720kbd_set_leds(v, on) 393 void *v; 394 int on; 395 { 396 /* XXX */ 397 return; 398 } 399 400 int 401 j720kbd_ioctl(v, cmd, data, flag, l) 402 void *v; 403 u_long cmd; 404 caddr_t data; 405 int flag; 406 struct lwp *l; 407 { 408 switch (cmd) { 409 case WSKBDIO_GTYPE: 410 *(int *)data = WSKBD_TYPE_HPC_KBD; 411 return 0; 412 case WSKBDIO_GETLEDS: /* dummy for wsconsctl(8) */ 413 *(int *)data = 0; 414 return 0; 415 } 416 417 return (EPASSTHROUGH); 418 } 419 420 int 421 j720kbd_intr(arg) 422 void *arg; 423 { 424 struct j720ssp_softc *sc = arg; 425 426 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_EDR, 1); 427 428 simple_lock(&sc->sc_ssp_status_lock); 429 sc->sc_ssp_status |= J720_SSP_STATUS_KBD; 430 simple_unlock(&sc->sc_ssp_status_lock); 431 432 wakeup(&sc->sc_ssp_kthread); 433 434 return (1); 435 } 436 437 int 438 j720tp_intr(arg) 439 void *arg; 440 { 441 struct j720ssp_softc *sc = arg; 442 443 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_EDR, 1 << 9); 444 445 simple_lock(&sc->sc_ssp_status_lock); 446 sc->sc_ssp_status |= J720_SSP_STATUS_TP; 447 simple_unlock(&sc->sc_ssp_status_lock); 448 449 j720tp_disable(sc); 450 wakeup(&sc->sc_ssp_kthread); 451 452 return (1); 453 } 454 455 void 456 j720kbd_poll(arg) 457 void *arg; 458 { 459 struct j720ssp_softc *sc = arg; 460 int s, type, value; 461 char buf[9], *p; 462 463 j720kbd_read(sc, buf); 464 465 for(p = buf; *p; p++) { 466 type = *p & 0x80 ? WSCONS_EVENT_KEY_UP : 467 WSCONS_EVENT_KEY_DOWN; 468 value = *p & 0x7f; 469 s = spltty(); 470 wskbd_input(sc->sc_wskbddev, type, value); 471 splx(s); 472 if (type == WSCONS_EVENT_KEY_DOWN && 473 value == 0x7f) { 474 j720ssp_powerstate = ! j720ssp_powerstate; 475 config_hook_call(CONFIG_HOOK_POWERCONTROL, 476 CONFIG_HOOK_POWERCONTROL_LCDLIGHT, 477 (void *)j720ssp_powerstate); 478 } 479 } 480 481 return; 482 } 483 484 void 485 j720kbd_read(sc, buf) 486 struct j720ssp_softc *sc; 487 char *buf; 488 { 489 int data, count; 490 #ifdef DEBUG 491 u_int32_t oscr; 492 493 oscr = gettick(); 494 #endif 495 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 496 497 /* send scan keycode command */ 498 if (j720ssp_readwrite(sc, 1, 0x900, &data, 100) < 0 || 499 data != 0x88) 500 goto out; 501 502 /* read numbers of scancode available */ 503 if (j720ssp_readwrite(sc, 0, 0x8800, &data, 100) < 0) 504 goto out; 505 BIT_INVERT(data); 506 count = data; 507 508 for(; count; count--) { 509 if (j720ssp_readwrite(sc, 0, 0x8800, &data, 100) < 0) 510 goto out; 511 BIT_INVERT(data); 512 *buf++ = data; 513 } 514 *buf = 0; 515 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 516 517 #ifdef DEBUG 518 oscr = (u_int32_t)gettick() - oscr; 519 j720sspwaitcnt++; 520 j720sspwaittime += oscr; 521 #endif 522 523 return; 524 525 out: 526 *buf = 0; 527 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 528 529 /* reset SSP */ 530 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 531 delay(100); 532 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 533 534 printf("j720kbd_read: error %x\n", data); 535 return; 536 } 537 538 int 539 j720tp_poll(arg) 540 void *arg; 541 { 542 struct j720ssp_softc *sc = arg; 543 int buf[8], data, i, x, y; 544 545 /* 546 * If touch panel is not touched anymore, 547 * stop polling and re-enable interrupt 548 */ 549 if (bus_space_read_4(sc->sc_iot, 550 sc->sc_gpioh, SAGPIO_PLR) & (1 << 9)) { 551 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0); 552 j720tp_enable(sc); 553 return 0; 554 } 555 556 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 557 558 /* send read touchpanel command */ 559 if (j720ssp_readwrite(sc, 1, 0x500, &data, 100) < 0 || 560 data != 0x88) 561 goto out; 562 563 for(i = 0; i < 8; i++) { 564 if (j720ssp_readwrite(sc, 0, 0x8800, &data, 100) < 0) 565 goto out; 566 BIT_INVERT(data); 567 buf[i] = data; 568 } 569 570 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 571 572 buf[6] <<= 8; 573 buf[7] <<= 8; 574 for(i = 0; i < 3; i++) { 575 buf[i] |= buf[6] & 0x300; 576 buf[6] >>= 2; 577 buf[i + 3] |= buf[7] & 0x300; 578 buf[7] >>= 2; 579 } 580 #if 0 581 printf("j720tp_poll: %d %d %d %d %d %d\n", buf[0], buf[1], buf[2], 582 buf[3], buf[4], buf[5]); 583 #endif 584 585 /* XXX buf[1], buf[2], ... should also be used */ 586 tpcalib_trans(&sc->sc_tpcalib, buf[1], buf[4], &x, &y); 587 wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0, 588 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 589 590 return 1; 591 592 out: 593 *buf = 0; 594 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 595 596 /* reset SSP */ 597 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 598 delay(100); 599 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 600 printf("j720tp_poll: error %x\n", data); 601 602 return 0; 603 } 604 605 static int 606 j720tp_enable(arg) 607 void *arg; 608 { 609 struct j720ssp_softc *sc = arg; 610 int er, s; 611 612 s = splhigh(); 613 er = bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER); 614 er |= 1 << 9; 615 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER, er); 616 splx(s); 617 618 return (0); 619 } 620 621 static void 622 j720tp_disable(arg) 623 void *arg; 624 { 625 struct j720ssp_softc *sc = arg; 626 int er, s; 627 628 s = splhigh(); 629 er = bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER); 630 er &= ~(1 << 9); 631 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_FER, er); 632 splx(s); 633 } 634 635 static int 636 j720tp_ioctl(arg, cmd, data, flag, l) 637 void *arg; 638 u_long cmd; 639 caddr_t data; 640 int flag; 641 struct lwp *l; 642 { 643 struct j720ssp_softc *sc = arg; 644 645 return hpc_tpanel_ioctl(&sc->sc_tpcalib, cmd, data, flag, l); 646 } 647 648 int 649 j720lcdparam(ctx, type, id, msg) 650 void *ctx; 651 int type; 652 long id; 653 void *msg; 654 { 655 struct j720ssp_softc *sc = ctx; 656 int i, s; 657 u_int32_t data[2], len; 658 659 switch (type) { 660 case CONFIG_HOOK_GET: 661 switch (id) { 662 case CONFIG_HOOK_BRIGHTNESS_MAX: 663 case CONFIG_HOOK_CONTRAST_MAX: 664 *(int *)msg = 255; 665 return 1; 666 case CONFIG_HOOK_BRIGHTNESS: 667 data[0] = 0x6b00; 668 data[1] = 0x8800; 669 len = 2; 670 break; 671 case CONFIG_HOOK_CONTRAST: 672 data[0] = 0x2b00; 673 data[1] = 0x8800; 674 len = 2; 675 break; 676 default: 677 return 0; 678 } 679 break; 680 681 case CONFIG_HOOK_SET: 682 switch (id) { 683 case CONFIG_HOOK_BRIGHTNESS: 684 if (*(int *)msg >= 0) { 685 data[0] = 0xcb00; 686 data[1] = *(int *)msg; 687 BIT_INVERT(data[1]); 688 data[1] <<= 8; 689 len = 2; 690 } else { 691 /* XXX hack */ 692 data[0] = 0xfb00; 693 len = 1; 694 } 695 break; 696 case CONFIG_HOOK_CONTRAST: 697 data[0] = 0x8b00; 698 data[1] = *(int *)msg; 699 BIT_INVERT(data[1]); 700 data[1] <<= 8; 701 len = 2; 702 break; 703 default: 704 return 0; 705 } 706 break; 707 708 default: 709 return 0; 710 } 711 712 s = splbio(); 713 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 714 715 for (i = 0; i < len; i++) { 716 if (j720ssp_readwrite(sc, 1, data[i], &data[i], 500) < 0) 717 goto out; 718 } 719 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 720 splx(s); 721 722 if (type == CONFIG_HOOK_SET) 723 return 1; 724 725 BIT_INVERT(data[1]); 726 *(int *)msg = data[1]; 727 728 return 1; 729 730 out: 731 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 732 733 /* reset SSP */ 734 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 735 delay(100); 736 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 737 splx(s); 738 return 0; 739 } 740 741 static int 742 j720ssp_readwrite(sc, drainfifo, in, out, wait) 743 struct j720ssp_softc *sc; 744 int drainfifo; 745 int in; 746 int *out; 747 int wait; 748 { 749 int timo; 750 751 timo = 100000; 752 while(bus_space_read_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PLR) & 0x400) 753 if (--timo == 0) { 754 printf("timo0\n"); 755 return -1; 756 } 757 if (drainfifo) { 758 while(bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_SR) & 759 SR_RNE) 760 bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_DR); 761 #if 1 762 delay(wait); 763 #endif 764 } 765 766 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_DR, in); 767 768 delay(wait); 769 timo = 100000; 770 while(! (bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_SR) & SR_RNE)) 771 if (--timo == 0) { 772 printf("timo1\n"); 773 return -1; 774 } 775 776 *out = bus_space_read_4(sc->sc_iot, sc->sc_ssph, SASSP_DR); 777 778 return 0; 779 } 780 781 #if 0 782 int 783 j720kbd_cnattach(void) 784 { 785 /* XXX defer initialization till j720sspattach */ 786 787 return (0); 788 } 789 #endif 790 791 /* ARGSUSED */ 792 void 793 j720kbd_cngetc(v, type, data) 794 void *v; 795 u_int *type; 796 int *data; 797 { 798 char buf[9]; 799 800 if (j720kbdcons_initstate < 1) 801 return; 802 803 for (;;) { 804 j720kbd_read(&j720kbdcons_sc, buf); 805 806 if (buf[0] != 0) { 807 /* XXX we are discarding buffer contents */ 808 *type = buf[0] & 0x80 ? WSCONS_EVENT_KEY_UP : 809 WSCONS_EVENT_KEY_DOWN; 810 *data = buf[0] & 0x7f; 811 return; 812 } 813 } 814 } 815 816 void 817 j720kbd_cnpollc(v, on) 818 void *v; 819 int on; 820 { 821 #if 0 822 /* XXX */ 823 struct j720kbd_internal *t = v; 824 825 pckbc_set_poll(t->t_kbctag, t->t_kbcslot, on); 826 #endif 827 } 828 829 void 830 j720kbd_cnbell(v, pitch, period, volume) 831 void *v; 832 u_int pitch; 833 u_int period; 834 u_int volume; 835 { 836 } 837 838 int 839 j720lcdpower(ctx, type, id, msg) 840 void *ctx; 841 int type; 842 long id; 843 void *msg; 844 { 845 struct sed1356_softc *sc = ctx; 846 struct sa11x0_softc *psc = sc->sc_parent; 847 int val; 848 u_int32_t reg; 849 850 if (type != CONFIG_HOOK_POWERCONTROL || 851 id != CONFIG_HOOK_POWERCONTROL_LCDLIGHT) 852 return 0; 853 854 sed1356_init_brightness(sc, 0); 855 sed1356_init_contrast(sc, 0); 856 857 if (msg) { 858 bus_space_write_1(sc->sc_iot, sc->sc_regh, 0x1f0, 0); 859 860 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 861 reg |= 0x1; 862 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 863 delay(50000); 864 865 val = sc->sc_contrast; 866 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_CONTRAST, &val); 867 delay(100000); 868 869 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 870 reg |= 0x4; 871 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 872 873 val = sc->sc_brightness; 874 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 875 876 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 877 reg |= 0x2; 878 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 879 } else { 880 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 881 reg &= ~0x2; 882 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 883 reg &= ~0x4; 884 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 885 delay(100000); 886 887 val = -2; 888 config_hook_call(CONFIG_HOOK_SET, CONFIG_HOOK_BRIGHTNESS, &val); 889 890 bus_space_write_1(sc->sc_iot, sc->sc_regh, 0x1f0, 1); 891 892 delay(100000); 893 reg = bus_space_read_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR); 894 reg &= ~0x1; 895 bus_space_write_4(psc->sc_iot, psc->sc_ppch, SAPPC_PSR, reg); 896 } 897 return 1; 898 } 899 900 int 901 hpcarm_apm_getpower(api, parent) 902 struct apm_power_info *api; 903 void *parent; 904 { 905 int data, pmdata[3], i; 906 struct j720ssp_softc *sc = (struct j720ssp_softc *)parent; 907 908 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PCR, 0x2000000); 909 910 if (j720ssp_readwrite(sc, 1, 0x300, &data, 100) < 0 || data != 0x88) 911 goto out; 912 913 for (i = 0; i < 3; i++) { 914 if (j720ssp_readwrite(sc, 0, 0x8800, &pmdata[i], 500) < 0) 915 goto out; 916 BIT_INVERT(pmdata[i]); 917 } 918 919 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 920 921 bzero(api, sizeof(struct apm_power_info)); 922 api->ac_state = APM_AC_UNKNOWN; 923 924 /* 925 * pmdata[0] is the main battery level 926 * pmdata[1] is the backup battery level 927 * pmdata[2] tells which battery is present 928 */ 929 switch(pmdata[2]) { 930 case 14: /* backup battery present */ 931 case 2: /* backup battery absent */ 932 api->battery_state = APM_BATT_CHARGING; 933 api->minutes_left = (pmdata[0] * 840) / 170; 934 api->battery_life = (pmdata[0] * 100) / 170; 935 api->nbattery = 1; 936 break; 937 case 15: /* backup battery present */ 938 case 3: /* backup battery absent */ 939 api->battery_state = APM_BATT_ABSENT; 940 api->battery_life = 0; 941 api->nbattery = 0; 942 break; 943 default: 944 api->battery_state = APM_BATT_UNKNOWN; 945 break; 946 } 947 948 return 0; 949 950 out: 951 bus_space_write_4(sc->sc_iot, sc->sc_gpioh, SAGPIO_PSR, 0x2000000); 952 953 /* reset SSP */ 954 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x307); 955 delay(100); 956 bus_space_write_4(sc->sc_iot, sc->sc_ssph, SASSP_CR0, 0x387); 957 958 printf("hpcarm_apm_getpower: error %x\n", data); 959 return EIO; 960 } 961