Module Name: src Committed By: jklos Date: Fri Jan 2 21:32:26 UTC 2015
Modified Files: src/sys/dev/dec: dzkbd.c lk201_ws.c lk201var.h src/sys/dev/tc: zskbd.c Log Message: Patches from Björ Johannesson to fix DEC LK201 keyboards, this time applied to correct tree. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/sys/dev/dec/dzkbd.c cvs rdiff -u -r1.8 -r1.9 src/sys/dev/dec/lk201_ws.c cvs rdiff -u -r1.6 -r1.7 src/sys/dev/dec/lk201var.h cvs rdiff -u -r1.17 -r1.18 src/sys/dev/tc/zskbd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/dec/dzkbd.c diff -u src/sys/dev/dec/dzkbd.c:1.26 src/sys/dev/dec/dzkbd.c:1.27 --- src/sys/dev/dec/dzkbd.c:1.26 Sat Oct 27 17:18:15 2012 +++ src/sys/dev/dec/dzkbd.c Fri Jan 2 21:32:26 2015 @@ -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 * 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); } Index: src/sys/dev/dec/lk201_ws.c diff -u src/sys/dev/dec/lk201_ws.c:1.8 src/sys/dev/dec/lk201_ws.c:1.9 --- src/sys/dev/dec/lk201_ws.c:1.8 Sat Mar 14 15:36:17 2009 +++ src/sys/dev/dec/lk201_ws.c Fri Jan 2 21:32:26 2015 @@ -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 #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, in 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); } Index: src/sys/dev/dec/lk201var.h diff -u src/sys/dev/dec/lk201var.h:1.6 src/sys/dev/dec/lk201var.h:1.7 --- src/sys/dev/dec/lk201var.h:1.6 Sun Dec 11 12:21:20 2005 +++ src/sys/dev/dec/lk201var.h Fri Jan 2 21:32:26 2015 @@ -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 + Index: src/sys/dev/tc/zskbd.c diff -u src/sys/dev/tc/zskbd.c:1.17 src/sys/dev/tc/zskbd.c:1.18 --- src/sys/dev/tc/zskbd.c:1.17 Tue May 12 14:47:05 2009 +++ src/sys/dev/tc/zskbd.c Fri Jan 2 21:32:26 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: zskbd.c,v 1.17 2009/05/12 14:47:05 cegger Exp $ */ +/* $NetBSD: zskbd.c,v 1.18 2015/01/02 21:32:26 jklos Exp $ */ /* * Copyright (c) 1992, 1993 @@ -45,7 +45,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: zskbd.c,v 1.17 2009/05/12 14:47:05 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: zskbd.c,v 1.18 2015/01/02 21:32:26 jklos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -281,7 +281,7 @@ zskbd_cngetc(void *v, u_int *type, int * do { c = zs_getc(zsi->zsi_cs); - } while (!lk201_decode(&zsi->zsi_ks, c, type, data)); + } while (!lk201_decode(&zsi->zsi_ks, 0, c, type, data) == LKD_NODATA); } static void @@ -336,12 +336,15 @@ zskbd_input(struct zskbd_softc *sc, int { u_int type; int val; + int decode; - if (sc->sc_enabled == 0) - return; + do { + decode = lk201_decode(&sc->sc_itl->zsi_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->zsi_ks, data, &type, &val)) - wskbd_input(sc->sc_wskbddev, type, val); } /****************************************************************