static int pms_protocol(pckbport_tag_t tag, pckbport_slot_t slot) { u_char cmd[2], resp[1]; int i, j, res; const struct pms_protocol *p; for (j = 0; j < sizeof(tries) / sizeof(tries[0]); ++j) { p = &pms_protocols[tries[j]]; if (!p->rates[0]) break; cmd[0] = PMS_SET_SAMPLE; for (i = 0; i < 3; i++) { cmd[1] = p->rates[i]; res = pckbport_enqueue_cmd(tag, slot, cmd, 2, 0, 1, 0); if (res) return PMS_STANDARD; } cmd[0] = PMS_SEND_DEV_ID; res = pckbport_enqueue_cmd(tag, slot, cmd, 1, 1, 1, resp); if (res) return PMS_UNKNOWN; if (resp[0] == p->response) { DPRINTF(("pms_protocol: found mouse protocol %d\n", tries[j])); return tries[j]; } } DPRINTF(("pms_protocol: standard PS/2 protocol (no scroll wheel)\n")); return PMS_STANDARD; }
static void do_enable(struct pms_softc *sc) { u_char cmd[2]; int res; sc->inputstate = 0; sc->buttons = 0; pckbport_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 1); #ifdef PMS_SYNAPTICS_TOUCHPAD if (sc->protocol == PMS_SYNAPTICS) pms_synaptics_enable(sc); #endif #ifdef PMS_ELANTECH_TOUCHPAD if (sc->protocol == PMS_ELANTECH) pms_elantech_enable(sc); #endif cmd[0] = PMS_DEV_ENABLE; res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 0, 1, 0); if (res) aprint_error("pms_enable: command error %d\n", res); if (sc->protocol == PMS_UNKNOWN) sc->protocol = pms_protocol(sc->sc_kbctag, sc->sc_kbcslot); DPRINTF(("pms_enable: using %s protocol\n", pms_protocols[sc->protocol].name)); #if 0 { u_char scmd[2]; scmd[0] = PMS_SET_RES; scmd[1] = 3; /* 8 counts/mm */ res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, scmd, 2, 0, 1, 0); if (res) printf("pms_enable: setup error1 (%d)\n", res); scmd[0] = PMS_SET_SCALE21; res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, scmd, 1, 0, 1, 0); if (res) printf("pms_enable: setup error2 (%d)\n", res); scmd[0] = PMS_SET_SAMPLE; scmd[1] = 100; /* 100 samples/sec */ res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, scmd, 2, 0, 1, 0); if (res) printf("pms_enable: setup error3 (%d)\n", res); } #endif }
void pckbd_set_leds(void *v, int leds) { struct pckbd_softc *sc = v; u_char cmd[2]; cmd[0] = KBC_MODEIND; cmd[1] = pckbd_led_encode(leds); sc->sc_ledstate = cmd[1]; (void)pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot, cmd, 2, 0, 0, 0); }
int pckbd_enable(void *v, int on) { struct pckbd_softc *sc = v; int res; u_char cmd[1]; if (on) { if (sc->sc_enabled) { #ifdef DIAGNOSTIC printf("pckbd_enable: bad enable\n"); #endif return EBUSY; } pckbport_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 1); cmd[0] = KBC_ENABLE; res = pckbport_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot, cmd, 1, 0, NULL, 0); if (res) { printf("pckbd_enable: command error\n"); return (res); } res = pckbd_set_xtscancode(sc->id->t_kbctag, sc->id->t_kbcslot); if (res) return res; sc->sc_enabled = 1; } else { if (sc->id->t_isconsole) return EBUSY; cmd[0] = KBC_DISABLE; res = pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot, cmd, 1, 0, 1, 0); if (res) { printf("pckbd_disable: command error\n"); return res; } pckbport_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 0); sc->sc_enabled = 0; } return 0; }
static void do_disable(struct pms_softc *sc) { u_char cmd[1]; int res; cmd[0] = PMS_DEV_DISABLE; res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 0, 1, 0); if (res) aprint_error("pms_disable: command error\n"); pckbport_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 0); }
int pckbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) { struct pckbd_softc *sc = v; switch (cmd) { case WSKBDIO_GTYPE: *(int *)data = WSKBD_TYPE_PC_XT; return 0; case WSKBDIO_SETLEDS: { int res; u_char cmdb[2]; cmdb[0] = KBC_MODEIND; cmdb[1] = pckbd_led_encode(*(int *)data); sc->sc_ledstate = cmdb[1]; res = pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot, cmdb, 2, 0, 1, 0); return res; } case WSKBDIO_GETLEDS: *(int *)data = pckbd_led_decode(sc->sc_ledstate); return 0; case WSKBDIO_COMPLEXBELL: #define d ((struct wskbd_bell_data *)data) /* * Keyboard can't beep directly; we have an * externally-provided global hook to do this. */ pckbd_bell(d->pitch, d->period, d->volume, 0); #undef d return 0; #ifdef WSDISPLAY_COMPAT_RAWKBD case WSKBDIO_SETMODE: sc->rawkbd = (*(int *)data == WSKBD_RAW); return 0; #endif } return EPASSTHROUGH; }
static bool pckbd_suspend(device_t dv, const pmf_qual_t *qual) { struct pckbd_softc *sc = device_private(dv); u_char cmd[1]; int res; /* XXX duped from pckbd_enable, but we want to disable * it even if it's the console kbd */ cmd[0] = KBC_DISABLE; res = pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot, cmd, 1, 0, 1, 0); if (res) return false; pckbport_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 0); sc->sc_enabled = 0; return true; }
int pms_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) { struct pms_softc *sc = v; u_char kbcmd[2]; int i; switch (cmd) { case WSMOUSEIO_GTYPE: *(u_int *)data = WSMOUSE_TYPE_PS2; break; case WSMOUSEIO_SRES: i = (*(u_int *)data - 12) / 25; if (i < 0) i = 0; if (i > 3) i = 3; kbcmd[0] = PMS_SET_RES; kbcmd[1] = i; i = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, kbcmd, 2, 0, 1, 0); if (i) printf("pms_ioctl: SET_RES command error\n"); break; default: return EPASSTHROUGH; } return 0; }
static void pms_reset_thread(void *arg) { struct pms_softc *sc = arg; u_char cmd[1], resp[2]; int res; int save_protocol; for (;;) { tsleep(&sc->sc_enabled, PWAIT, "pmsreset", 0); #ifdef PMSDEBUG if (pmsdebug) #endif #if defined(PMSDEBUG) || defined(DIAGNOSTIC) aprint_debug_dev(sc->sc_dev, "resetting mouse interface\n"); #endif save_protocol = sc->protocol; pms_disable(sc); cmd[0] = PMS_RESET; res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 2, 1, resp); if (res) { DPRINTF(("%s: reset error %d\n", device_xname(sc->sc_dev), res)); } /* For the synaptics and elantech case, leave the protocol alone. */ if (sc->protocol != PMS_SYNAPTICS && sc->protocol != PMS_ELANTECH) sc->protocol = PMS_UNKNOWN; pms_enable(sc); if (sc->protocol != save_protocol) { #if defined(PMSDEBUG) || defined(DIAGNOSTIC) aprint_verbose_dev(sc->sc_dev, "protocol change, sleeping and retrying\n"); #endif pms_disable(sc); cmd[0] = PMS_RESET; res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 2, 1, resp); if (res) { DPRINTF(("%s: reset error %d\n", device_xname(sc->sc_dev), res)); } tsleep(pms_reset_thread, PWAIT, "pmsreset", hz); cmd[0] = PMS_RESET; res = pckbport_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, cmd, 1, 2, 1, resp); if (res) { DPRINTF(("%s: reset error %d\n", device_xname(sc->sc_dev), res)); } sc->protocol = PMS_UNKNOWN; /* reprobe protocol */ pms_enable(sc); #if defined(PMSDEBUG) || defined(DIAGNOSTIC) if (sc->protocol != save_protocol) { printf("%s: protocol changed.\n", device_xname(sc->sc_dev)); } #endif } } }