153889Smckusick /*
2*63250Sbostic * Copyright (c) 1992, 1993
3*63250Sbostic * The Regents of the University of California. All rights reserved.
453889Smckusick *
553889Smckusick * This code is derived from software contributed to Berkeley by
653889Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753889Smckusick *
853889Smckusick * %sccs.include.redist.c%
953889Smckusick *
1053889Smckusick * from: $Hdr: kb_ctrl.c,v 4.300 91/06/09 06:14:49 root Rel41 $ SONY
1153889Smckusick *
12*63250Sbostic * @(#)kb_ctrl.c 8.1 (Berkeley) 06/10/93
1353889Smckusick */
1453889Smckusick
1553889Smckusick /*
1653889Smckusick * Keyboard driver
1753889Smckusick */
1853889Smckusick
1953889Smckusick #ifdef IPC_MRX
2057177Sutashiro #include <sys/ioctl.h>
2157177Sutashiro #include <news3400/iop/keyboard.h>
2257177Sutashiro #include <news3400/iop/kbreg.h>
2353889Smckusick #else
2457177Sutashiro #include <sys/ioctl.h>
2557177Sutashiro #include <sys/param.h>
2657177Sutashiro #include <sys/systm.h>
2757177Sutashiro #include <sys/types.h>
2857177Sutashiro #include <news3400/iop/keyboard.h>
2957177Sutashiro #include <news3400/iop/kbreg.h>
3053889Smckusick #endif
3153889Smckusick
3253889Smckusick extern int tmode;
3353889Smckusick extern int kbd_status;
3453889Smckusick
3553889Smckusick int iscaps = 0;
3653889Smckusick int change_country = K_JAPANESE_J;
3753889Smckusick int country;
3853889Smckusick
3953889Smckusick extern Key_table default_table[];
4053889Smckusick
4153889Smckusick #ifdef CPU_SINGLE
4253889Smckusick extern Key_table key_table[];
4353889Smckusick Key_table *key_table_addr = key_table;
4453889Smckusick #endif
4553889Smckusick
4653889Smckusick #ifdef CPU_DOUBLE
4753889Smckusick Key_table *key_table_addr = default_table;
4853889Smckusick #endif
4953889Smckusick
5053889Smckusick #ifdef CPU_SINGLE
5153889Smckusick #include "ms.h"
5257177Sutashiro #include <sys/clist.h>
5357177Sutashiro #include <sys/ttydev.h>
5457177Sutashiro #include <sys/tty.h>
5557177Sutashiro #include <news3400/sio/scc.h>
5657177Sutashiro #include <sys/time.h>
5757177Sutashiro #include <news3400/iop/mouse.h>
5853889Smckusick
5953889Smckusick extern int cnrint();
6053889Smckusick
kbd_open(chan)6153889Smckusick kbd_open(chan)
6253889Smckusick int chan;
6353889Smckusick {
6453889Smckusick register int i;
6553889Smckusick
6658606Sutashiro #if defined(news3400)
6753889Smckusick kbm_open(chan);
6853889Smckusick #endif
6953889Smckusick return (0);
7053889Smckusick }
7153889Smckusick
kbd_read(chan,buf,n)7253889Smckusick kbd_read(chan, buf, n)
7353889Smckusick int chan;
7453889Smckusick char *buf;
7553889Smckusick int n;
7653889Smckusick {
7753889Smckusick #if defined(news1700) || defined(news1200)
7853889Smckusick
7953889Smckusick return (kbd_read_raw(chan, buf, n));
8053889Smckusick #endif
8153889Smckusick }
8253889Smckusick
kbd_write(chan,buf,n)8353889Smckusick kbd_write(chan, buf, n)
8453889Smckusick int chan;
8553889Smckusick char *buf;
8653889Smckusick int n;
8753889Smckusick {
8853889Smckusick
8958606Sutashiro #if defined(news3400)
9053889Smckusick return (kbm_write(SCC_KEYBOARD, buf, n));
9153889Smckusick #endif
9253889Smckusick }
9353889Smckusick
kbd_back(buf,len)9453889Smckusick kbd_back(buf, len)
9553889Smckusick register char *buf;
9653889Smckusick register int len;
9753889Smckusick {
9853889Smckusick int s;
9953889Smckusick
10053889Smckusick while (--len >= 0) {
10153889Smckusick s = spltty();
10253889Smckusick cnrint(*buf++);
10353889Smckusick (void) splx(s);
10453889Smckusick }
10553889Smckusick return (0);
10653889Smckusick }
10753889Smckusick
10853889Smckusick #define KBPRI (PZERO+1)
10953889Smckusick
11053889Smckusick struct clist scode_buf;
11153889Smckusick struct clist keyboard_buf;
11253889Smckusick char kb_rwait;
11353889Smckusick
kbd_flush()11453889Smckusick kbd_flush()
11553889Smckusick {
11653889Smckusick
11753889Smckusick ndflush(&scode_buf, scode_buf.c_cc);
11853889Smckusick return (0);
11953889Smckusick }
12053889Smckusick
12153889Smckusick static
kbd_put_raw(scode)12253889Smckusick kbd_put_raw(scode)
12353889Smckusick int scode;
12453889Smckusick {
12553889Smckusick extern char kb_busy;
12653889Smckusick
12753889Smckusick if (kb_busy) {
12853889Smckusick if (scode_buf.c_cc < CBSIZE)
12953889Smckusick putc(scode, &scode_buf);
13053889Smckusick if (kb_rwait) {
13153889Smckusick kb_rwait = 0;
13253889Smckusick wakeup((caddr_t)&kb_rwait);
13353889Smckusick }
13453889Smckusick }
13553889Smckusick return (scode);
13653889Smckusick
13753889Smckusick }
13853889Smckusick
kbd_read_raw(chan,buf,count)13953889Smckusick kbd_read_raw(chan, buf, count)
14053889Smckusick int chan;
14153889Smckusick char *buf;
14253889Smckusick register int count;
14353889Smckusick {
14453889Smckusick register int i;
14553889Smckusick register int n;
14653889Smckusick register int s;
14753889Smckusick
14853889Smckusick if (count <= 0)
14953889Smckusick return (count);
15053889Smckusick s = splscc();
15153889Smckusick while ((n = min(scode_buf.c_cc, count)) == 0) {
15253889Smckusick kb_rwait = 1;
15353889Smckusick sleep((caddr_t)&kb_rwait, KBPRI);
15453889Smckusick kb_rwait = 0;
15553889Smckusick }
15653889Smckusick (void) splx(s);
15753889Smckusick for (i = n; i > 0 ; i--)
15853889Smckusick *buf++ = getc(&scode_buf);
15953889Smckusick return (n);
16053889Smckusick }
16153889Smckusick
kbd_nread()16253889Smckusick kbd_nread()
16353889Smckusick {
16453889Smckusick
16553889Smckusick return (scode_buf.c_cc);
16653889Smckusick }
16753889Smckusick
kbd_bell(n)16853889Smckusick kbd_bell(n)
16953889Smckusick register int n;
17053889Smckusick {
17153889Smckusick
17258606Sutashiro #if defined(news3400)
17353889Smckusick (void) kbm_write(SCC_KEYBOARD, NULL, n);
17453889Smckusick #endif
17553889Smckusick return (0);
17653889Smckusick }
17753889Smckusick
kbd_putcode(code)17853889Smckusick kbd_putcode(code)
17953889Smckusick int code;
18053889Smckusick {
18153889Smckusick int c;
18253889Smckusick
18353889Smckusick kbd_put_raw(code);
18453889Smckusick kbd_encode(code);
18553889Smckusick while ((c = getc(&keyboard_buf)) != -1)
18653889Smckusick cnrint(c);
18753889Smckusick }
18853889Smckusick
put_code(buf,cnt)18953889Smckusick put_code(buf, cnt)
19053889Smckusick register char *buf;
19153889Smckusick register int cnt;
19253889Smckusick {
19353889Smckusick
19453889Smckusick while (--cnt >= 0)
19553889Smckusick putc(*buf++, &keyboard_buf);
19653889Smckusick }
19753889Smckusick
kb_softint()19853889Smckusick kb_softint()
19953889Smckusick {
20053889Smckusick int code;
20153889Smckusick extern int tty00_is_console;
20253889Smckusick
20353889Smckusick while ((code = xgetc(SCC_KEYBOARD)) >= 0) {
20458606Sutashiro #if defined(news3200) /* BEGIN reiko */
20553889Smckusick if ((code & 0x7f) == KEY_EISUU) {
20653889Smckusick int up = code & OFF;
20753889Smckusick static int kana = 0;
20853889Smckusick
20953889Smckusick if (kana) {
21053889Smckusick if (up) {
21153889Smckusick kana = 0;
21253889Smckusick }
21353889Smckusick } else {
21453889Smckusick if (up) {
21553889Smckusick code = KEY_KANA | OFF;
21653889Smckusick kana = 1;
21753889Smckusick } else {
21853889Smckusick code = KEY_KANA;
21953889Smckusick }
22053889Smckusick }
22153889Smckusick }
22253889Smckusick #endif
22353889Smckusick
22453889Smckusick #ifdef NOTDEF /* KU:XXX */
22553889Smckusick if (!tty00_is_console)
22653889Smckusick #endif
22753889Smckusick rst_dimmer_cnt();
22853889Smckusick #if NMS > 0
22953889Smckusick if (!mskeytrigger(0, code & OFF, code & 0x7f))
23053889Smckusick #endif
23153889Smckusick kbd_putcode(code);
23253889Smckusick }
23353889Smckusick }
23453889Smckusick #endif /* CPU_SINGLE */
23553889Smckusick
23653889Smckusick #ifdef IPC_MRX
23753889Smckusick #include "mrx.h"
23853889Smckusick #include "queue.h"
23953889Smckusick #include "process.h"
24053889Smckusick #include "buffer.h"
24153889Smckusick #include "port.h"
24253889Smckusick #include "message.h"
24353889Smckusick #include "machdep.h"
24453889Smckusick #include "malloc.h"
24553889Smckusick #include "config.h"
24653889Smckusick #include "kbms.h"
24753889Smckusick
24853889Smckusick static struct buffer *kbd_buf;
24953889Smckusick static int port_kbd_intr;
25053889Smckusick static int port_kbd_back;
25153889Smckusick static int port_kbd_ctrl;
25253889Smckusick
keyboard(chan)25353889Smckusick keyboard(chan)
25453889Smckusick int chan;
25553889Smckusick {
25653889Smckusick int kbd_ctrl(), kbd_output();
25753889Smckusick int kbd_read(), kbd_ioctl(), kbd_io();
25853889Smckusick
25953889Smckusick #ifdef news3800
26053889Smckusick extern int (*Xkb_intr)();
26153889Smckusick int kb_intr();
26253889Smckusick
26353889Smckusick Xkb_intr = kb_intr;
26453889Smckusick #endif
26553889Smckusick kb_ioctl = kbd_ioctl;
26653889Smckusick kb_read = kbd_read;
26753889Smckusick kbd_init();
26853889Smckusick proc_create("kbd_ctrl", kbd_ctrl, 300, DEFAULT_STACK_SIZE, 0);
26953889Smckusick proc_create("kbd_output", kbd_output, 300, DEFAULT_STACK_SIZE, 0);
27053889Smckusick proc_create("kbd_io", kbd_io, 300, DEFAULT_STACK_SIZE, 0);
27153889Smckusick }
27253889Smckusick
27353889Smckusick int (*reset_dimmer)();
27453889Smckusick
kbd_ctrl()27553889Smckusick kbd_ctrl()
27653889Smckusick {
27753889Smckusick register int m, n;
27853889Smckusick register int select;
27953889Smckusick int *len, from, count;
28053889Smckusick char *addr;
28153889Smckusick int ports[3];
28253889Smckusick static char buf[16];
28353889Smckusick
28453889Smckusick ports[0] = port_kbd_intr = port_create("kb_intr");
28553889Smckusick ports[1] = port_kbd_back = port_create("kb_echoback");
28653889Smckusick ports[2] = port_kbd_ctrl = STDPORT;
28753889Smckusick
28853889Smckusick #ifdef news3800
28953889Smckusick *(char *)KEYBD_RESET = 0;
29053889Smckusick *(char *)KEYBD_INTE = 1;
29153889Smckusick #endif
29253889Smckusick
29353889Smckusick kbd_buf = buffer_alloc(32);
29453889Smckusick (void) spl0();
29553889Smckusick for (;;) {
29653889Smckusick if (buffer_status(kbd_buf) > 0)
29753889Smckusick m = 3;
29853889Smckusick else
29953889Smckusick m = 2;
30053889Smckusick if ((select = msg_select(m, ports)) == 0) {
30153889Smckusick msg_recv(ports[0], NULL, &addr, &count, 0);
30253889Smckusick if (reset_dimmer)
30353889Smckusick (*reset_dimmer)();
30453889Smckusick while (--count >= 0) {
30553889Smckusick if (send_mouse == 0 || (*send_mouse)(*addr) == 0)
30653889Smckusick kbd_encode(*addr);
30753889Smckusick addr++;
30853889Smckusick }
30953889Smckusick } else if (select == 1) { /* ESC [ 6 n */
31053889Smckusick msg_recv(ports[select], NULL, &addr, &count, 0);
31153889Smckusick put(kbd_buf, addr, count);
31253889Smckusick } else {
31353889Smckusick msg_recv(ports[select], &from, &len, NULL, 0);
31453889Smckusick n = buffer_status(kbd_buf);
31553889Smckusick n = min(n, *len);
31653889Smckusick n = get(kbd_buf, buf, min(n, sizeof (buf)));
31753889Smckusick msg_send(from, ports[select], buf, n, 0);
31853889Smckusick }
31953889Smckusick }
32053889Smckusick }
32153889Smckusick
kbd_output()32253889Smckusick kbd_output()
32353889Smckusick {
32453889Smckusick char *addr;
32553889Smckusick int from, len;
32653889Smckusick
32753889Smckusick (void) spl0();
32853889Smckusick for (;;) {
32953889Smckusick msg_recv(STDPORT, &from, &addr, &len, 0);
33053889Smckusick #ifdef news3800
33153889Smckusick len = kbd_write(0, addr, len);
33253889Smckusick #endif
33353889Smckusick msg_send(from, STDPORT, &len, sizeof(len), 0);
33453889Smckusick }
33553889Smckusick }
33653889Smckusick
kbd_io()33753889Smckusick kbd_io()
33853889Smckusick {
33953889Smckusick struct kb_ctrl_req *req;
34053889Smckusick int from, reply;
34153889Smckusick
34253889Smckusick (void) spl0();
34353889Smckusick for (;;) {
34453889Smckusick msg_recv(STDPORT, &from, &req, NULL, 0);
34553889Smckusick if (req->kb_func == KIOCCHTBL || req->kb_func == KIOCOYATBL)
34653889Smckusick kbd_ioctl(0, req->kb_func, req->kb_arg);
34753889Smckusick else
34853889Smckusick kbd_ioctl(0, req->kb_func, &req->kb_arg);
34953889Smckusick reply = req->kb_arg;
35053889Smckusick msg_send(from, STDPORT, &reply, sizeof(reply), 0);
35153889Smckusick }
35253889Smckusick }
35353889Smckusick
kbd_read(chan,buf,n)35453889Smckusick kbd_read(chan, buf, n)
35553889Smckusick int chan;
35653889Smckusick char *buf;
35753889Smckusick int n;
35853889Smckusick {
35953889Smckusick static int port;
36053889Smckusick char *addr;
36153889Smckusick int len;
36253889Smckusick
36353889Smckusick if (port == 0)
36453889Smckusick port = port_create("port_kbd_read");
36553889Smckusick if (n <= 0)
36653889Smckusick return (0);
36753889Smckusick msg_send(port_kbd_ctrl, port, &n, sizeof (n), 0);
36853889Smckusick msg_recv(port, NULL, &addr, &len, 0);
36953889Smckusick bcopy(addr, buf, len);
37053889Smckusick msg_free(port);
37153889Smckusick return (len);
37253889Smckusick }
37353889Smckusick
kbd_write(chan,buf,n)37453889Smckusick kbd_write(chan, buf, n)
37553889Smckusick int chan;
37653889Smckusick char *buf;
37753889Smckusick int n;
37853889Smckusick {
37953889Smckusick
38053889Smckusick #ifdef news3800
38153889Smckusick *(char *)BEEP_FREQ = ~(n & 1);
38253889Smckusick *(char *)KEYBD_BEEP = 1;
38353889Smckusick return (n);
38453889Smckusick #endif
38553889Smckusick }
38653889Smckusick
kbd_back(buf,len)38753889Smckusick kbd_back(buf, len)
38853889Smckusick char *buf;
38953889Smckusick int len;
39053889Smckusick {
39153889Smckusick
39253889Smckusick msg_send(port_kbd_back, 0, buf, len, 0);
39353889Smckusick return (0);
39453889Smckusick }
39553889Smckusick
kbd_nread()39653889Smckusick kbd_nread()
39753889Smckusick {
39853889Smckusick
39953889Smckusick return (buffer_status(kbd_buf));
40053889Smckusick }
40153889Smckusick
kbd_flush()40253889Smckusick kbd_flush()
40353889Smckusick {
40453889Smckusick
40553889Smckusick buffer_flush(kbd_buf);
40653889Smckusick return (0);
40753889Smckusick }
40853889Smckusick
40953889Smckusick #ifdef news3800
kb_intr()41053889Smckusick kb_intr()
41153889Smckusick {
41253889Smckusick char c;
41353889Smckusick
41453889Smckusick if (port_kbd_intr > 0)
41553889Smckusick while (*(char *)KBMS_STAT & (1 << b_KBREADY)) {
41653889Smckusick c = *(char *)KEYBD_DATA;
41753889Smckusick msg_send(port_kbd_intr, 0, &c, sizeof (char), 0);
41853889Smckusick }
41953889Smckusick }
42053889Smckusick #endif /* news3800 */
42153889Smckusick
kbd_bell(n,port)42253889Smckusick kbd_bell(n, port)
42353889Smckusick int n, port;
42453889Smckusick {
42553889Smckusick
42653889Smckusick #ifdef news3800
42753889Smckusick (void) kbd_write(0, NULL, n);
42853889Smckusick #else
42953889Smckusick kbd_bell_scc(n, port);
43053889Smckusick #endif
43153889Smckusick return (0);
43253889Smckusick }
43353889Smckusick
put_code(buf,cnt)43453889Smckusick put_code(buf, cnt)
43553889Smckusick char *buf;
43653889Smckusick int cnt;
43753889Smckusick {
43853889Smckusick
43953889Smckusick put(kbd_buf, buf, cnt);
44053889Smckusick }
44153889Smckusick #endif /* IPC_MRX */
44253889Smckusick
kbd_ioctl(chan,cmd,argp)44353889Smckusick kbd_ioctl(chan, cmd, argp)
44453889Smckusick int chan;
44553889Smckusick int cmd;
44653889Smckusick int *argp;
44753889Smckusick {
44853889Smckusick switch (cmd) {
44953889Smckusick
45053889Smckusick case KIOCFLUSH:
45153889Smckusick return (kbd_flush());
45253889Smckusick
45353889Smckusick case KIOCSETS:
45453889Smckusick case KIOCGETS:
45553889Smckusick return (kbd_string(cmd, (Pfk_string *)argp));
45653889Smckusick
45753889Smckusick case KIOCBELL:
45853889Smckusick return (kbd_bell(*argp));
45953889Smckusick
46053889Smckusick case KIOCBACK:
46153889Smckusick if (argp == NULL)
46253889Smckusick return (-1);
46353889Smckusick if ((int)((Key_string *)argp)->key_string == NULL)
46453889Smckusick return (-1);
46553889Smckusick if ((int)((Key_string *)argp)->key_length <= 0)
46653889Smckusick return (-1);
46753889Smckusick return (kbd_back(((Key_string *)argp)->key_string,
46853889Smckusick ((Key_string *)argp)->key_length));
46953889Smckusick
47053889Smckusick case KIOCREPT:
47153889Smckusick return (kbd_repeat(1));
47253889Smckusick
47353889Smckusick case KIOCNRPT:
47453889Smckusick return (kbd_repeat(0));
47553889Smckusick
47653889Smckusick case KIOCNREAD:
47753889Smckusick *argp = kbd_nread();
47853889Smckusick return (0);
47953889Smckusick
48053889Smckusick case KIOCSETLOCK:
48153889Smckusick iscaps = *argp;
48253889Smckusick return (0);
48353889Smckusick
48453889Smckusick case KIOCGETCNUM:
48553889Smckusick *argp = country;
48653889Smckusick return (0);
48753889Smckusick
48853889Smckusick case KIOCSETCNUM:
48953889Smckusick country = *argp;
49053889Smckusick change_country = country;
49153889Smckusick return (0);
49253889Smckusick
49353889Smckusick case KIOCDEFTBL:
49453889Smckusick key_table_addr = default_table;
49553889Smckusick country = K_JAPANESE_J;
49653889Smckusick return (0);
49753889Smckusick
49853889Smckusick case KIOCCHTBL:
49953889Smckusick key_table_addr = (Key_table *)argp;
50053889Smckusick country = change_country;
50153889Smckusick return (0);
50253889Smckusick
50353889Smckusick case KIOCGETSTAT:
50453889Smckusick *argp = kbd_status;
50553889Smckusick return (0);
50653889Smckusick
50753889Smckusick case KIOCSETSTAT:
50853889Smckusick kbd_status = *argp;
50953889Smckusick return (0);
51053889Smckusick
51153889Smckusick default:
51253889Smckusick return (-1);
51353889Smckusick }
51453889Smckusick }
51553889Smckusick
kbd_bell_scc(n)51653889Smckusick kbd_bell_scc(n)
51753889Smckusick register int n;
51853889Smckusick {
51953889Smckusick register int i;
52053889Smckusick static char bell_data[] = {
52153889Smckusick 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
52253889Smckusick 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
52353889Smckusick 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
52453889Smckusick 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0
52553889Smckusick };
52653889Smckusick
52753889Smckusick while (n > 0) {
52853889Smckusick i = min(n, sizeof (bell_data));
52953889Smckusick (void) kbd_write(0, bell_data, i);
53053889Smckusick n -= i;
53153889Smckusick }
53253889Smckusick }
53353889Smckusick
53453889Smckusick #ifdef KBDEBUG
scc_error_puts(chan,buf)53553889Smckusick scc_error_puts(chan, buf)
53653889Smckusick int chan;
53753889Smckusick char *buf;
53853889Smckusick {
53953889Smckusick while (*buf) {
54053889Smckusick scc_error_write(chan, *buf++, 1);
54153889Smckusick }
54253889Smckusick }
54353889Smckusick
scc_error_write_hex(chan,n,zs)54453889Smckusick scc_error_write_hex(chan, n, zs)
54553889Smckusick int chan;
54653889Smckusick unsigned int n;
54753889Smckusick int zs;
54853889Smckusick {
54953889Smckusick int i;
55053889Smckusick int tmp, al;
55153889Smckusick static char hex[] = "0123456789abcdef";
55253889Smckusick
55353889Smckusick al = 0;
55453889Smckusick
55553889Smckusick for (i = 28; i >= 0; i -= 4) {
55653889Smckusick tmp = (n >> i) & 0x0f;
55753889Smckusick if (tmp || al || !zs || !i) {
55853889Smckusick al++;
55953889Smckusick scc_error_write(chan, hex[tmp], 1);
56053889Smckusick }
56153889Smckusick }
56253889Smckusick }
56353889Smckusick #endif /* KBDEBUG */
564