Home | History | Annotate | Line # | Download | only in common
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