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