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