Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/luna68k/dev Implement transmitting keyboard LED and...
details: https://anonhg.NetBSD.org/src/rev/7fff23001a2f
branches: trunk
changeset: 1023614:7fff23001a2f
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Sat Sep 18 13:44:02 2021 +0000
description:
Implement transmitting keyboard LED and buzzer control commands.
- enable TX on uPD7201 for keyboard port
- prepare TX queue and handle it in hardware interrupt and softint(9)
- send proper LED commands on WSKBDIO_SETLEDS
(XXX: KANA LED is not handled in wscons)
- return current LED settings on WSKBDIO_GETLEDS
- implement WSKBDIO_COMPLEXBELL by parsing struct wskbd_bell_data and
send proper buzzer commands
- handle pitch, period, and volume in cnbell(9)
(XXX: no description in cnbell(9) man pages)
- use proper queued TX function for omms_enable() and omms_disable()
- add DPRINTF()s for debug
- use C99 designated initializer and misc cosmetics
Tested on LUNA and its keyboard (3W4SD-098NDT).
diffstat:
sys/arch/luna68k/dev/lunaws.c | 321 ++++++++++++++++++++++++++++++++++++-----
1 files changed, 278 insertions(+), 43 deletions(-)
diffs (truncated from 507 to 300 lines):
diff -r a65859905f88 -r 7fff23001a2f sys/arch/luna68k/dev/lunaws.c
--- a/sys/arch/luna68k/dev/lunaws.c Sat Sep 18 12:25:06 2021 +0000
+++ b/sys/arch/luna68k/dev/lunaws.c Sat Sep 18 13:44:02 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lunaws.c,v 1.34 2021/09/04 18:38:03 tsutsui Exp $ */
+/* $NetBSD: lunaws.c,v 1.35 2021/09/18 13:44:02 tsutsui Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.34 2021/09/04 18:38:03 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.35 2021/09/18 13:44:02 tsutsui Exp $");
#include "opt_wsdisplay_compat.h"
#include "wsmouse.h"
@@ -57,10 +57,43 @@
#define OMKBD_RXQ_LEN 64
#define OMKBD_RXQ_LEN_MASK (OMKBD_RXQ_LEN - 1)
#define OMKBD_NEXTRXQ(x) (((x) + 1) & OMKBD_RXQ_LEN_MASK)
+#define OMKBD_TXQ_LEN 16
+#define OMKBD_TXQ_LEN_MASK (OMKBD_TXQ_LEN - 1)
+#define OMKBD_NEXTTXQ(x) (((x) + 1) & OMKBD_TXQ_LEN_MASK)
+
+/* Keyboard commands */
+/* 000XXXXXb : LED commands */
+#define OMKBD_LED_ON_KANA 0x10 /* kana LED on */
+#define OMKBD_LED_OFF_KANA 0x00 /* kana LED off */
+#define OMKBD_LED_ON_CAPS 0x11 /* caps LED on */
+#define OMKBD_LED_OFF_CAPS 0x01 /* caps LED off */
+/* 010XXXXXb : buzzer commands */
+#define OMKBD_BUZZER 0x40
+#define OMKBD_BUZZER_PERIOD 0x18
+#define OMKBD_BUZZER_40MS 0x00
+#define OMKBD_BUZZER_150MS 0x08
+#define OMKBD_BUZZER_400MS 0x10
+#define OMKBD_BUZZER_700MS 0x18
+#define OMKBD_BUZZER_PITCH 0x07
+#define OMKBD_BUZZER_6000HZ 0x00
+#define OMKBD_BUZZER_3000HZ 0x01
+#define OMKBD_BUZZER_1500HZ 0x02
+#define OMKBD_BUZZER_1000HZ 0x03
+#define OMKBD_BUZZER_600HZ 0x04
+#define OMKBD_BUZZER_300HZ 0x05
+#define OMKBD_BUZZER_150HZ 0x06
+#define OMKBD_BUZZER_100HZ 0x07
+/* 011XXXXXb : mouse on command */
+#define OMKBD_MOUSE_ON 0x60
+/* 001XXXXXb : mouse off command */
+#define OMKBD_MOUSE_OFF 0x20
+
+#define OMKBD_BUZZER_DEFAULT \
+ (OMKBD_BUZZER | OMKBD_BUZZER_40MS | OMKBD_BUZZER_1500HZ)
static const uint8_t ch1_regs[6] = {
WR0_RSTINT, /* Reset E/S Interrupt */
- WR1_RXALLS, /* Rx per char, No Tx */
+ WR1_RXALLS | WR1_TXENBL, /* Rx per char, Tx */
0, /* */
WR3_RX8BIT | WR3_RXENBL, /* Rx */
WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY, /* Tx/Rx */
@@ -75,6 +108,12 @@
uint8_t sc_rxq[OMKBD_RXQ_LEN];
u_int sc_rxqhead;
u_int sc_rxqtail;
+ uint8_t sc_txq[OMKBD_TXQ_LEN];
+ u_int sc_txqhead;
+ u_int sc_txqtail;
+ bool sc_tx_busy;
+ bool sc_tx_done;
+ int sc_leds;
#if NWSMOUSE > 0
device_t sc_wsmousedev;
int sc_msbuttons, sc_msdx, sc_msdy;
@@ -84,28 +123,36 @@
int sc_rawkbd;
};
-static void omkbd_input(void *, int);
-static void omkbd_decode(void *, int, u_int *, int *);
+static void omkbd_input(struct ws_softc *, int);
+static void omkbd_send(struct ws_softc *, uint8_t);
+static void omkbd_decode(struct ws_softc *, int, u_int *, int *);
+
static int omkbd_enable(void *, int);
static void omkbd_set_leds(void *, int);
static int omkbd_ioctl(void *, u_long, void *, int, struct lwp *);
+static void omkbd_complex_buzzer(struct ws_softc *, struct wskbd_bell_data *);
+static uint8_t omkbd_get_buzcmd(struct ws_softc *, struct wskbd_bell_data *,
+ uint8_t);
+
static const struct wskbd_mapdata omkbd_keymapdata = {
- omkbd_keydesctab,
- KB_JP,
+ .keydesc = omkbd_keydesctab,
+ .layout = KB_JP,
};
static const struct wskbd_accessops omkbd_accessops = {
- omkbd_enable,
- omkbd_set_leds,
- omkbd_ioctl,
+ .enable = omkbd_enable,
+ .set_leds = omkbd_set_leds,
+ .ioctl = omkbd_ioctl,
};
void ws_cnattach(void);
static void ws_cngetc(void *, u_int *, int *);
static void ws_cnpollc(void *, int);
+static void ws_cnbell(void *, u_int, u_int, u_int);
static const struct wskbd_consops ws_consops = {
- ws_cngetc,
- ws_cnpollc,
+ .getc = ws_cngetc,
+ .pollc = ws_cnpollc,
+ .bell = ws_cnbell,
};
#if NWSMOUSE > 0
@@ -129,6 +176,18 @@
CFATTACH_DECL_NEW(ws, sizeof(struct ws_softc),
wsmatch, wsattach, NULL, NULL);
+/* #define LUNAWS_DEBUG */
+
+#ifdef LUNAWS_DEBUG
+#define DEBUG_KBDTX 0x01
+#define DEBUG_RXSOFT 0x02
+#define DEBUG_BUZZER 0x04
+uint32_t lunaws_debug = 0x00 /* | DEBUG_BUZZER | DEBUG_KBDTX | DEBUG_RXSOFT */;
+#define DPRINTF(x, y) if (lunaws_debug & (x)) printf y
+#else
+#define DPRINTF(x, y) __nothing
+#endif
+
static int
wsmatch(device_t parent, cfdata_t cf, void *aux)
{
@@ -159,17 +218,24 @@
setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
- setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]);
-
- syscnputc((dev_t)1, 0x20); /* keep quiet mouse */
sc->sc_rxqhead = 0;
sc->sc_rxqtail = 0;
+ sc->sc_txqhead = 0;
+ sc->sc_txqtail = 0;
+ sc->sc_tx_busy = false;
+ sc->sc_tx_done = false;
sc->sc_si = softint_establish(SOFTINT_SERIAL, wssoftintr, sc);
+ /* enable interrupt */
+ setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]);
+
aprint_normal("\n");
+ /* keep mouse quiet */
+ omkbd_send(sc, OMKBD_MOUSE_OFF);
+
a.console = (args->hwflags == 1);
a.keymap = &omkbd_keymapdata;
a.accessops = &omkbd_accessops;
@@ -189,7 +255,6 @@
sc->sc_msreport = 0;
}
-/*ARGSUSED*/
static void
wsintr(void *arg)
{
@@ -197,6 +262,7 @@
struct sioreg *sio = sc->sc_ctl;
uint8_t code;
int rr;
+ bool handled = false;
rr = getsiocsr(sio);
if ((rr & RR_RXRDY) != 0) {
@@ -209,11 +275,18 @@
sc->sc_rxq[sc->sc_rxqtail] = code;
sc->sc_rxqtail = OMKBD_NEXTRXQ(sc->sc_rxqtail);
} while (((rr = getsiocsr(sio)) & RR_RXRDY) != 0);
- softint_schedule(sc->sc_si);
+ handled = true;
}
- if ((rr & RR_TXRDY) != 0)
+ if ((rr & RR_TXRDY) != 0) {
sio->sio_cmd = WR0_RSTPEND;
- /* not capable of transmit, yet */
+ if (sc->sc_tx_busy) {
+ sc->sc_tx_busy = false;
+ sc->sc_tx_done = true;
+ handled = true;
+ }
+ }
+ if (handled)
+ softint_schedule(sc->sc_si);
}
static void
@@ -222,8 +295,32 @@
struct ws_softc *sc = arg;
uint8_t code;
+ /* handle pending keyboard commands */
+ if (sc->sc_tx_done) {
+ int s;
+
+ s = splserial();
+ sc->sc_tx_done = false;
+ DPRINTF(DEBUG_KBDTX, ("%s: tx complete\n", __func__));
+ if (sc->sc_txqhead != sc->sc_txqtail) {
+ struct sioreg *sio = sc->sc_ctl;
+
+ sc->sc_tx_busy = true;
+ sio->sio_data = sc->sc_txq[sc->sc_txqhead];
+ DPRINTF(DEBUG_KBDTX,
+ ("%s: sio_data <- txq[%2d] (%02x)\n", __func__,
+ sc->sc_txqhead, sc->sc_txq[sc->sc_txqhead]));
+
+ sc->sc_txqhead = OMKBD_NEXTTXQ(sc->sc_txqhead);
+ }
+ splx(s);
+ }
+
+ /* handle received keyboard and mouse data */
while (sc->sc_rxqhead != sc->sc_rxqtail) {
code = sc->sc_rxq[sc->sc_rxqhead];
+ DPRINTF(DEBUG_RXSOFT, ("%s: %02x <- rxq[%2d]\n", __func__,
+ code, sc->sc_rxqhead));
sc->sc_rxqhead = OMKBD_NEXTRXQ(sc->sc_rxqhead);
/*
* if (code >= 0x80 && code <= 0x87), i.e.
@@ -265,13 +362,38 @@
}
static void
-omkbd_input(void *v, int data)
+omkbd_send(struct ws_softc *sc, uint8_t txdata)
{
- struct ws_softc *sc = v;
+ int s;
+
+ if (!sc->sc_tx_busy) {
+ struct sioreg *sio = sc->sc_ctl;
+
+ DPRINTF(DEBUG_KBDTX,
+ ("%s: sio_data <- %02x\n", __func__, txdata));
+ s = splserial();
+ sc->sc_tx_busy = true;
+ sio->sio_data = txdata;
+ splx(s);
+ } else {
+ s = splsoftserial();
+ sc->sc_txq[sc->sc_txqtail] = txdata;
+ DPRINTF(DEBUG_KBDTX,
+ ("%s: txq[%2d] <- %02x\n", __func__,
+ sc->sc_txqtail, sc->sc_txq[sc->sc_txqtail]));
+ sc->sc_txqtail = OMKBD_NEXTTXQ(sc->sc_txqtail);
+ splx(s);
+ softint_schedule(sc->sc_si);
+ }
+}
+
+static void
+omkbd_input(struct ws_softc *sc, int data)
+{
u_int type;
int key;
- omkbd_decode(v, data, &type, &key);
+ omkbd_decode(sc, data, &type, &key);
#ifdef WSDISPLAY_COMPAT_RAWKBD
if (sc->sc_rawkbd) {
@@ -299,7 +421,7 @@
}
static void
-omkbd_decode(void *v, int datain, u_int *type, int *dataout)
+omkbd_decode(struct ws_softc *sc, int datain, u_int *type, int *dataout)
{
*type = (datain & 0x80) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
@@ -307,17 +429,96 @@
}
static void
-ws_cngetc(void *v, u_int *type, int *data)
+omkbd_complex_buzzer(struct ws_softc *sc, struct wskbd_bell_data *wbd)
+{
+ uint8_t buzcmd;
+
Home |
Main Index |
Thread Index |
Old Index