summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-07-31 06:47:26 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-07-31 06:47:26 +0000
commite9fe007d506ddbbb2153f193ad78706a914a3432 (patch)
tree59460382c5edd8a6fceefa14e45ade95d80f21d7 /sys/arch
parent0c43d9678ef48189d7d1efc8613c68f4e8fbac28 (diff)
On startup, and when a keyboard change is detected, probe for the keyboard
type. For now it is only reported to the user, but we'll use this very soon to alter keycodes depending upon the keyboard type (so that we do not have the compose and alt keys swapped on LK401 keyboards).
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/vax/dec/dzkbd.c11
-rw-r--r--sys/arch/vax/dec/lk201_ws.c83
-rw-r--r--sys/arch/vax/dec/lk201var.h34
3 files changed, 105 insertions, 23 deletions
diff --git a/sys/arch/vax/dec/dzkbd.c b/sys/arch/vax/dec/dzkbd.c
index 5c3e3a81265..4ba622f3663 100644
--- a/sys/arch/vax/dec/dzkbd.c
+++ b/sys/arch/vax/dec/dzkbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dzkbd.c,v 1.7 2006/07/30 18:35:10 miod Exp $ */
+/* $OpenBSD: dzkbd.c,v 1.8 2006/07/31 06:47:25 miod Exp $ */
/* $NetBSD: dzkbd.c,v 1.1 2000/12/02 17:03:55 ragge Exp $ */
/*
@@ -51,6 +51,7 @@
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
+#include <sys/timeout.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
@@ -174,6 +175,7 @@ dzkbd_attach(struct device *parent, struct device *self, void *aux)
dzi->dzi_ks.attmt.sendchar = dzkbd_sendchar;
dzi->dzi_ks.attmt.cookie = ls;
}
+ dzi->dzi_ks.device = self;
dzi->dzi_ls = ls;
dzkbd->sc_itl = dzi;
@@ -182,10 +184,7 @@ dzkbd_attach(struct device *parent, struct device *self, void *aux)
if (!isconsole)
lk201_init(&dzi->dzi_ks);
- /* XXX should identify keyboard ID here XXX */
- /* XXX layout and the number of LED is varying XXX */
-
- a.console = isconsole;
+ a.console = dzi == &dzkbd_console_internal;
a.keymap = &dzkbd_keymapdata;
a.accessops = &dzkbd_accessops;
a.accesscookie = dzkbd;
@@ -203,7 +202,7 @@ dzkbd_cnattach(struct dz_linestate *ls)
dzkbd_console_internal.dzi_ls = ls;
wskbd_cnattach(&dzkbd_consops, &dzkbd_console_internal,
- &dzkbd_keymapdata);
+ &dzkbd_keymapdata);
return 0;
}
diff --git a/sys/arch/vax/dec/lk201_ws.c b/sys/arch/vax/dec/lk201_ws.c
index d00ec591aee..eceb949864d 100644
--- a/sys/arch/vax/dec/lk201_ws.c
+++ b/sys/arch/vax/dec/lk201_ws.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lk201_ws.c,v 1.5 2006/07/30 18:35:10 miod Exp $ */
+/* $OpenBSD: lk201_ws.c,v 1.6 2006/07/31 06:47:25 miod Exp $ */
/* $NetBSD: lk201_ws.c,v 1.2 1998/10/22 17:55:20 drochner Exp $ */
/*
@@ -35,6 +35,10 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/timeout.h>
#include <dev/wscons/wsconsio.h>
@@ -42,14 +46,23 @@
#include <vax/dec/lk201var.h>
#include <vax/dec/wskbdmap_lk201.h> /* for {MIN,MAX}_LK201_KEY */
-#define send(lks, c) ((*((lks)->attmt.sendchar))((lks)->attmt.cookie, c))
+void lk201_identify(void *);
-int
-lk201_init(lks)
- struct lk201_state *lks;
+static const char *lkkbd_descr[] = {
+ "no keyboard",
+ "LK-201 keyboard",
+ "LK-401 keyboard"
+};
+
+#define send(lks, c) ((*((lks)->attmt.sendchar))((lks)->attmt.cookie, c))
+
+void
+lk201_init(struct lk201_state *lks)
{
int i;
+ lks->waitack = 0;
+
send(lks, LK_LED_ENABLE);
send(lks, LK_LED_ALL);
@@ -73,7 +86,59 @@ lk201_init(lks)
send(lks, LK_LED_ALL);
lks->leds_state = 0;
- return (0);
+ /*
+ * Note that, when attaching lkkbd initially, this timeout will
+ * be scheduled but will not run until interrupts are enabled.
+ * This is not a problem, since lk201_identify() relies upon
+ * interrupts being enabled.
+ */
+ timeout_set(&lks->probetmo, lk201_identify, lks);
+ timeout_add(&lks->probetmo, 0);
+}
+
+void
+lk201_identify(void *v)
+{
+ struct lk201_state *lks = v;
+ int i;
+
+ /*
+ * 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 = 10; 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 = 10; 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("%s: %s\n", lks->device->dv_xname, lkkbd_descr[lks->kbdtype]);
}
int
@@ -82,6 +147,12 @@ lk201_decode(struct lk201_state *lks, int active, int datain, u_int *type,
{
int i, freeslot;
+ if (lks->waitack != 0) {
+ lks->ackdata = datain;
+ lks->waitack = 0;
+ return (0);
+ }
+
switch (datain) {
case LK_KEY_UP:
for (i = 0; i < LK_KLL; i++)
diff --git a/sys/arch/vax/dec/lk201var.h b/sys/arch/vax/dec/lk201var.h
index 378eb2d4aa9..56a3a648a8a 100644
--- a/sys/arch/vax/dec/lk201var.h
+++ b/sys/arch/vax/dec/lk201var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lk201var.h,v 1.4 2006/07/30 18:35:10 miod Exp $ */
+/* $OpenBSD: lk201var.h,v 1.5 2006/07/31 06:47:25 miod Exp $ */
/* $NetBSD: lk201var.h,v 1.2 1998/10/22 17:55:20 drochner Exp $ */
/*
@@ -39,16 +39,28 @@ struct lk201_attachment {
};
struct lk201_state {
- struct lk201_attachment attmt;
+ struct device *device;
+ struct lk201_attachment attmt;
+
+ struct timeout probetmo;
+ 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;
- int leds_state;
- int kcvol;
+ int down_keys_list[LK_KLL];
+
+ int bellvol;
+ int leds_state;
+ int kcvol;
};
-int lk201_init(struct lk201_state *);
-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);
+void lk201_bell(struct lk201_state *, struct wskbd_bell_data *);
+int lk201_decode(struct lk201_state *, int, int, u_int *, int *);
+void lk201_init(struct lk201_state *);
+void lk201_set_keyclick(struct lk201_state *, int);
+void lk201_set_leds(struct lk201_state *, int);