Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc/dev First cut at PS/2 keyboard and mouse driv...
details: https://anonhg.NetBSD.org/src/rev/fc86f84d04bb
branches: trunk
changeset: 537621:fc86f84d04bb
user: uwe <uwe%NetBSD.org@localhost>
date: Thu Oct 03 16:27:04 2002 +0000
description:
First cut at PS/2 keyboard and mouse drivers that talk Sun firm events.
Console and Xsun for Mr.Coffee.
diffstat:
sys/arch/sparc/dev/kbd_pckbc.c | 771 +++++++++++++++++++++++++++++++++++++++++
sys/arch/sparc/dev/ms_pckbc.c | 308 ++++++++++++++++
2 files changed, 1079 insertions(+), 0 deletions(-)
diffs (truncated from 1087 to 300 lines):
diff -r beb081d35121 -r fc86f84d04bb sys/arch/sparc/dev/kbd_pckbc.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sparc/dev/kbd_pckbc.c Thu Oct 03 16:27:04 2002 +0000
@@ -0,0 +1,771 @@
+/* $NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $ */
+
+/*
+ * Copyright (c) 2002 Valeriy E. Ushakov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $");
+
+/*
+ * Pretend we are a Type5 keyboard with US101A layout.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/select.h>
+#include <sys/syslog.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <machine/kbd.h>
+#include <machine/kbio.h>
+
+#include <dev/pckbc/pckbdreg.h>
+
+#include <dev/ic/pckbcvar.h>
+
+#include <dev/sun/event_var.h>
+#include <dev/sun/kbd_xlate.h>
+#include <dev/sun/kbdvar.h>
+
+#define DPRINTF(args) /* printf args */
+
+
+struct kbd_pckbc_softc {
+ struct kbd_softc sc_kbd;
+
+ /* pckbc attachment */
+ pckbc_tag_t sc_kbctag;
+ pckbc_slot_t sc_kbcslot;
+
+ /*
+ * Middle layer data.
+ */
+ int sc_isopen;
+ int sc_pcleds;
+
+ /* xt scan-codes decoding */
+ int sc_lastchar;
+ int sc_extended;
+ int sc_extended1;
+
+};
+
+static int kbd_pckbc_match(struct device *, struct cfdata *, void *);
+static void kbd_pckbc_attach(struct device *, struct device *, void *);
+
+CFATTACH_DECL(kbd_pckbc, sizeof(struct kbd_pckbc_softc),
+ kbd_pckbc_match, kbd_pckbc_attach, NULL, NULL);
+
+
+/*
+ * Middle layer.
+ */
+
+/* callbacks for the upper /dev/kbd layer */
+static int kbd_pckbc_open(struct kbd_softc *);
+static int kbd_pckbc_close(struct kbd_softc *);
+static int kbd_pckbc_do_cmd(struct kbd_softc *, int, int);
+static int kbd_pckbc_set_leds(struct kbd_softc *, int, int);
+
+struct kbd_ops kbd_ops_pckbc = {
+ kbd_pckbc_open,
+ kbd_pckbc_close,
+ kbd_pckbc_do_cmd,
+ kbd_pckbc_set_leds
+};
+
+
+static u_int8_t kbd_pckbc_xt_to_sun[];
+
+static int kbd_pckbc_set_xtscancode(pckbc_tag_t, pckbc_slot_t);
+static void kbd_pckbc_input(void *, int);
+static int kbd_pckbc_decode(struct kbd_pckbc_softc *, int, int *);
+
+
+/*********************************************************************
+ * Autoconfiguration
+ */
+
+int
+kbd_pckbc_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct pckbc_attach_args *pa = aux;
+
+ if (pa->pa_slot != PCKBC_KBD_SLOT)
+ return (0);
+
+ return (1);
+}
+
+
+void
+kbd_pckbc_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+
+{
+ struct kbd_pckbc_softc *sc = (void *)self;
+ struct pckbc_attach_args *pa = aux;
+ struct kbd_softc *kbd = &sc->sc_kbd;
+ struct kbd_state *ks = &kbd->k_state;
+
+ /* save our attachment to pckbc */
+ sc->sc_kbctag = pa->pa_tag;
+ sc->sc_kbcslot = pa->pa_slot;
+
+ /* provide upper layer a link to our middle layer */
+ kbd->k_ops = &kbd_ops_pckbc;
+
+ /* pre-fill keyboard id/layout */
+ ks->kbd_id = KB_SUN4;
+ ks->kbd_layout = 19; /* US101A */
+
+ if (1) {
+ /*
+ * Hookup ourselves as the console input channel
+ */
+ extern void kd_attach_input(struct cons_channel *);
+ struct cons_channel *cc;
+
+ if ((cc = malloc(sizeof *cc, M_DEVBUF, M_NOWAIT)) == NULL)
+ return;
+
+ cc->cc_dev = self;
+ cc->cc_iopen = kbd_cc_open;
+ cc->cc_iclose = kbd_cc_close;
+ cc->cc_upstream = NULL; /* will be provided by upper driver */
+ kd_attach_input(cc); /* XXX ???? */
+
+ kbd->k_cc = cc;
+ kbd->k_isconsole = 1;
+
+ printf(": console input");
+ }
+
+ printf("\n");
+
+ kbd_pckbc_set_xtscancode(sc->sc_kbctag, sc->sc_kbcslot);
+
+ /* slow down typematic (can't disable, grrr) */
+ {
+ u_char cmd[2];
+ int res;
+
+ cmd[0] = KBC_TYPEMATIC;
+ cmd[1] = 0x7f; /* 1s, 2/s */
+ res = pckbc_poll_cmd(sc->sc_kbctag, sc->sc_kbcslot,
+ cmd, 2, 0, NULL, 0);
+ if (res) {
+ printf("%s: set typematic failed, error %d\n",
+ kbd->k_dev.dv_xname, res);
+ }
+ }
+
+ /* register our callback with pckbc interrupt handler */
+ pckbc_set_inputhandler(sc->sc_kbctag, sc->sc_kbcslot,
+ kbd_pckbc_input, sc,
+ kbd->k_dev.dv_xname);
+}
+
+
+static int
+kbd_pckbc_set_xtscancode(kbctag, kbcslot)
+ pckbc_tag_t kbctag;
+ pckbc_slot_t kbcslot;
+{
+ u_char cmd[2];
+ int res;
+
+ /*
+ * Some keyboard/8042 combinations do not seem to work if the keyboard
+ * is set to table 1; in fact, it would appear that some keyboards just
+ * ignore the command altogether. So by default, we use the AT scan
+ * codes and have the 8042 translate them. Unfortunately, this is
+ * known to not work on some PS/2 machines. We try desparately to deal
+ * with this by checking the (lack of a) translate bit in the 8042 and
+ * attempting to set the keyboard to XT mode. If this all fails, well,
+ * tough luck.
+ *
+ * XXX It would perhaps be a better choice to just use AT scan codes
+ * and not bother with this.
+ */
+ if (pckbc_xt_translation(kbctag, kbcslot, 1)) {
+ /* The 8042 is translating for us; use AT codes. */
+ cmd[0] = KBC_SETTABLE;
+ cmd[1] = 2;
+ res = pckbc_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0);
+ if (res) {
+ u_char cmd[1];
+#ifdef DEBUG
+ printf("pckbd: error setting scanset 2\n");
+#endif
+ /*
+ * XXX at least one keyboard is reported to lock up
+ * if a "set table" is attempted, thus the "reset".
+ * XXX ignore errors, scanset 2 should be
+ * default anyway.
+ */
+ cmd[0] = KBC_RESET;
+ (void)pckbc_poll_cmd(kbctag, kbcslot, cmd, 1, 1, 0, 1);
+ pckbc_flush(kbctag, kbcslot);
+ res = 0;
+ }
+ } else {
+ /* Stupid 8042; set keyboard to XT codes. */
+ cmd[0] = KBC_SETTABLE;
+ cmd[1] = 1;
+ res = pckbc_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0);
+#ifdef DEBUG
+ if (res)
+ printf("pckbd: error setting scanset 1\n");
+#endif
+ }
+ return (res);
+}
+
+
+/*********************************************************************
+ * /dev/kbd middle layer
+ */
+
+/*
+ * Initialization to be done at first open.
+ * This is called from kbdopen() or kd_cc_open()
+ * Called with user context.
+ */
+static int
+kbd_pckbc_open(kbd)
+ struct kbd_softc *kbd;
+{
+ struct kbd_pckbc_softc *sc = (struct kbd_pckbc_softc *)kbd;
+ struct kbd_state *ks;
+ int error = 0;
+
+ if (kbd == NULL) {
+ DPRINTF(("kbd_pckbc_open: kbd == NULL\n"));
+ return (ENXIO);
+ }
+
+ ks = &kbd->k_state;
+
+ /* tolerate extra calls. */
+ if (sc->sc_isopen)
+ return (0);
+
+ /* open internal device */
+
+ /* reset the keyboard (and enable interrupts?) */
+
+ /* initialize the table pointers for this type */
+ kbd_xlate_init(ks);
+
+ /* layout US101A */
+
Home |
Main Index |
Thread Index |
Old Index