diff options
| author | jklos <jklos@NetBSD.org> | 2015-01-02 21:32:26 +0000 |
|---|---|---|
| committer | jklos <jklos@NetBSD.org> | 2015-01-02 21:32:26 +0000 |
| commit | 5326aa6eff4b6da27166a62e129cd2965a5ecc4d (patch) | |
| tree | a7f0ff2161e8c2614514605d9f45bd090676151e /sys/dev/dec | |
| parent | 6da2d2aa1210b81892cec7c71c985d6c51e1e446 (diff) | |
Patches from Björ Johannesson to fix DEC LK201 keyboards, this time
applied to correct tree.
Diffstat (limited to 'sys/dev/dec')
| -rw-r--r-- | sys/dev/dec/dzkbd.c | 17 | ||||
| -rw-r--r-- | sys/dev/dec/lk201_ws.c | 97 | ||||
| -rw-r--r-- | sys/dev/dec/lk201var.h | 17 |
3 files changed, 118 insertions, 13 deletions
diff --git a/sys/dev/dec/dzkbd.c b/sys/dev/dec/dzkbd.c index 1003a9679de..6f3c6c64fef 100644 --- a/sys/dev/dec/dzkbd.c +++ b/sys/dev/dec/dzkbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: dzkbd.c,v 1.26 2012/10/27 17:18:15 chs Exp $ */ +/* $NetBSD: dzkbd.c,v 1.27 2015/01/02 21:32:26 jklos Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dzkbd.c,v 1.26 2012/10/27 17:18:15 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dzkbd.c,v 1.27 2015/01/02 21:32:26 jklos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -237,7 +237,7 @@ dzkbd_cngetc(void *v, u_int *type, int *data) do { c = dzgetc(dzi->dzi_ls); - } while (!lk201_decode(&dzi->dzi_ks, c, type, data)); + } while (!lk201_decode(&dzi->dzi_ks, 0, c, type, data) == LKD_NODATA); } static void @@ -294,12 +294,15 @@ dzkbd_input(void *v, int data) struct dzkbd_softc *sc = (struct dzkbd_softc *)v; u_int type; int val; + int decode; - if (sc->sc_enabled == 0) - return(0); + do { + decode = lk201_decode(&sc->sc_itl->dzi_ks, 1, + data, &type, &val); + if (decode != LKD_NODATA) + wskbd_input(sc->sc_wskbddev, type, val); + } while (decode == LKD_MORE); - if (lk201_decode(&sc->sc_itl->dzi_ks, data, &type, &val)) - wskbd_input(sc->sc_wskbddev, type, val); return(1); } diff --git a/sys/dev/dec/lk201_ws.c b/sys/dev/dec/lk201_ws.c index df51ba79221..1ce77046de3 100644 --- a/sys/dev/dec/lk201_ws.c +++ b/sys/dev/dec/lk201_ws.c @@ -1,4 +1,4 @@ -/* $NetBSD: lk201_ws.c,v 1.8 2009/03/14 15:36:17 dsl Exp $ */ +/* $NetBSD: lk201_ws.c,v 1.9 2015/01/02 21:32:26 jklos Exp $ */ /* * Copyright (c) 1998 @@ -27,10 +27,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lk201_ws.c,v 1.8 2009/03/14 15:36:17 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lk201_ws.c,v 1.9 2015/01/02 21:32:26 jklos Exp $"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/callout.h> #include <dev/wscons/wsconsio.h> @@ -40,11 +41,23 @@ __KERNEL_RCSID(0, "$NetBSD: lk201_ws.c,v 1.8 2009/03/14 15:36:17 dsl Exp $"); #define send(lks, c) ((*((lks)->attmt.sendchar))((lks)->attmt.cookie, c)) +void lk201_identify(void *); + +static callout_t lkkbd_id; + +static const char *lkkbd_descr[] = { + "no keyboard", + "LK-201 keyboard", + "LK-401 keyboard", +}; + int lk201_init(struct lk201_state *lks) { int i; + lks->waitack = 0; + send(lks, LK_LED_ENABLE); send(lks, LK_LED_ALL); @@ -69,20 +82,78 @@ lk201_init(struct lk201_state *lks) send(lks, LK_LED_ALL); lks->leds_state = 0; + callout_init(&lkkbd_id, 0); + callout_setfunc(&lkkbd_id, lk201_identify, lks); + callout_schedule(&lkkbd_id, 0); + return (0); } +void +lk201_identify(void *v) +{ + struct lk201_state *lks = v; + int i; + + callout_destroy(&lkkbd_id); + /* + * Swallow all the keyboard acknowledges from lk201_init(). + * There should be 14 of them - one per LK_CMD_MODE command. + */ + for(;;) { + lks->waitack = 1; + for (i = 100; i != 0; i--) { + DELAY(1000); + if (lks->waitack == 0) + break; + } + if (i == 0) + break; + } + + /* + * Try to set the keyboard in LK-401 mode. + * If we receive an error, this is an LK-201 keyboard. + */ + lks->waitack = 1; + send(lks, LK_ENABLE_401); + for (i = 100; i != 0; i--) { + DELAY(1000); + if (lks->waitack == 0) + break; + } + if (lks->waitack != 0) + lks->kbdtype = KBD_NONE; + else { + if (lks->ackdata == LK_INPUT_ERROR) + lks->kbdtype = KBD_LK201; + else + lks->kbdtype = KBD_LK401; + } + lks->waitack = 0; + + printf("lkkbd0: %s\n", lkkbd_descr[lks->kbdtype]); +} + int -lk201_decode(struct lk201_state *lks, int datain, u_int *type, int *dataout) +lk201_decode(struct lk201_state *lks, int wantmulti, int datain, u_int *type, int *dataout) { int i, freeslot; + if (lks->waitack != 0) { + lks->ackdata = datain; + lks->waitack = 0; + return LKD_NODATA; + } + switch (datain) { +#if 0 case LK_KEY_UP: for (i = 0; i < LK_KLL; i++) lks->down_keys_list[i] = -1; *type = WSCONS_EVENT_ALL_KEYS_UP; return (1); +#endif case LK_POWER_UP: printf("lk201_decode: powerup detected\n"); lk201_init(lks); @@ -98,7 +169,25 @@ lk201_decode(struct lk201_state *lks, int datain, u_int *type, int *dataout) return (0); } - if (datain < MIN_LK201_KEY || datain > MAX_LK201_KEY) { + + if (datain == LK_KEY_UP) { + if (wantmulti) { + for (i = 0; i < LK_KLL; i++) + if (lks->down_keys_list[i] != -1) { + *type = WSCONS_EVENT_KEY_UP; + *dataout = lks->down_keys_list[i] - + MIN_LK201_KEY; + lks->down_keys_list[i] = -1; + return (LKD_MORE); + } + return (LKD_NODATA); + } else { + for (i = 0; i < LK_KLL; i++) + lks->down_keys_list[i] = -1; + *type = WSCONS_EVENT_ALL_KEYS_UP; + return (LKD_COMPLETE); + } + } else if (datain < MIN_LK201_KEY || datain > MAX_LK201_KEY) { printf("lk201_decode: %x\n", datain); return (0); } diff --git a/sys/dev/dec/lk201var.h b/sys/dev/dec/lk201var.h index df4d109fd8c..af9f0226557 100644 --- a/sys/dev/dec/lk201var.h +++ b/sys/dev/dec/lk201var.h @@ -1,4 +1,4 @@ -/* $NetBSD: lk201var.h,v 1.6 2005/12/11 12:21:20 christos Exp $ */ +/* $NetBSD: lk201var.h,v 1.7 2015/01/02 21:32:26 jklos Exp $ */ /* * Copyright (c) 1998 @@ -33,6 +33,14 @@ struct lk201_attachment { struct lk201_state { struct lk201_attachment attmt; + + volatile int waitack; + int ackdata; + + int kbdtype; +#define KBD_NONE 0x00 +#define KBD_LK201 0x01 +#define KBD_LK401 0x02 #define LK_KLL 8 int down_keys_list[LK_KLL]; int bellvol; @@ -41,7 +49,12 @@ struct lk201_state { }; int lk201_init(struct lk201_state *); -int lk201_decode(struct lk201_state *, int, u_int *, int *); +int lk201_decode(struct lk201_state *, int, int, u_int *, int *); void lk201_bell(struct lk201_state *, struct wskbd_bell_data *); void lk201_set_leds(struct lk201_state *, int); void lk201_set_keyclick(struct lk201_state *, int); + +#define LKD_NODATA 0x00 +#define LKD_COMPLETE 0x01 +#define LKD_MORE 0x02 + |
