cons_zskbd.c revision 1.4 1 1.4 martin /* $NetBSD: cons_zskbd.c,v 1.4 2008/04/28 20:23:18 martin Exp $ */
2 1.1 tsutsui
3 1.1 tsutsui /*-
4 1.1 tsutsui * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc.
5 1.1 tsutsui * All rights reserved.
6 1.1 tsutsui *
7 1.1 tsutsui * This code is derived from software contributed to The NetBSD Foundation
8 1.1 tsutsui * by UCHIYAMA Yasushi.
9 1.1 tsutsui *
10 1.1 tsutsui * Redistribution and use in source and binary forms, with or without
11 1.1 tsutsui * modification, are permitted provided that the following conditions
12 1.1 tsutsui * are met:
13 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright
14 1.1 tsutsui * notice, this list of conditions and the following disclaimer.
15 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the
17 1.1 tsutsui * documentation and/or other materials provided with the distribution.
18 1.1 tsutsui *
19 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 tsutsui * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 tsutsui * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 tsutsui * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 tsutsui * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 tsutsui * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 tsutsui * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 tsutsui * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 tsutsui * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 tsutsui * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 tsutsui * POSSIBILITY OF SUCH DAMAGE.
30 1.1 tsutsui */
31 1.1 tsutsui
32 1.1 tsutsui #include <sys/param.h>
33 1.1 tsutsui #include <sys/systm.h>
34 1.1 tsutsui
35 1.1 tsutsui #include <lib/libsa/stand.h>
36 1.1 tsutsui #include <lib/libkern/libkern.h>
37 1.1 tsutsui
38 1.1 tsutsui #include <machine/sbd.h>
39 1.1 tsutsui
40 1.1 tsutsui #include "console.h"
41 1.1 tsutsui
42 1.1 tsutsui struct zskbd zskbd;
43 1.1 tsutsui
44 1.1 tsutsui int zskbd_common_getc(int);
45 1.1 tsutsui void zskbd_busy(void);
46 1.1 tsutsui
47 1.1 tsutsui static const uint8_t map_normal[] = {
48 1.1 tsutsui '0', '1', '2', '3', '4', '5', '6', '7',
49 1.1 tsutsui '8', '9', '-', '^', '\\', ':', '.', '/',
50 1.1 tsutsui '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
51 1.1 tsutsui 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
52 1.1 tsutsui 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
53 1.1 tsutsui 'x', 'y', 'z', '[', ',', ']', ';', 0x00,
54 1.1 tsutsui '0', '1', '2', '3', '4', '5', '6', '7',
55 1.1 tsutsui '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
56 1.2 tsutsui '\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.',
57 1.1 tsutsui 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 1.1 tsutsui 0x08, 0x00, 0x0c, 0x7f, 0x12, 0x00, 0x00, 0x00,
59 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 1.1 tsutsui 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
62 1.2 tsutsui '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
63 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 1.1 tsutsui };
65 1.1 tsutsui
66 1.1 tsutsui static const uint8_t map_shift[] = {
67 1.1 tsutsui '0', '!', '\"', '#', '$', '%', '&', '\'',
68 1.1 tsutsui '(', ')', '=', '^', '|', '*', '>', '?',
69 1.1 tsutsui '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
70 1.1 tsutsui 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
71 1.1 tsutsui 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
72 1.1 tsutsui 'X', 'Y', 'Z', '{', '<', '}', '+', '_',
73 1.1 tsutsui '0', '1', '2', '3', '4', '5', '6', '7',
74 1.1 tsutsui '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
75 1.2 tsutsui '\r', '\r', 'B', 'C', '\r', 'E', '-', '.',
76 1.1 tsutsui 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 1.1 tsutsui 0x08, 0x00, 0x0b, 0x7f, 0x12, 0x09, 0x00, 0x00,
78 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 1.1 tsutsui 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
81 1.2 tsutsui '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
82 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 1.1 tsutsui };
84 1.1 tsutsui
85 1.1 tsutsui static const uint8_t map_ctrl[] = {
86 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 1.1 tsutsui 0xa4, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
89 1.1 tsutsui 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
90 1.1 tsutsui 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
91 1.1 tsutsui 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
92 1.1 tsutsui '0', '1', '2', '3', '4', '5', '6', '7',
93 1.1 tsutsui '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
94 1.2 tsutsui '\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.',
95 1.1 tsutsui 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 1.1 tsutsui 0x08, 0x00, 0x00, 0x7f, 0x12, 0x00, 0x00, 0x00,
97 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 1.1 tsutsui 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
100 1.2 tsutsui '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
101 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 1.1 tsutsui };
103 1.1 tsutsui
104 1.1 tsutsui static const uint8_t map_capslock[] = {
105 1.1 tsutsui '0', '1', '2', '3', '4', '5', '6', '7',
106 1.1 tsutsui '8', '9', '-', '^', '\\', ':', '.', '/',
107 1.1 tsutsui '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
108 1.1 tsutsui 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
109 1.1 tsutsui 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
110 1.1 tsutsui 'X', 'Y', 'Z', '[', ',', ']', ';', 0x00,
111 1.1 tsutsui '0', '1', '2', '3', '4', '5', '6', '7',
112 1.1 tsutsui '8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
113 1.2 tsutsui '\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.',
114 1.1 tsutsui 0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 1.1 tsutsui 0x08, 0x00, 0x0c, 0x7f, 0x12, 0x00, 0x00, 0x00,
116 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 1.1 tsutsui 0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
119 1.2 tsutsui '+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
120 1.1 tsutsui 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 1.1 tsutsui };
122 1.1 tsutsui
123 1.1 tsutsui void
124 1.1 tsutsui zskbd_set_addr(uint32_t status, uint32_t data)
125 1.1 tsutsui {
126 1.1 tsutsui zskbd.status = (volatile uint8_t *)status;
127 1.1 tsutsui zskbd.data = (volatile uint8_t *)data;
128 1.1 tsutsui zskbd.normal = map_normal;
129 1.1 tsutsui zskbd.shift = map_shift;
130 1.1 tsutsui zskbd.ctrl = map_ctrl;
131 1.1 tsutsui zskbd.capslock = map_capslock;
132 1.1 tsutsui
133 1.1 tsutsui cons.getc = zskbd_getc;
134 1.1 tsutsui cons.scan = zskbd_scan;
135 1.1 tsutsui }
136 1.1 tsutsui
137 1.1 tsutsui void
138 1.1 tsutsui zskbd_print_keyscan(int on)
139 1.1 tsutsui {
140 1.1 tsutsui
141 1.1 tsutsui zskbd.print = on;
142 1.1 tsutsui }
143 1.1 tsutsui
144 1.1 tsutsui int
145 1.1 tsutsui zskbd_getc(void)
146 1.1 tsutsui {
147 1.1 tsutsui
148 1.1 tsutsui return zskbd_common_getc(0);
149 1.1 tsutsui }
150 1.1 tsutsui
151 1.1 tsutsui int
152 1.1 tsutsui zskbd_scan(void)
153 1.1 tsutsui {
154 1.1 tsutsui
155 1.1 tsutsui return zskbd_common_getc(1);
156 1.1 tsutsui }
157 1.1 tsutsui
158 1.1 tsutsui int
159 1.1 tsutsui zskbd_common_getc(int scan)
160 1.1 tsutsui {
161 1.1 tsutsui #ifdef CHECK_KEY_RELEASE
162 1.1 tsutsui static int released = 1;
163 1.1 tsutsui int push;
164 1.1 tsutsui #endif
165 1.1 tsutsui int v, c;
166 1.1 tsutsui
167 1.1 tsutsui for (;;) {
168 1.1 tsutsui if (scan) {
169 1.1 tsutsui if ((*zskbd.status & 0x01) != 0x01)
170 1.1 tsutsui return -1;
171 1.1 tsutsui } else {
172 1.1 tsutsui while ((*zskbd.status & 0x01) != 0x01)
173 1.1 tsutsui continue;
174 1.1 tsutsui }
175 1.1 tsutsui
176 1.1 tsutsui v = *zskbd.data;
177 1.1 tsutsui if (zskbd.print)
178 1.1 tsutsui printf("scancode = 0x%x\n", v);
179 1.1 tsutsui
180 1.1 tsutsui switch (v) {
181 1.1 tsutsui case 123: /* Shift-L */
182 1.1 tsutsui /* FALLTHROUGH */
183 1.1 tsutsui case 124: /* Shift-R */
184 1.1 tsutsui zskbd.keymap |= 0x01;
185 1.1 tsutsui break;
186 1.1 tsutsui case 251:
187 1.1 tsutsui /* FALLTHROUGH */
188 1.1 tsutsui case 252:
189 1.1 tsutsui zskbd.keymap &= ~0x01;
190 1.1 tsutsui break;
191 1.1 tsutsui case 120: /* Ctrl-L */
192 1.1 tsutsui zskbd.keymap |= 0x02;
193 1.1 tsutsui break;
194 1.1 tsutsui case 248:
195 1.1 tsutsui zskbd.keymap &= ~0x02;
196 1.1 tsutsui break;
197 1.1 tsutsui case 121: /* CapsLock */
198 1.1 tsutsui if (zskbd.keymap & 0x04) {
199 1.1 tsutsui zskbd.keymap &= ~0x04;
200 1.1 tsutsui zskbd_busy();
201 1.1 tsutsui *zskbd.data = 0x90; /* LED */
202 1.1 tsutsui } else {
203 1.1 tsutsui zskbd.keymap |= 0x04;
204 1.1 tsutsui zskbd_busy();
205 1.1 tsutsui *zskbd.data = 0x92; /* LED */
206 1.1 tsutsui }
207 1.1 tsutsui break;
208 1.1 tsutsui default:
209 1.1 tsutsui #ifdef CHECK_KEY_RELEASE
210 1.1 tsutsui push = (v & 0x80) == 0;
211 1.1 tsutsui if (push && released) {
212 1.1 tsutsui released = 0;
213 1.1 tsutsui goto exit_loop;
214 1.1 tsutsui }
215 1.1 tsutsui if (!push)
216 1.1 tsutsui released = 1;
217 1.1 tsutsui #else /* CHECK_KEY_RELEASE */
218 1.1 tsutsui if ((v & 0x80) == 0)
219 1.1 tsutsui goto exit_loop;
220 1.1 tsutsui #endif /* CHECK_KEY_RELEASE */
221 1.1 tsutsui break;
222 1.1 tsutsui }
223 1.1 tsutsui }
224 1.1 tsutsui
225 1.1 tsutsui exit_loop:
226 1.1 tsutsui c = v & 0x7f;
227 1.1 tsutsui if (zskbd.keymap & 0x01) /* Shift */
228 1.1 tsutsui return *(zskbd.shift + c);
229 1.1 tsutsui if (zskbd.keymap & 0x02) /* Ctrl */
230 1.1 tsutsui return *(zskbd.ctrl + c);
231 1.1 tsutsui if (zskbd.keymap & 0x04) /* CapsLock */
232 1.1 tsutsui return *(zskbd.capslock + c);
233 1.1 tsutsui /* Normal */
234 1.1 tsutsui return *(zskbd.normal + c);
235 1.1 tsutsui }
236 1.1 tsutsui
237 1.1 tsutsui void
238 1.1 tsutsui zskbd_busy(void)
239 1.1 tsutsui {
240 1.1 tsutsui
241 1.1 tsutsui #if 0 /* I misunderstand??? -uch */
242 1.1 tsutsui do {
243 1.1 tsutsui while ((*zskbd.status & 0x20) != 0x20)
244 1.1 tsutsui ;
245 1.1 tsutsui } while ((*zskbd.status & 0x4) != 0x4);
246 1.1 tsutsui #endif
247 1.1 tsutsui }
248