summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/isa/pckbd.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-06-18 09:45:47 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-06-18 09:45:47 +0000
commit41ae123ec2d77615cd0b0476ff62564bd7a4865f (patch)
treeba6a57d3a8d7d725a5e0ae64e8401ed3bea0efb9 /sys/arch/alpha/isa/pckbd.c
parent7a0b7f798c45842a34a4c6413f45e1b3824154a5 (diff)
sync to 0616, retaining local diffs
Diffstat (limited to 'sys/arch/alpha/isa/pckbd.c')
-rw-r--r--sys/arch/alpha/isa/pckbd.c400
1 files changed, 236 insertions, 164 deletions
diff --git a/sys/arch/alpha/isa/pckbd.c b/sys/arch/alpha/isa/pckbd.c
index ab269620ef7..0a212449aeb 100644
--- a/sys/arch/alpha/isa/pckbd.c
+++ b/sys/arch/alpha/isa/pckbd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbd.c,v 1.3 1995/12/24 02:29:35 mycroft Exp $ */
+/* $NetBSD: pckbd.c,v 1.7 1996/05/05 01:41:53 thorpej Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles Hannum. All rights reserved.
@@ -52,16 +52,18 @@
#include <sys/kernel.h>
#include <sys/device.h>
-#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <machine/bus.h>
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
#include <alpha/isa/pckbdreg.h>
+#include <alpha/isa/spkrreg.h>
+#include <alpha/isa/timerreg.h>
+#include <machine/wsconsio.h>
-#include "wsc.h"
-#if NWSC
-#include <alpha/pci/wsconsvar.h>
-#endif
+#include <alpha/wscons/wsconsvar.h>
+#include "wscons.h"
static volatile u_char ack, nak; /* Don't ask. */
static u_char async, kernel, polling; /* Really, you don't want to know. */
@@ -70,28 +72,58 @@ static u_char lock_state = 0x00, /* all off */
typematic_rate = 0xff, /* don't update until set by user */
old_typematic_rate = 0xff;
-__const struct isa_intr_fns *pckbd_intr_fns; /* XXX */
-void *pckbd_intr_arg; /* XXX */
-__const struct isa_pio_fns *pckbd_pio_fns; /* XXX */
-void *pckbd_pio_arg; /* XXX */
+bus_chipset_tag_t pckbd_bc;
+isa_chipset_tag_t pckbd_ic;
+
+bus_io_handle_t pckbd_data_ioh;
+#define pckbd_out_ioh pckbd_data_ioh
+bus_io_handle_t pckbd_status_ioh;
+#define pckbd_cmd_ioh pckbd_status_ioh
+bus_io_handle_t pckbd_timer_ioh;
+bus_io_handle_t pckbd_pitaux_ioh;
+bus_io_handle_t pckbd_delay_ioh;
struct pckbd_softc {
struct device sc_dev;
void *sc_ih;
+
+ int sc_bellactive; /* is the bell active? */
+ int sc_bellpitch; /* last pitch programmed */
};
int pckbdprobe __P((struct device *, void *, void *));
void pckbdattach __P((struct device *, struct device *, void *));
int pckbdintr __P((void *));
-struct cfdriver pckbdcd = {
- NULL, "pckbd", pckbdprobe, pckbdattach, DV_DULL,
- sizeof(struct pckbd_softc)
+struct cfattach pckbd_ca = {
+ sizeof(struct pckbd_softc), pckbdprobe, pckbdattach,
};
-char *sget __P((void));
-int pccngetc __P((void *));
-void pccnpollc __P((void *, int));
+struct cfdriver pckbd_cd = {
+ NULL, "pckbd", DV_DULL,
+};
+
+int pckbd_cngetc __P((struct device *));
+void pckbd_cnpollc __P((struct device *, int));
+void pckbd_bell __P((struct device *, struct wsconsio_bell_data *));
+int pckbd_ioctl __P((struct device *, u_long, caddr_t, int,
+ struct proc *));
+
+char *pckbd_translate __P((struct device *dev, int c));
+
+#if NWSCONS
+struct wscons_idev_spec pckbd_wscons_idev = {
+ pckbd_cngetc,
+ pckbd_cnpollc,
+ pckbd_bell,
+ pckbd_ioctl,
+ pckbd_translate,
+ 0x7f, /* key data mask */
+ 0x80, /* key-up mask */
+};
+#endif
+
+void pckbd_bell_stop __P((void *));
/*
* DANGER WIL ROBINSON -- the values of SCROLL, NUM, CAPS, and ALT are
@@ -109,10 +141,10 @@ void pccnpollc __P((void *, int));
#define NONE 0x0400 /* no function */
#define KBD_DELAY \
- { u_char x = INB(pckbd_pio_fns, pckbd_pio_arg, 0x84); } \
- { u_char x = INB(pckbd_pio_fns, pckbd_pio_arg, 0x84); } \
- { u_char x = INB(pckbd_pio_fns, pckbd_pio_arg, 0x84); } \
- { u_char x = INB(pckbd_pio_fns, pckbd_pio_arg, 0x84); }
+ { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); } \
+ { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); } \
+ { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); } \
+ { u_char x = bus_io_read_1(pckbd_bc, pckbd_delay_ioh, 0); }
static inline int
kbd_wait_output()
@@ -120,7 +152,7 @@ kbd_wait_output()
u_int i;
for (i = 100000; i; i--)
- if ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_IBF)
+ if ((bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_IBF)
== 0) {
KBD_DELAY;
return 1;
@@ -134,7 +166,7 @@ kbd_wait_input()
u_int i;
for (i = 100000; i; i--)
- if ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB)
+ if ((bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_DIB)
!= 0) {
KBD_DELAY;
return 1;
@@ -148,11 +180,11 @@ kbd_flush_input()
u_int i;
for (i = 10; i; i--) {
- if ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB)
+ if ((bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_DIB)
== 0)
return;
KBD_DELAY;
- (void) INB(pckbd_pio_fns, pckbd_pio_arg, KBDATAP);
+ (void) bus_io_read_1(pckbd_bc, pckbd_data_ioh, 0);
}
}
@@ -166,10 +198,10 @@ kbc_get8042cmd()
if (!kbd_wait_output())
return -1;
- OUTB(pckbd_pio_fns, pckbd_pio_arg, KBCMDP, K_RDCMDBYTE);
+ bus_io_write_1(pckbd_bc, pckbd_cmd_ioh, 0, K_RDCMDBYTE);
if (!kbd_wait_input())
return -1;
- return INB(pckbd_pio_fns, pckbd_pio_arg, KBDATAP);
+ return bus_io_read_1(pckbd_bc, pckbd_data_ioh, 0);
}
#endif
@@ -183,10 +215,10 @@ kbc_put8042cmd(val)
if (!kbd_wait_output())
return 0;
- OUTB(pckbd_pio_fns, pckbd_pio_arg, KBCMDP, K_LDCMDBYTE);
+ bus_io_write_1(pckbd_bc, pckbd_cmd_ioh, 0, K_LDCMDBYTE);
if (!kbd_wait_output())
return 0;
- OUTB(pckbd_pio_fns, pckbd_pio_arg, KBOUTP, val);
+ bus_io_write_1(pckbd_bc, pckbd_out_ioh, 0, val);
return 1;
}
@@ -205,16 +237,16 @@ kbd_cmd(val, polling)
if (!kbd_wait_output())
return 0;
ack = nak = 0;
- OUTB(pckbd_pio_fns, pckbd_pio_arg, KBOUTP, val);
+ bus_io_write_1(pckbd_bc, pckbd_out_ioh, 0, val);
if (polling)
for (i = 100000; i; i--) {
- if (INB(pckbd_pio_fns, pckbd_pio_arg,
- KBSTATP) & KBS_DIB) {
+ if (bus_io_read_1(pckbd_bc,
+ pckbd_status_ioh, 0) & KBS_DIB) {
register u_char c;
KBD_DELAY;
- c = INB(pckbd_pio_fns, pckbd_pio_arg,
- KBDATAP);
+ c = bus_io_read_1(pckbd_bc,
+ pckbd_data_ioh, 0);
if (c == KBR_ACK || c == KBR_ECHO) {
ack = 1;
return 1;
@@ -231,8 +263,8 @@ kbd_cmd(val, polling)
}
else
for (i = 100000; i; i--) {
- (void) INB(pckbd_pio_fns, pckbd_pio_arg,
- KBSTATP);
+ (void) bus_io_read_1(pckbd_bc,
+ pckbd_status_ioh, 0);
if (ack)
return 1;
if (nak)
@@ -252,11 +284,19 @@ pckbdprobe(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct isadev_attach_args *ida = aux;
+ struct isa_attach_args *ia = aux;
u_int i;
- pckbd_pio_fns = ida->ida_piofns; /* XXX */
- pckbd_pio_arg = ida->ida_pioarg; /* XXX */
+ pckbd_bc = ia->ia_bc;
+ pckbd_ic = ia->ia_ic;
+
+ if (bus_io_map(pckbd_bc, KBDATAP, 1, &pckbd_data_ioh) ||
+ bus_io_map(pckbd_bc, KBSTATP, 1, &pckbd_status_ioh) ||
+ bus_io_map(pckbd_bc, IO_TIMER1, 4, &pckbd_timer_ioh) ||
+ bus_io_map(pckbd_bc, PITAUX_PORT, 1, &pckbd_pitaux_ioh))
+ return 0;
+
+ pckbd_delay_ioh = ia->ia_delayioh;
/* Enable interrupts and keyboard, etc. */
if (!kbc_put8042cmd(CMDBYTE)) {
@@ -273,12 +313,12 @@ pckbdprobe(parent, match, aux)
goto lose;
}
for (i = 600000; i; i--)
- if ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB)
+ if ((bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_DIB)
!= 0) {
KBD_DELAY;
break;
}
- if (i == 0 || INB(pckbd_pio_fns, pckbd_pio_arg, KBDATAP)
+ if (i == 0 || bus_io_read_1(pckbd_bc, pckbd_data_ioh, 0)
!= KBR_RSTDONE) {
printf("pcprobe: reset error %d\n", 2);
goto lose;
@@ -329,8 +369,8 @@ lose:
*/
#endif
- ida->ida_nports[0] = 16;
- ida->ida_iosiz[0] = 0;
+ ia->ia_iobase = 16;
+ ia->ia_iosize = 0;
return 1;
}
@@ -340,20 +380,29 @@ pckbdattach(parent, self, aux)
void *aux;
{
struct pckbd_softc *sc = (void *)self;
- struct isadev_attach_args *ida = aux;
-
- pckbd_intr_fns = ida->ida_intrfns; /* XXX */
- pckbd_intr_arg = ida->ida_intrarg; /* XXX */
- pckbd_pio_fns = ida->ida_piofns; /* XXX */
- pckbd_pio_arg = ida->ida_pioarg; /* XXX */
-
- sc->sc_ih = ISA_INTR_ESTABLISH(pckbd_intr_fns, pckbd_intr_arg,
- ida->ida_irq[0], IST_EDGE, IPL_TTY, pckbdintr, sc);
-#if NWSC
+ struct isa_attach_args *ia = aux;
+
+ pckbd_bc = ia->ia_bc;
+ pckbd_ic = ia->ia_ic;
+
+ if (bus_io_map(pckbd_bc, KBDATAP, 1, &pckbd_data_ioh) ||
+ bus_io_map(pckbd_bc, KBSTATP, 1, &pckbd_status_ioh) ||
+ bus_io_map(pckbd_bc, IO_TIMER1, 4, &pckbd_timer_ioh) ||
+ bus_io_map(pckbd_bc, PITAUX_PORT, 1, &pckbd_pitaux_ioh))
+ panic("pckbdattach couldn't map");
+
+ pckbd_delay_ioh = ia->ia_delayioh;
+
+ sc->sc_ih = isa_intr_establish(pckbd_ic, ia->ia_irq, IST_EDGE,
+ IPL_TTY, pckbdintr, sc);
+
+ sc->sc_bellactive = sc->sc_bellpitch = 0;
+
+#if NWSCONS
printf("\n");
- wscattach_input(self, self, pccngetc, pccnpollc);
+ kbdattach(self, &pckbd_wscons_idev);
#else
- printf(": no wsc driver; no input possible\n");
+ printf(": no wscons driver present; no input possible\n");
#endif
}
@@ -367,19 +416,35 @@ pckbdintr(arg)
void *arg;
{
struct pckbd_softc *sc = arg;
- u_char *cp;
+ u_char data;
+ static u_char last;
- if ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB) == 0)
+ if ((bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_DIB) == 0)
return 0;
if (polling)
return 1;
do {
- cp = sget();
-#if NWSC
- if (cp)
- wscons_kbdinput(cp);
+ KBD_DELAY;
+ data = bus_io_read_1(pckbd_bc, pckbd_data_ioh, 0);
+
+ switch (data) {
+ case KBR_ACK:
+ ack = 1;
+ break;
+ case KBR_RESEND:
+ nak = 1;
+ break;
+ default:
+ /* Always ignore typematic keys */
+ if (data == last)
+ break;
+ last = data;
+#if NWSCONS
+ kbd_input(data);
#endif
- } while (INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB);
+ break;
+ }
+ } while (bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_DIB);
return 1;
}
@@ -426,6 +491,23 @@ async_update()
}
}
+int
+pckbd_ioctl(dev, cmd, data, flag, p)
+ struct device *dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+
+ switch (cmd) {
+ case WSCONSIO_KBD_GTYPE:
+ *(int *)data = KBD_TYPE_PC;
+ return 0;
+ }
+ return ENOTTY;
+}
+
#if 0
int
pcioctl(dev, cmd, data, flag, p)
@@ -633,96 +715,18 @@ static Scan_def scan_codes[] = {
* Get characters from the keyboard. If none are present, return NULL.
*/
char *
-sget()
+pckbd_translate(dev, c)
+ struct device *dev;
+ int c;
{
- u_char dt;
+ u_char dt = c;
static u_char extended = 0, shift_state = 0;
static u_char capchar[2];
-top:
- KBD_DELAY;
- dt = INB(pckbd_pio_fns, pckbd_pio_arg, KBDATAP);
-
- switch (dt) {
- case KBR_ACK:
- ack = 1;
- goto loop;
- case KBR_RESEND:
- nak = 1;
- goto loop;
- }
-
-#if 0
- if (pc_xmode > 0) {
-#if defined(DDB) && defined(XSERVER_DDB)
- /* F12 enters the debugger while in X mode */
- if (dt == 88)
- Debugger();
-#endif
- capchar[0] = dt;
- capchar[1] = 0;
- /*
- * Check for locking keys.
- *
- * XXX Setting the LEDs this way is a bit bogus. What if the
- * keyboard has been remapped in X?
- */
- switch (scan_codes[dt & 0x7f].type) {
- case NUM:
- if (dt & 0x80) {
- shift_state &= ~NUM;
- break;
- }
- if (shift_state & NUM)
- break;
- shift_state |= NUM;
- lock_state ^= NUM;
- async_update();
- break;
- case CAPS:
- if (dt & 0x80) {
- shift_state &= ~CAPS;
- break;
- }
- if (shift_state & CAPS)
- break;
- shift_state |= CAPS;
- lock_state ^= CAPS;
- async_update();
- break;
- case SCROLL:
- if (dt & 0x80) {
- shift_state &= ~SCROLL;
- break;
- }
- if (shift_state & SCROLL)
- break;
- shift_state |= SCROLL;
- lock_state ^= SCROLL;
- if ((lock_state & SCROLL) == 0)
- wakeup((caddr_t)&lock_state);
- async_update();
- break;
- }
- return capchar;
- }
-#endif /* 0 */
-
- switch (dt) {
- case KBR_EXTENDED:
+ if (dt == KBR_EXTENDED) {
extended = 1;
- goto loop;
- }
-
-#ifdef DDB
- /*
- * Check for cntl-alt-esc.
- */
- if ((dt == 1) && (shift_state & (CTL | ALT)) == (CTL | ALT)) {
- Debugger();
- dt |= 0x80; /* discard esc (ddb discarded ctl-alt) */
+ return NULL;
}
-#endif
/*
* Check for make/break.
@@ -837,31 +841,43 @@ top:
}
extended = 0;
-loop:
- if ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB) == 0)
- return 0;
- goto top;
+ return (NULL);
}
/* ARGSUSED */
int
-pccngetc(cookie)
- void *cookie;
+pckbd_cngetc(dev)
+ struct device *dev;
{
register char *cp;
-
-#if 0
- if (pc_xmode > 0)
- return 0;
-#endif
+ u_char data;
+ static u_char last;
do {
- /* wait for byte */
- while ((INB(pckbd_pio_fns, pckbd_pio_arg, KBSTATP) & KBS_DIB)
- == 0);
- /* see if it's worthwhile */
- cp = sget();
+ /* wait for byte */
+ while ((bus_io_read_1(pckbd_bc, pckbd_status_ioh, 0) & KBS_DIB)
+ == 0)
+ KBD_DELAY;
+ KBD_DELAY;
+
+ data = bus_io_read_1(pckbd_bc, pckbd_data_ioh, 0);
+
+ if (data == KBR_ACK) {
+ ack = 1;
+ continue;
+ }
+ if (data == KBR_RESEND) {
+ nak = 1;
+ continue;
+ }
+
+ /* Ignore typematic keys */
+ if (data == last)
+ continue;
+ last = data;
+
+ cp = pckbd_translate(NULL, data);
} while (!cp);
if (*cp == '\r')
return '\n';
@@ -869,11 +885,11 @@ pccngetc(cookie)
}
void
-pccnpollc(cookie, on)
- void *cookie;
+pckbd_cnpollc(dev, on)
+ struct device *dev;
int on;
{
- struct pckbd_softc *sc = cookie;
+ struct pckbd_softc *sc = (struct pckbd_softc *)dev;
polling = on;
if (!on) {
@@ -892,3 +908,59 @@ pccnpollc(cookie, on)
}
}
}
+
+void
+pckbd_bell(dev, wbd)
+ struct device *dev;
+ struct wsconsio_bell_data *wbd;
+{
+ struct pckbd_softc *sc = (struct pckbd_softc *)dev;
+ int pitch, period;
+ int s;
+
+ pitch = wbd->wbd_pitch;
+ period = (wbd->wbd_period * hz) / 1000;
+ /* XXX volume ignored */
+
+ s = splhigh();
+ if (sc->sc_bellactive)
+ untimeout(pckbd_bell_stop, sc);
+ splx(s);
+ if (pitch == 0 || period == 0) {
+ pckbd_bell_stop(sc);
+ sc->sc_bellpitch = 0;
+ return;
+ }
+ if (!sc->sc_bellactive || sc->sc_bellpitch != pitch) {
+ s = splhigh();
+ bus_io_write_1(pckbd_bc, pckbd_timer_ioh, TIMER_MODE,
+ TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
+ bus_io_write_1(pckbd_bc, pckbd_timer_ioh, TIMER_CNTR2,
+ TIMER_DIV(pitch) % 256);
+ bus_io_write_1(pckbd_bc, pckbd_timer_ioh, TIMER_CNTR2,
+ TIMER_DIV(pitch) / 256);
+ /* enable speaker */
+ bus_io_write_1(pckbd_bc, pckbd_pitaux_ioh, 0,
+ bus_io_read_1(pckbd_bc, pckbd_pitaux_ioh, 0) |
+ PIT_SPKR);
+ splx(s);
+ }
+ sc->sc_bellpitch = pitch;
+ sc->sc_bellactive = 1;
+ timeout(pckbd_bell_stop, sc, period);
+}
+
+void
+pckbd_bell_stop(arg)
+ void *arg;
+{
+ struct pckbd_softc *sc = arg;
+ int s;
+
+ /* disable bell */
+ s = splhigh();
+ bus_io_write_1(pckbd_bc, pckbd_pitaux_ioh, 0,
+ bus_io_read_1(pckbd_bc, pckbd_pitaux_ioh, 0) & ~PIT_SPKR);
+ sc->sc_bellactive = 0;
+ splx(s);
+}