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