|
|
1.1 root 1: /*
2: * Copyright (C) 2003, 2004 Stefan Reinauer
3: *
4: * See the file "COPYING" for further information about
5: * the copyright and warranty status of this work.
6: */
7:
8: #include "config.h"
9: #include "libopenbios/bindings.h"
10: #include "kernel/kernel.h"
11: #include "drivers/drivers.h"
12: #include "libc/vsprintf.h"
13:
14: /* ******************************************************************
15: * simple polling video/keyboard console functions
16: * ****************************************************************** */
17:
18: /*
19: * keyboard driver
20: */
21:
22: static const char normal[] = {
23: 0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
24: '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
25: 'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j',
26: 'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b',
27: 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
28: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
29: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f
30: };
31:
32: static const char shifted[] = {
33: 0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
34: '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
35: 'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J',
36: 'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B',
37: 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
38: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8',
39: '9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f
40: };
41:
42: static int key_ext;
43: static int key_lshift = 0, key_rshift = 0, key_caps = 0;
44:
45: static char last_key;
46:
47: static void pc_kbd_cmd(unsigned char cmd, unsigned char val)
48: {
49: outb(cmd, 0x60);
50: /* wait until keyboard controller accepts cmds: */
51: while (inb(0x64) & 2);
52: outb(val, 0x60);
53: while (inb(0x64) & 2);
54: }
55:
56: static void pc_kbd_controller_cmd(unsigned char cmd, unsigned char val)
57: {
58: outb(cmd, 0x64);
59: /* wait until keyboard controller accepts cmds: */
60: while (inb(0x64) & 2);
61: outb(val, 0x60);
62: while (inb(0x64) & 2);
63: }
64:
65: static char pc_kbd_poll(void)
66: {
67: unsigned int c;
68: if (inb(0x64) & 1) {
69: c = inb(0x60);
70: switch (c) {
71: case 0xe0:
72: key_ext = 1;
73: return 0;
74: case 0x2a:
75: key_lshift = 1;
76: return 0;
77: case 0x36:
78: key_rshift = 1;
79: return 0;
80: case 0xaa:
81: key_lshift = 0;
82: return 0;
83: case 0xb6:
84: key_rshift = 0;
85: return 0;
86: case 0x3a:
87: if (key_caps) {
88: key_caps = 0;
89: pc_kbd_cmd(0xed, 0);
90: } else {
91: key_caps = 1;
92: pc_kbd_cmd(0xed, 4); /* set caps led */
93: }
94: return 0;
95: }
96:
97: if (key_ext) {
98: // void printk(const char *format, ...);
99: printk("extended keycode: %x\n", c);
100:
101: key_ext = 0;
102: return 0;
103: }
104:
105: if (c & 0x80) /* unhandled key release */
106: return 0;
107:
108: if (key_lshift || key_rshift)
109: return key_caps ? normal[c] : shifted[c];
110: else
111: return key_caps ? shifted[c] : normal[c];
112: }
113: return 0;
114: }
115:
116: int pc_kbd_dataready(void)
117: {
118: if (last_key)
119: return 1;
120:
121: last_key = pc_kbd_poll();
122:
123: return (last_key != 0);
124: }
125:
126: unsigned char pc_kbd_readdata(void)
127: {
128: char tmp;
129: while (!pc_kbd_dataready());
130: tmp = last_key;
131: last_key = 0;
132: return tmp;
133: }
134:
135: /* ( addr len -- actual ) */
136: static void
137: pc_kbd_read(void)
138: {
139: unsigned char *addr;
140: int len;
141:
142: len = POP();
143: addr = (unsigned char *)POP();
144:
145: if (len != 1)
146: printk("pc_kbd_read: bad len, addr %lx len %x\n", (unsigned long)addr, len);
147:
148: if (pc_kbd_dataready()) {
149: *addr = pc_kbd_readdata();
150: PUSH(1);
151: } else {
152: PUSH(0);
153: }
154: }
155:
156: static void
157: pc_kbd_close(void)
158: {
159: }
160:
161: static void
162: pc_kbd_open(unsigned long *address)
163: {
164: int len;
165: phandle_t ph;
166: unsigned long *prop;
167:
168: fword("my-self");
169: fword("ihandle>phandle");
170: ph = (phandle_t)POP();
171: prop = (unsigned long *)get_property(ph, "address", &len);
172: *address = *prop;
173:
174: RET ( -1 );
175: }
176:
177: DECLARE_UNNAMED_NODE(pc_kbd, INSTALL_OPEN, sizeof(unsigned long));
178:
179: NODE_METHODS(pc_kbd) = {
180: { "open", pc_kbd_open },
181: { "close", pc_kbd_close },
182: { "read", pc_kbd_read },
183: };
184:
185: void
186: ob_pc_kbd_init(const char *path, const char *dev_name, uint64_t base,
187: uint64_t offset, int intr)
188: {
189: phandle_t chosen, aliases;
190: char nodebuff[128];
191:
192: snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name);
193: REGISTER_NAMED_NODE(pc_kbd, nodebuff);
194:
195: push_str(nodebuff);
196: fword("find-device");
197:
198: push_str(dev_name);
199: fword("device-name");
200:
201: push_str("serial");
202: fword("device-type");
203:
204: PUSH(-1);
205: fword("encode-int");
206: push_str("keyboard");
207: fword("property");
208:
209: PUSH(0);
210: fword("encode-int");
211: push_str("reg");
212: fword("property");
213:
214: chosen = find_dev("/chosen");
215: push_str(nodebuff);
216: fword("open-dev");
217: set_int_property(chosen, "keyboard", POP());
218:
219: aliases = find_dev("/aliases");
220: set_property(aliases, "keyboard", nodebuff, strlen(nodebuff) + 1);
221:
222: pc_kbd_controller_cmd(0x60, 0x40); // Write mode command, translated mode
223: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.