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