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