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