- In sunkbd_probe_keyboard() don't bother to determine the keyboard layout
as we have no use for that info. Instead let this function return the keyboard ID and verify at its invocation in sunkbd_configure() that we're talking to a Sun type 4/5/6 keyboard, i.e. a keyboard supported by this driver. - Add an option SUNKBD_EMULATE_ATKBD whose code is based on the respective code in ukbd(4) and like UKBD_EMULATE_ATSCANCODE causes this driver to emit AT keyboard/KB_101 compatible scan codes in K_RAW mode as assumed by kbdmux(4). Unlike UKBD_EMULATE_ATSCANCODE, SUNKBD_EMULATE_ATKBD also triggers the use of AT keyboard maps and thus allows to use the map files in share/syscons/keymaps with this driver at the cost of an additional translation (in ukbd(4) this just is the way of operation). - Implement an option SUNKBD_DFLT_KEYMAP, which like the equivalent options of the other keyboard drivers allows to specify the default in-kernel keyboard map. For obvious reasons this made to only work when also using SUNKBD_EMULATE_ATKBD. - Implement sunkbd_check(), sunkbd_check_char() and sunkbd_clear_state(), which are also required for interoperability with kbdmux(4). - Implement K_CODE mode and FreeBSD keypad compose. - As a minor hack define KBD_DFLT_KEYMAP also in the !SUNKBD_EMULATE_ATKBD case so we can obtain fkey_tab from <dev/kbd/kbdtables.h> rather than having to duplicate it and #ifdef some more code. - Don't use the TX-buffer for writing the two command bytes for setting the keyboard LEDs as this consequently requires a hardware FIFO that is at least two bytes in depth, which the NMOS-variant of the Zilog SCCs doesn't have. Thus use an inlined version of uart_putc() to consecutively write the command bytes (a cleaner approach would be to do this via the soft interrupt handler but that variant wouldn't work while in ddb(4)). [1] - Fix some minor style(9) bugs. PR: 90316 [1] Reviewed by: marcel [1]
This commit is contained in:
parent
1f52d4e246
commit
abfeec800f
@ -12,6 +12,11 @@ atkbdmap.h optional atkbd_dflt_keymap \
|
||||
no-obj no-implicit-rule before-depend \
|
||||
clean "atkbdmap.h"
|
||||
#
|
||||
sunkbdmap.h optional sunkbd_dflt_keymap \
|
||||
compile-with "/usr/sbin/kbdcontrol -L ${SUNKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > sunkbdmap.h" \
|
||||
no-obj no-implicit-rule before-depend \
|
||||
clean "sunkbdmap.h"
|
||||
#
|
||||
ukbdmap.h optional ukbd_dflt_keymap \
|
||||
compile-with "/usr/sbin/kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \
|
||||
no-obj no-implicit-rule before-depend \
|
||||
|
@ -18,3 +18,5 @@ ATKBD_DFLT_KEYMAP opt_atkbd.h
|
||||
PSM_DEBUG opt_psm.h
|
||||
PSM_HOOKRESUME opt_psm.h
|
||||
PSM_RESETAFTERSUSPEND opt_psm.h
|
||||
SUNKBD_DFLT_KEYMAP opt_sunkbd.h
|
||||
SUNKBD_EMULATE_ATKBD opt_sunkbd.h
|
||||
|
@ -29,6 +29,12 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_kbd.h"
|
||||
#include "opt_sunkbd.h"
|
||||
|
||||
#if (defined(SUNKBD_EMULATE_ATKBD) && defined(SUNKBD_DFLT_KEYMAP)) || \
|
||||
!defined(SUNKBD_EMULATE_ATKBD)
|
||||
#define KBD_DFLT_KEYMAP
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -36,26 +42,28 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/interrupt.h>
|
||||
#include <sys/kbio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/limits.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/kbd/kbdreg.h>
|
||||
#include <dev/kbd/kbdtables.h>
|
||||
|
||||
#include <dev/uart/uart.h>
|
||||
#include <dev/uart/uart_bus.h>
|
||||
#include <dev/uart/uart_cpu.h>
|
||||
|
||||
#include <dev/uart/uart_kbd_sun.h>
|
||||
#if !defined(SUNKBD_EMULATE_ATKBD)
|
||||
#include <dev/uart/uart_kbd_sun_tables.h>
|
||||
#endif
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD) && defined(SUNKBD_DFLT_KEYMAP)
|
||||
#include "sunkbdmap.h"
|
||||
#endif
|
||||
#include "uart_if.h"
|
||||
|
||||
#define SUNKBD_BUF_SIZE 128
|
||||
#define SUNKBD_DRIVER_NAME "sunkbd"
|
||||
|
||||
#define TODO printf("%s: unimplemented", __func__)
|
||||
|
||||
@ -64,14 +72,23 @@ struct sunkbd_softc {
|
||||
struct uart_softc *sc_uart;
|
||||
struct uart_devinfo *sc_sysdev;
|
||||
|
||||
int sc_checked_key;
|
||||
|
||||
struct callout sc_repeat_callout;
|
||||
int sc_repeat_key;
|
||||
|
||||
int sc_accents;
|
||||
int sc_composed_char;
|
||||
int sc_flags;
|
||||
#define KPCOMPOSE (1 << 0)
|
||||
int sc_mode;
|
||||
int sc_polling;
|
||||
int sc_repeating;
|
||||
int sc_state;
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
int sc_buffered_char[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
static int sunkbd_configure(int flags);
|
||||
@ -97,6 +114,9 @@ static int sunkbd_poll_mode(keyboard_t *kbd, int on);
|
||||
static void sunkbd_diag(keyboard_t *kbd, int level);
|
||||
|
||||
static void sunkbd_repeat(void *v);
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
static int keycode2scancode(int keycode, int shift, int up);
|
||||
#endif
|
||||
|
||||
static keyboard_switch_t sunkbdsw = {
|
||||
sunkbd_probe,
|
||||
@ -125,41 +145,46 @@ KEYBOARD_DRIVER(sunkbd, sunkbdsw, sunkbd_configure);
|
||||
static struct sunkbd_softc sunkbd_softc;
|
||||
static struct uart_devinfo uart_keyboard;
|
||||
|
||||
static fkeytab_t fkey_tab[96] = {
|
||||
/* 01-04 */ {"\033[M", 3}, {"\033[N", 3}, {"\033[O", 3}, {"\033[P", 3},
|
||||
/* 05-08 */ {"\033[Q", 3}, {"\033[R", 3}, {"\033[S", 3}, {"\033[T", 3},
|
||||
/* 09-12 */ {"\033[U", 3}, {"\033[V", 3}, {"\033[W", 3}, {"\033[X", 3},
|
||||
/* 13-16 */ {"\033[Y", 3}, {"\033[Z", 3}, {"\033[a", 3}, {"\033[b", 3},
|
||||
/* 17-20 */ {"\033[c", 3}, {"\033[d", 3}, {"\033[e", 3}, {"\033[f", 3},
|
||||
/* 21-24 */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3},
|
||||
/* 25-28 */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3},
|
||||
/* 29-32 */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3},
|
||||
/* 33-36 */ {"\033[s", 3}, {"\033[t", 3}, {"\033[u", 3}, {"\033[v", 3},
|
||||
/* 37-40 */ {"\033[w", 3}, {"\033[x", 3}, {"\033[y", 3}, {"\033[z", 3},
|
||||
/* 41-44 */ {"\033[@", 3}, {"\033[[", 3}, {"\033[\\",3}, {"\033[]", 3},
|
||||
/* 45-48 */ {"\033[^", 3}, {"\033[_", 3}, {"\033[`", 3}, {"\033[{", 3},
|
||||
/* 49-52 */ {"\033[H", 3}, {"\033[A", 3}, {"\033[I", 3}, {"-" , 1},
|
||||
/* 53-56 */ {"\033[D", 3}, {"\033[E", 3}, {"\033[C", 3}, {"+" , 1},
|
||||
/* 57-60 */ {"\033[F", 3}, {"\033[B", 3}, {"\033[G", 3}, {"\033[L", 3},
|
||||
/* 61-64 */ {"\177", 1}, {"\033[J", 3}, {"\033[~", 3}, {"\033[}", 3},
|
||||
/* 65-68 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 69-72 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 73-76 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 77-80 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 81-84 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 85-88 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 89-92 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
|
||||
/* 93-96 */ {"", 0} , {"", 0} , {"", 0} , {"", 0}
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
|
||||
#define SCAN_PRESS 0x000
|
||||
#define SCAN_RELEASE 0x080
|
||||
#define SCAN_PREFIX_E0 0x100
|
||||
#define SCAN_PREFIX_E1 0x200
|
||||
#define SCAN_PREFIX_CTL 0x400
|
||||
#define SCAN_PREFIX_SHIFT 0x800
|
||||
#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
|
||||
SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
|
||||
|
||||
#define NOTR 0x0 /* no translation */
|
||||
|
||||
static const uint8_t sunkbd_trtab[] = {
|
||||
NOTR, 0x6d, 0x78, 0x6e, 0x79, 0x3b, 0x3c, 0x44, /* 0x00 - 0x07 */
|
||||
0x3d, 0x57, 0x3e, 0x58, 0x3f, 0x5d, 0x40, NOTR, /* 0x08 - 0x0f */
|
||||
0x41, 0x42, 0x43, 0x38, 0x5f, 0x68, 0x5c, 0x46, /* 0x10 - 0x17 */
|
||||
0x61, 0x6e, 0x70, 0x64, 0x62, 0x01, 0x02, 0x03, /* 0x18 - 0x1f */
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, /* 0x20 - 0x27 */
|
||||
0x0c, 0x0d, 0x29, 0x0e, 0x66, 0x77, 0x5b, 0x37, /* 0x28 - 0x2f */
|
||||
0x7a, 0x71, 0x53, 0x72, 0x5e, 0x0f, 0x10, 0x11, /* 0x30 - 0x37 */
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, /* 0x38 - 0x3f */
|
||||
0x1a, 0x1b, 0x67, 0x6b, 0x47, 0x48, 0x49, 0x4a, /* 0x40 - 0x47 */
|
||||
0x73, 0x74, 0x63, NOTR, 0x1d, 0x1e, 0x1f, 0x20, /* 0x48 - 0x4f */
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* 0x50 - 0x57 */
|
||||
0x2b, 0x1c, 0x59, 0x4b, 0x4c, 0x4d, 0x52, 0x75, /* 0x58 - 0x5f */
|
||||
0x60, 0x76, 0x45, 0x2a, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x60 - 0x67 */
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, NOTR, /* 0x68 - 0x6f */
|
||||
0x4f, 0x50, 0x51, NOTR, NOTR, NOTR, 0x6c, 0x3a, /* 0x70 - 0x77 */
|
||||
0x69, 0x39, 0x6a, 0x65, 0x56, 0x4e, NOTR, NOTR /* 0x78 - 0x7f */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
sunkbd_probe_keyboard(struct uart_devinfo *di)
|
||||
{
|
||||
int tries;
|
||||
int c, id, ltries, tries;
|
||||
|
||||
for (tries = 5; tries != 0; tries--) {
|
||||
int ltries;
|
||||
|
||||
uart_putc(di, SKBD_CMD_RESET);
|
||||
for (ltries = 1000; ltries != 0; ltries--) {
|
||||
if (uart_poll(di) == SKBD_RSP_RESET)
|
||||
@ -168,17 +193,18 @@ sunkbd_probe_keyboard(struct uart_devinfo *di)
|
||||
}
|
||||
if (ltries == 0)
|
||||
continue;
|
||||
id = -1;
|
||||
for (ltries = 1000; ltries != 0; ltries--) {
|
||||
if (uart_poll(di) == SKBD_RSP_IDLE)
|
||||
switch (c = uart_poll(di)) {
|
||||
case -1:
|
||||
break;
|
||||
case SKBD_RSP_IDLE:
|
||||
return (id);
|
||||
default:
|
||||
id = c;
|
||||
}
|
||||
DELAY(1000);
|
||||
}
|
||||
if (ltries == 0)
|
||||
continue;
|
||||
uart_putc(di, SKBD_CMD_LAYOUT);
|
||||
if (uart_getc(di) != SKBD_RSP_LAYOUT)
|
||||
break;
|
||||
return (uart_getc(di));
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -212,18 +238,23 @@ sunkbd_configure(int flags)
|
||||
uart_keyboard.attach = sunkbd_attach;
|
||||
uart_add_sysdev(&uart_keyboard);
|
||||
|
||||
if (sunkbd_probe_keyboard(&uart_keyboard) == -1)
|
||||
if (sunkbd_probe_keyboard(&uart_keyboard) != KB_SUN4)
|
||||
return (0);
|
||||
|
||||
sc = &sunkbd_softc;
|
||||
callout_init(&sc->sc_repeat_callout, 0);
|
||||
sc->sc_repeat_key = -1;
|
||||
sc->sc_repeating = 0;
|
||||
sunkbd_clear_state(&sc->sc_kbd);
|
||||
|
||||
kbd_init_struct(&sc->sc_kbd, "sunkbd", KB_OTHER, 0, 0, 0, 0);
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
|
||||
kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
|
||||
sizeof(fkey_tab) / sizeof(fkey_tab[0]));
|
||||
#else
|
||||
kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_OTHER, 0, 0, 0, 0);
|
||||
kbd_set_maps(&sc->sc_kbd, &keymap_sun_us_unix_kbd,
|
||||
&accentmap_sun_us_unix_kbd, fkey_tab,
|
||||
sizeof(fkey_tab) / sizeof(fkey_tab[0]));
|
||||
#endif
|
||||
sc->sc_mode = K_XLATE;
|
||||
kbd_register(&sc->sc_kbd);
|
||||
|
||||
@ -284,12 +315,12 @@ sunkbd_uart_intr(void *arg)
|
||||
KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
sunkbd_probe(int unit, void *arg, int flags)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -297,6 +328,7 @@ sunkbd_probe(int unit, void *arg, int flags)
|
||||
static int
|
||||
sunkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -304,6 +336,7 @@ sunkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
|
||||
static int
|
||||
sunkbd_term(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -311,6 +344,7 @@ sunkbd_term(keyboard_t *kbd)
|
||||
static int
|
||||
sunkbd_intr(keyboard_t *kbd, void *arg)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -318,6 +352,7 @@ sunkbd_intr(keyboard_t *kbd, void *arg)
|
||||
static int
|
||||
sunkbd_test_if(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -325,6 +360,7 @@ sunkbd_test_if(keyboard_t *kbd)
|
||||
static int
|
||||
sunkbd_enable(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
KBD_ACTIVATE(kbd);
|
||||
return (0);
|
||||
}
|
||||
@ -332,6 +368,7 @@ sunkbd_enable(keyboard_t *kbd)
|
||||
static int
|
||||
sunkbd_disable(keyboard_t *kbd)
|
||||
{
|
||||
|
||||
KBD_DEACTIVATE(kbd);
|
||||
return (0);
|
||||
}
|
||||
@ -339,6 +376,7 @@ sunkbd_disable(keyboard_t *kbd)
|
||||
static int
|
||||
sunkbd_read(keyboard_t *kbd, int wait)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -346,69 +384,255 @@ sunkbd_read(keyboard_t *kbd, int wait)
|
||||
static int
|
||||
sunkbd_check(keyboard_t *kbd)
|
||||
{
|
||||
TODO;
|
||||
return (0);
|
||||
struct sunkbd_softc *sc;
|
||||
|
||||
if (!KBD_IS_ACTIVE(kbd))
|
||||
return (FALSE);
|
||||
|
||||
sc = (struct sunkbd_softc *)kbd;
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
if (sc->sc_buffered_char[0])
|
||||
return (TRUE);
|
||||
#endif
|
||||
|
||||
if (sc->sc_repeating)
|
||||
return (TRUE);
|
||||
|
||||
if (sc->sc_uart != NULL && !uart_rx_empty(sc->sc_uart))
|
||||
return (TRUE);
|
||||
|
||||
if (sc->sc_polling != 0 && sc->sc_sysdev != NULL &&
|
||||
(sc->sc_checked_key = uart_poll(sc->sc_sysdev)) != -1)
|
||||
return (TRUE);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
static u_int
|
||||
sunkbd_read_char(keyboard_t *kbd, int wait)
|
||||
{
|
||||
struct sunkbd_softc *sc;
|
||||
int action;
|
||||
int key;
|
||||
int key, release, repeated, suncode;
|
||||
|
||||
sc = (struct sunkbd_softc *)kbd;
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
if (sc->sc_mode == K_RAW && sc->sc_buffered_char[0]) {
|
||||
key = sc->sc_buffered_char[0];
|
||||
if (key & SCAN_PREFIX) {
|
||||
sc->sc_buffered_char[0] = key & ~SCAN_PREFIX;
|
||||
return ((key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
|
||||
} else {
|
||||
sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
|
||||
sc->sc_buffered_char[1] = 0;
|
||||
return (key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
repeated = 0;
|
||||
if (sc->sc_repeating) {
|
||||
repeated = 1;
|
||||
sc->sc_repeating = 0;
|
||||
callout_reset(&sc->sc_repeat_callout, hz / 10,
|
||||
sunkbd_repeat, sc);
|
||||
key = sc->sc_repeat_key;
|
||||
if (sc->sc_mode == K_RAW)
|
||||
return (key);
|
||||
else
|
||||
return genkbd_keyaction(kbd, key & 0x7f, key & 0x80,
|
||||
&sc->sc_state, &sc->sc_accents);
|
||||
suncode = sc->sc_repeat_key;
|
||||
goto process_code;
|
||||
}
|
||||
|
||||
if (sc->sc_checked_key != -1) {
|
||||
suncode = sc->sc_checked_key;
|
||||
sc->sc_checked_key = -1;
|
||||
goto process_code;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* XXX compose */
|
||||
next_code:
|
||||
if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) {
|
||||
key = sc->sc_composed_char;
|
||||
sc->sc_composed_char = 0;
|
||||
if (key > UCHAR_MAX)
|
||||
return (ERRKEY);
|
||||
return (key);
|
||||
}
|
||||
|
||||
if (sc->sc_uart != NULL && !uart_rx_empty(sc->sc_uart)) {
|
||||
key = uart_rx_get(sc->sc_uart);
|
||||
suncode = uart_rx_get(sc->sc_uart);
|
||||
} else if (sc->sc_polling != 0 && sc->sc_sysdev != NULL) {
|
||||
if (wait)
|
||||
key = uart_getc(sc->sc_sysdev);
|
||||
else if ((key = uart_poll(sc->sc_sysdev)) == -1)
|
||||
suncode = uart_getc(sc->sc_sysdev);
|
||||
else if ((suncode = uart_poll(sc->sc_sysdev)) == -1)
|
||||
return (NOKEY);
|
||||
} else {
|
||||
return (NOKEY);
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
switch (suncode) {
|
||||
case SKBD_RSP_IDLE:
|
||||
break;
|
||||
default:
|
||||
++kbd->kb_count;
|
||||
|
||||
if ((key & 0x80) == 0) {
|
||||
callout_reset(&sc->sc_repeat_callout, hz / 2,
|
||||
sunkbd_repeat, sc);
|
||||
sc->sc_repeat_key = key;
|
||||
} else {
|
||||
if (sc->sc_repeat_key == (key & 0x7f)) {
|
||||
process_code:
|
||||
++kbd->kb_count;
|
||||
key = SKBD_KEY_CHAR(suncode);
|
||||
release = suncode & SKBD_KEY_RELEASE;
|
||||
if (!repeated) {
|
||||
if (release == 0) {
|
||||
callout_reset(&sc->sc_repeat_callout,
|
||||
hz / 2, sunkbd_repeat, sc);
|
||||
sc->sc_repeat_key = suncode;
|
||||
} else if (sc->sc_repeat_key == key) {
|
||||
callout_stop(&sc->sc_repeat_callout);
|
||||
sc->sc_repeat_key = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->sc_mode == K_RAW)
|
||||
return (key);
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
key = sunkbd_trtab[key];
|
||||
if (key == NOTR)
|
||||
return (NOKEY);
|
||||
|
||||
action = genkbd_keyaction(kbd, key & 0x7f, key & 0x80,
|
||||
if (!repeated) {
|
||||
switch (key) {
|
||||
case 0x1d: /* ctrl */
|
||||
if (release != 0)
|
||||
sc->sc_flags &= ~CTLS;
|
||||
else
|
||||
sc->sc_flags |= CTLS;
|
||||
break;
|
||||
case 0x2a: /* left shift */
|
||||
case 0x36: /* right shift */
|
||||
if (release != 0)
|
||||
sc->sc_flags &= ~SHIFTS;
|
||||
else
|
||||
sc->sc_flags |= SHIFTS;
|
||||
break;
|
||||
case 0x38: /* alt */
|
||||
case 0x5d: /* altgr */
|
||||
if (release != 0)
|
||||
sc->sc_flags &= ~ALTS;
|
||||
else
|
||||
sc->sc_flags |= ALTS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sc->sc_mode == K_RAW) {
|
||||
key = keycode2scancode(key, sc->sc_flags,
|
||||
release);
|
||||
if (key & SCAN_PREFIX) {
|
||||
if (key & SCAN_PREFIX_CTL) {
|
||||
sc->sc_buffered_char[0] =
|
||||
0x1d | (key & SCAN_RELEASE);
|
||||
sc->sc_buffered_char[1] =
|
||||
key & ~SCAN_PREFIX;
|
||||
} else if (key & SCAN_PREFIX_SHIFT) {
|
||||
sc->sc_buffered_char[0] =
|
||||
0x2a | (key & SCAN_RELEASE);
|
||||
sc->sc_buffered_char[1] =
|
||||
key & ~SCAN_PREFIX_SHIFT;
|
||||
} else {
|
||||
sc->sc_buffered_char[0] =
|
||||
key & ~SCAN_PREFIX;
|
||||
sc->sc_buffered_char[1] = 0;
|
||||
}
|
||||
return ((key & SCAN_PREFIX_E0) ?
|
||||
0xe0 : 0xe1);
|
||||
}
|
||||
return (key);
|
||||
}
|
||||
switch (key) {
|
||||
case 0x5c: /* print screen */
|
||||
if (sc->sc_flags & ALTS)
|
||||
key = 0x54; /* sysrq */
|
||||
break;
|
||||
case 0x68: /* pause/break */
|
||||
if (sc->sc_flags & CTLS)
|
||||
key = 0x6c; /* break */
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc->sc_mode == K_CODE)
|
||||
return (key | release);
|
||||
#else
|
||||
if (sc->sc_mode == K_RAW || sc->sc_mode == K_CODE)
|
||||
return (suncode);
|
||||
#endif
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
if (key == 0x38) { /* left alt (KP compose key) */
|
||||
#else
|
||||
if (key == 0x13) { /* left alt (KP compose key) */
|
||||
#endif
|
||||
if (release != 0) {
|
||||
if (sc->sc_flags & KPCOMPOSE) {
|
||||
sc->sc_flags &= ~KPCOMPOSE;
|
||||
if (sc->sc_composed_char > UCHAR_MAX)
|
||||
sc->sc_composed_char = 0;
|
||||
}
|
||||
} else {
|
||||
if (!(sc->sc_flags & KPCOMPOSE)) {
|
||||
sc->sc_flags |= KPCOMPOSE;
|
||||
sc->sc_composed_char = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sc->sc_flags & KPCOMPOSE) {
|
||||
switch (suncode) {
|
||||
case 0x44: /* KP 7 */
|
||||
case 0x45: /* KP 8 */
|
||||
case 0x46: /* KP 9 */
|
||||
sc->sc_composed_char *= 10;
|
||||
sc->sc_composed_char += suncode - 0x3d;
|
||||
if (sc->sc_composed_char > UCHAR_MAX)
|
||||
return (ERRKEY);
|
||||
goto next_code;
|
||||
case 0x5b: /* KP 4 */
|
||||
case 0x5c: /* KP 5 */
|
||||
case 0x5d: /* KP 6 */
|
||||
sc->sc_composed_char *= 10;
|
||||
sc->sc_composed_char += suncode - 0x58;
|
||||
if (sc->sc_composed_char > UCHAR_MAX)
|
||||
return (ERRKEY);
|
||||
goto next_code;
|
||||
case 0x70: /* KP 1 */
|
||||
case 0x71: /* KP 2 */
|
||||
case 0x72: /* KP 3 */
|
||||
sc->sc_composed_char *= 10;
|
||||
sc->sc_composed_char += suncode - 0x6f;
|
||||
if (sc->sc_composed_char > UCHAR_MAX)
|
||||
return (ERRKEY);
|
||||
goto next_code;
|
||||
case 0x5e: /* KP 0 */
|
||||
sc->sc_composed_char *= 10;
|
||||
if (sc->sc_composed_char > UCHAR_MAX)
|
||||
return (ERRKEY);
|
||||
goto next_code;
|
||||
|
||||
case 0x44 | SKBD_KEY_RELEASE: /* KP 7 */
|
||||
case 0x45 | SKBD_KEY_RELEASE: /* KP 8 */
|
||||
case 0x46 | SKBD_KEY_RELEASE: /* KP 9 */
|
||||
case 0x5b | SKBD_KEY_RELEASE: /* KP 4 */
|
||||
case 0x5c | SKBD_KEY_RELEASE: /* KP 5 */
|
||||
case 0x5d | SKBD_KEY_RELEASE: /* KP 6 */
|
||||
case 0x70 | SKBD_KEY_RELEASE: /* KP 1 */
|
||||
case 0x71 | SKBD_KEY_RELEASE: /* KP 2 */
|
||||
case 0x72 | SKBD_KEY_RELEASE: /* KP 3 */
|
||||
case 0x5e | SKBD_KEY_RELEASE: /* KP 0 */
|
||||
goto next_code;
|
||||
default:
|
||||
if (sc->sc_composed_char > 0) {
|
||||
sc->sc_flags &= ~KPCOMPOSE;
|
||||
sc->sc_composed_char = 0;
|
||||
return (ERRKEY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
key = genkbd_keyaction(kbd, key, release,
|
||||
&sc->sc_state, &sc->sc_accents);
|
||||
if (action != NOKEY)
|
||||
return (action);
|
||||
break;
|
||||
if (key != NOKEY || repeated)
|
||||
return (key);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
@ -417,15 +641,23 @@ sunkbd_read_char(keyboard_t *kbd, int wait)
|
||||
static int
|
||||
sunkbd_check_char(keyboard_t *kbd)
|
||||
{
|
||||
TODO;
|
||||
return (0);
|
||||
struct sunkbd_softc *sc;
|
||||
|
||||
if (!KBD_IS_ACTIVE(kbd))
|
||||
return (FALSE);
|
||||
|
||||
sc = (struct sunkbd_softc *)kbd;
|
||||
if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0))
|
||||
return (TRUE);
|
||||
|
||||
return (sunkbd_check(kbd));
|
||||
}
|
||||
|
||||
static int
|
||||
sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
|
||||
{
|
||||
struct sunkbd_softc *sc;
|
||||
int error;
|
||||
int c, error;
|
||||
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5)
|
||||
int ival;
|
||||
#endif
|
||||
@ -477,18 +709,19 @@ sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (sc->sc_uart == NULL)
|
||||
if (sc->sc_sysdev == NULL)
|
||||
break;
|
||||
sc->sc_uart->sc_txdatasz = 2;
|
||||
sc->sc_uart->sc_txbuf[0] = SKBD_CMD_SETLED;
|
||||
sc->sc_uart->sc_txbuf[1] = 0;
|
||||
c = 0;
|
||||
if (*(int *)data & CLKED)
|
||||
sc->sc_uart->sc_txbuf[1] |= SKBD_LED_CAPSLOCK;
|
||||
c |= SKBD_LED_CAPSLOCK;
|
||||
if (*(int *)data & NLKED)
|
||||
sc->sc_uart->sc_txbuf[1] |= SKBD_LED_NUMLOCK;
|
||||
c |= SKBD_LED_NUMLOCK;
|
||||
if (*(int *)data & SLKED)
|
||||
sc->sc_uart->sc_txbuf[1] |= SKBD_LED_SCROLLLOCK;
|
||||
UART_TRANSMIT(sc->sc_uart);
|
||||
c |= SKBD_LED_SCROLLLOCK;
|
||||
uart_lock(sc->sc_sysdev->hwmtx);
|
||||
sc->sc_sysdev->ops.putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED);
|
||||
sc->sc_sysdev->ops.putc(&sc->sc_sysdev->bas, c);
|
||||
uart_unlock(sc->sc_sysdev->hwmtx);
|
||||
KBD_LED_VAL(kbd) = *(int *)data;
|
||||
break;
|
||||
case KDGKBSTATE:
|
||||
@ -524,6 +757,7 @@ sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
|
||||
static int
|
||||
sunkbd_lock(keyboard_t *kbd, int lock)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -531,12 +765,28 @@ sunkbd_lock(keyboard_t *kbd, int lock)
|
||||
static void
|
||||
sunkbd_clear_state(keyboard_t *kbd)
|
||||
{
|
||||
/* TODO; */
|
||||
struct sunkbd_softc *sc;
|
||||
|
||||
sc = (struct sunkbd_softc *)kbd;
|
||||
sc->sc_checked_key = -1;
|
||||
sc->sc_repeat_key = -1;
|
||||
sc->sc_accents = 0;
|
||||
sc->sc_composed_char = 0;
|
||||
sc->sc_flags = 0;
|
||||
sc->sc_polling = 0;
|
||||
sc->sc_repeating = 0;
|
||||
sc->sc_state &= LOCK_MASK; /* Preserve locking key state. */
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
sc->sc_buffered_char[0] = 0;
|
||||
sc->sc_buffered_char[1] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
sunkbd_get_state(keyboard_t *kbd, void *buf, size_t len)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -544,6 +794,7 @@ sunkbd_get_state(keyboard_t *kbd, void *buf, size_t len)
|
||||
static int
|
||||
sunkbd_set_state(keyboard_t *kbd, void *buf, size_t len)
|
||||
{
|
||||
|
||||
TODO;
|
||||
return (0);
|
||||
}
|
||||
@ -564,6 +815,7 @@ sunkbd_poll_mode(keyboard_t *kbd, int on)
|
||||
static void
|
||||
sunkbd_diag(keyboard_t *kbd, int level)
|
||||
{
|
||||
|
||||
TODO;
|
||||
}
|
||||
|
||||
@ -580,3 +832,45 @@ sunkbd_repeat(void *v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SUNKBD_EMULATE_ATKBD)
|
||||
static int
|
||||
keycode2scancode(int keycode, int shift, int up)
|
||||
{
|
||||
static const int scan[] = {
|
||||
/* KP enter, right ctrl, KP divide */
|
||||
0x1c , 0x1d , 0x35 ,
|
||||
/* print screen */
|
||||
0x37 | SCAN_PREFIX_SHIFT,
|
||||
/* right alt, home, up, page up, left, right, end */
|
||||
0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
|
||||
/* down, page down, insert, delete */
|
||||
0x50, 0x51, 0x52, 0x53,
|
||||
/* pause/break (see also below) */
|
||||
0x46,
|
||||
/*
|
||||
* MS: left window, right window, menu
|
||||
* also Sun: left meta, right meta, compose
|
||||
*/
|
||||
0x5b, 0x5c, 0x5d,
|
||||
/* Sun type 6 USB */
|
||||
/* help, stop, again, props, undo, front, copy */
|
||||
0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
|
||||
/* open, paste, find, cut, audiomute, audiolower, audioraise */
|
||||
0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
|
||||
/* power */
|
||||
0x20
|
||||
};
|
||||
int scancode;
|
||||
|
||||
scancode = keycode;
|
||||
if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0])))
|
||||
scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
|
||||
/* pause/break */
|
||||
if ((keycode == 104) && !(shift & CTLS))
|
||||
scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
|
||||
if (shift & SHIFTS)
|
||||
scancode &= ~SCAN_PREFIX_SHIFT;
|
||||
return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
|
||||
}
|
||||
#endif
|
||||
|
@ -63,3 +63,6 @@
|
||||
#define KB_SUN2 2 /* type 2 keyboard */
|
||||
#define KB_SUN3 3 /* type 3 keyboard */
|
||||
#define KB_SUN4 4 /* type 4/5/6 keyboard */
|
||||
|
||||
#define SKBD_KEY_RELEASE 0x80
|
||||
#define SKBD_KEY_CHAR(c) ((c) & 0x7f)
|
||||
|
@ -76,6 +76,16 @@ makeoptions ATKBD_DFLT_KEYMAP=jp.106
|
||||
# dockingstations
|
||||
# 0x04 Old-style (XT) keyboard support, useful for older ThinkPads
|
||||
|
||||
# Sun type 4/5/6 RS-232@TTL keyboard
|
||||
#device sunkbd
|
||||
|
||||
# Options for sunkbd:
|
||||
options SUNKBD_EMULATE_ATKBD # allows to use the AT keyboard maps
|
||||
# in share/syscons/keymaps, required
|
||||
# for SUNKBD_DFLT_KEYMAP and kbdmux
|
||||
options SUNKBD_DFLT_KEYMAP # specify the built-in keymap
|
||||
makeoptions SUNKBD_DFLT_KEYMAP=jp.106
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Devices we don't want to deal with
|
||||
|
Loading…
Reference in New Issue
Block a user