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