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);
 }
 
 /****************************************************************

Reply via email to