blob: 717ee5541cd70919e0a8e9130ac8e1dabbf47961 [file] [log] [blame]
Jordan Crousef6145c32008-03-19 23:56:58 +00001/*
2 * This file is part of the libpayload project.
3 *
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
Jordan Crousedb8c0ab2008-11-24 17:54:46 +000030#include <libpayload-config.h>
Jordan Crousef6145c32008-03-19 23:56:58 +000031#include <libpayload.h>
Patrick Georgie6408a32008-09-17 18:12:46 +000032#include <curses.h>
Jordan Crousef6145c32008-03-19 23:56:58 +000033
Jordan Crouse63f181f2008-04-25 23:09:39 +000034#define I8042_CMD_READ_MODE 0x20
35#define I8042_CMD_WRITE_MODE 0x60
36
37#define I8042_MODE_XLATE 0x40
38
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +000039struct layout_maps {
Patrick Georgi7f965832011-04-21 18:57:16 +020040 const char *country;
41 const unsigned short map[4][0x57];
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +000042};
43
Stefan Reinauer1beabe12010-03-25 18:52:24 +000044static struct layout_maps *map;
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +000045
Stefan Reinauer1beabe12010-03-25 18:52:24 +000046static struct layout_maps keyboard_layouts[] = {
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +000047#ifdef CONFIG_PC_KEYBOARD_LAYOUT_US
48{ .country = "us", .map = {
Patrick Georgie6408a32008-09-17 18:12:46 +000049 { /* No modifier */
Uwe Hermann6a441bf2008-03-20 19:54:59 +000050 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
51 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09,
52 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
53 0x6F, 0x70, 0x5B, 0x5D, 0x0A, 0x00, 0x61, 0x73,
54 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B,
55 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
56 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A,
Stefan Reinauer4614aed2008-09-18 07:48:59 +000057 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
58 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
Patrick Georgie6408a32008-09-17 18:12:46 +000059 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
60 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00
Uwe Hermann6a441bf2008-03-20 19:54:59 +000061 },
Patrick Georgie6408a32008-09-17 18:12:46 +000062 { /* Shift */
Uwe Hermann6a441bf2008-03-20 19:54:59 +000063 0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E,
64 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00,
65 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
66 0x4F, 0x50, 0x7B, 0x7D, 0x0A, 0x00, 0x41, 0x53,
67 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A,
68 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
69 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A,
Stefan Reinauer4614aed2008-09-18 07:48:59 +000070 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
71 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
Patrick Georgie6408a32008-09-17 18:12:46 +000072 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
73 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00
74 },
75 { /* ALT */
76 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
77 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09,
78 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
79 0x6F, 0x70, 0x5B, 0x5D, 0x0A, 0x00, 0x61, 0x73,
80 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B,
81 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
82 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A,
Stefan Reinauer4614aed2008-09-18 07:48:59 +000083 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
84 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
Patrick Georgie6408a32008-09-17 18:12:46 +000085 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
86 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00
87 },
88 { /* Shift-ALT */
89 0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E,
90 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00,
91 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
92 0x4F, 0x50, 0x7B, 0x7D, 0x0A, 0x00, 0x41, 0x53,
93 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A,
94 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
95 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A,
Stefan Reinauer4614aed2008-09-18 07:48:59 +000096 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
97 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
Patrick Georgie6408a32008-09-17 18:12:46 +000098 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
99 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00
Uwe Hermann6a441bf2008-03-20 19:54:59 +0000100 }
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000101}},
102#endif
103#ifdef CONFIG_PC_KEYBOARD_LAYOUT_DE
104{ .country = "de", .map = {
105 { /* No modifier */
106 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
107 0x37, 0x38, 0x39, 0x30, 0x00, 0x27, 0x08, 0x09,
108 0x71, 0x77, 0x65, 0x72, 0x74, 0x7A, 0x75, 0x69,
109 0x6F, 0x70, 0x00, 0x2B, 0x0A, 0x00, 0x61, 0x73,
110 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x00,
111 0x00, 0x5E, 0x00, 0x23, 0x79, 0x78, 0x63, 0x76,
112 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2D, 0x00, 0x2A,
113 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
114 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
115 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
116 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x3C
117 },
118 { /* Shift */
119 0x00, 0x1B, 0x21, 0x22, 0xA7, 0x24, 0x25, 0x26,
120 0x2F, 0x28, 0x29, 0x3D, 0x3F, 0x60, 0x08, 0x00,
121 0x51, 0x57, 0x45, 0x52, 0x54, 0x5A, 0x55, 0x49,
122 0x4F, 0x50, 0x00, 0x2A, 0x0A, 0x00, 0x41, 0x53,
123 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x00,
124 0x00, 0x7E, 0x00, 0x27, 0x59, 0x58, 0x43, 0x56,
125 0x42, 0x4E, 0x4D, 0x3B, 0x3A, 0x5F, 0x00, 0x2A,
126 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
127 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
128 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
129 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x3E
130 },
131 { /* ALT */
132 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
133 0x7B, 0x5B, 0x5D, 0x7D, 0x5C, 0x3D, 0x08, 0x09,
134 0x40, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
135 0x6F, 0x70, 0x5B, 0x7E, 0x0A, 0x00, 0x61, 0x73,
136 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B,
137 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
138 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A,
139 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
140 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
141 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
142 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x7C
143 },
144 { /* Shift-ALT */
145 /* copied from US */
146 0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E,
147 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00,
148 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
149 0x4F, 0x50, 0x7B, 0x7D, 0x0A, 0x00, 0x41, 0x53,
150 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A,
151 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
152 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A,
153 0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5),
154 KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME,
155 KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END,
156 KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00
157 }
158}},
159#endif
Jordan Crousef6145c32008-03-19 23:56:58 +0000160};
161
Patrick Georgie6408a32008-09-17 18:12:46 +0000162#define MOD_SHIFT (1 << 0)
163#define MOD_CTRL (1 << 1)
164#define MOD_CAPSLOCK (1 << 2)
165#define MOD_ALT (1 << 3)
Jordan Crousef6145c32008-03-19 23:56:58 +0000166
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000167static void keyboard_cmd(unsigned char cmd, unsigned char val)
168{
Patrick Georgi583abc22011-11-10 15:48:37 +0100169 while (inb(0x64) & 2);
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000170 outb(cmd, 0x60);
Patrick Georgi583abc22011-11-10 15:48:37 +0100171 mdelay(20);
172
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000173 while (inb(0x64) & 2);
174 outb(val, 0x60);
Patrick Georgi583abc22011-11-10 15:48:37 +0100175 mdelay(20);
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000176}
177
Jordan Crousef6145c32008-03-19 23:56:58 +0000178int keyboard_havechar(void)
179{
180 unsigned char c = inb(0x64);
Jordan Crouseec6363d2008-10-20 17:07:26 +0000181 return (c == 0xFF) ? 0 : c & 1;
Jordan Crousef6145c32008-03-19 23:56:58 +0000182}
183
184unsigned char keyboard_get_scancode(void)
185{
186 unsigned char ch = 0;
187
188 if (keyboard_havechar())
189 ch = inb(0x60);
190
191 return ch;
192}
193
194int keyboard_getchar(void)
195{
Stefan Reinauer56471f12008-09-02 09:35:43 +0000196 static int modifier = 0;
Jordan Crousef6145c32008-03-19 23:56:58 +0000197 unsigned char ch;
198 int shift;
Jordan Crousef6145c32008-03-19 23:56:58 +0000199 int ret = 0;
200
Uwe Hermann6a441bf2008-03-20 19:54:59 +0000201 while (!keyboard_havechar()) ;
Jordan Crousef6145c32008-03-19 23:56:58 +0000202
203 ch = keyboard_get_scancode();
204
Uwe Hermann6a441bf2008-03-20 19:54:59 +0000205 switch (ch) {
Jordan Crousef6145c32008-03-19 23:56:58 +0000206 case 0x36:
207 case 0x2a:
Stefan Reinauer56471f12008-09-02 09:35:43 +0000208 modifier |= MOD_SHIFT;
Jordan Crousef6145c32008-03-19 23:56:58 +0000209 break;
Jordan Crousef6145c32008-03-19 23:56:58 +0000210 case 0x80 | 0x36:
211 case 0x80 | 0x2a:
Stefan Reinauer56471f12008-09-02 09:35:43 +0000212 modifier &= ~MOD_SHIFT;
Stefan Reinauer96b734c2008-08-12 14:19:40 +0000213 break;
Patrick Georgie6408a32008-09-17 18:12:46 +0000214 case 0x38:
215 modifier |= MOD_ALT;
216 break;
217 case 0x80 | 0x38:
218 modifier &= ~MOD_ALT;
219 break;
Jordan Crousef6145c32008-03-19 23:56:58 +0000220 case 0x1d:
Stefan Reinauer56471f12008-09-02 09:35:43 +0000221 modifier |= MOD_CTRL;
Jordan Crousef6145c32008-03-19 23:56:58 +0000222 break;
Jordan Crousef6145c32008-03-19 23:56:58 +0000223 case 0x80 | 0x1d:
Stefan Reinauer56471f12008-09-02 09:35:43 +0000224 modifier &= ~MOD_CTRL;
Jordan Crousef6145c32008-03-19 23:56:58 +0000225 break;
Jordan Crousef6145c32008-03-19 23:56:58 +0000226 case 0x3a:
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000227 if (modifier & MOD_CAPSLOCK) {
Jordan Crousef6145c32008-03-19 23:56:58 +0000228 modifier &= ~MOD_CAPSLOCK;
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000229 keyboard_cmd(0xed, (0 << 2));
230 } else {
Jordan Crousef6145c32008-03-19 23:56:58 +0000231 modifier |= MOD_CAPSLOCK;
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000232 keyboard_cmd(0xed, (1 << 2));
233 }
Jordan Crousef6145c32008-03-19 23:56:58 +0000234 break;
235 }
236
Uwe Hermann6a441bf2008-03-20 19:54:59 +0000237 if (!(ch & 0x80) && ch < 0x57) {
238 shift =
239 (modifier & MOD_SHIFT) ^ (modifier & MOD_CAPSLOCK) ? 1 : 0;
Patrick Georgie6408a32008-09-17 18:12:46 +0000240
241 if (modifier & MOD_ALT)
242 shift += 2;
243
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000244 ret = map->map[shift][ch];
Jordan Crousef6145c32008-03-19 23:56:58 +0000245
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000246 if (modifier & MOD_CTRL) {
247 switch (ret) {
248 case 'a' ... 'z':
249 ret &= 0x1f;
250 break;
251 case KEY_DC:
252 /* vulcan nerve pinch */
253 if ((modifier & MOD_ALT) && reset_handler)
254 reset_handler();
255 default:
256 ret = 0;
257 }
258 }
Jordan Crousef6145c32008-03-19 23:56:58 +0000259 }
260
261 return ret;
262}
Jordan Crouse63f181f2008-04-25 23:09:39 +0000263
264static int keyboard_wait_read(void)
265{
Patrick Georgi7f965832011-04-21 18:57:16 +0200266 int retries = 10000;
Jordan Crouse63f181f2008-04-25 23:09:39 +0000267
Patrick Georgi7f965832011-04-21 18:57:16 +0200268 while(retries-- && !(inb(0x64) & 0x01))
Jordan Crouse63f181f2008-04-25 23:09:39 +0000269 udelay(50);
270
Patrick Georgi7f965832011-04-21 18:57:16 +0200271 return (retries <= 0) ? -1 : 0;
Jordan Crouse63f181f2008-04-25 23:09:39 +0000272}
273
274static int keyboard_wait_write(void)
275{
Patrick Georgi7f965832011-04-21 18:57:16 +0200276 int retries = 10000;
Jordan Crouse63f181f2008-04-25 23:09:39 +0000277
Patrick Georgi7f965832011-04-21 18:57:16 +0200278 while(retries-- && (inb(0x64) & 0x02))
Jordan Crouse63f181f2008-04-25 23:09:39 +0000279 udelay(50);
280
Patrick Georgi7f965832011-04-21 18:57:16 +0200281 return (retries <= 0) ? -1 : 0;
Jordan Crouse63f181f2008-04-25 23:09:39 +0000282}
283
284static unsigned char keyboard_get_mode(void)
285{
286 outb(I8042_CMD_READ_MODE, 0x64);
287 keyboard_wait_read();
288 return inb(0x60);
289}
290
291static void keyboard_set_mode(unsigned char mode)
292{
293 outb(I8042_CMD_WRITE_MODE, 0x64);
294 keyboard_wait_write();
295 outb(mode, 0x60);
296}
297
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000298/**
299 * Set keyboard layout
Stefan Reinauer14e22772010-04-27 06:56:47 +0000300 * @param country string describing the keyboard layout language.
Patrick Georgi4727c072008-10-16 19:20:51 +0000301 * Valid values are "us", "de".
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000302 */
303
304int keyboard_set_layout(char *country)
305{
306 int i;
307
308 for (i=0; i<ARRAY_SIZE(keyboard_layouts); i++) {
309 if (strncmp(keyboard_layouts[i].country, country,
310 strlen(keyboard_layouts[i].country)))
311 continue;
312
313 /* Found, changing keyboard layout */
314 map = &keyboard_layouts[i];
315 return 0;
316 }
317
318 /* Nothing found, not changed */
319 return -1;
320}
321
Patrick Georgi657a6dc2008-10-21 15:08:18 +0000322static struct console_input_driver cons = {
323 .havekey = keyboard_havechar,
324 .getchar = keyboard_getchar
325};
326
Jordan Crouse63f181f2008-04-25 23:09:39 +0000327void keyboard_init(void)
328{
329 u8 mode;
Stefan Reinauerd84ef1e2008-09-26 18:37:26 +0000330 map = &keyboard_layouts[0];
Jordan Crouse63f181f2008-04-25 23:09:39 +0000331
Jordan Crouseec6363d2008-10-20 17:07:26 +0000332 /* If 0x64 returns 0xff, then we have no keyboard
333 * controller */
334
335 if (inb(0x64) == 0xFF)
336 return;
337
Patrick Georgie6408a32008-09-17 18:12:46 +0000338 /* Empty keyboard buffer */
339 while (keyboard_havechar()) keyboard_getchar();
340
Jordan Crouse63f181f2008-04-25 23:09:39 +0000341 /* Read the current mode */
342 mode = keyboard_get_mode();
343
344 /* Turn on scancode translate mode so that we can
345 use the scancode set 1 tables */
346
347 mode |= I8042_MODE_XLATE;
348
349 /* Write the new mode */
350 keyboard_set_mode(mode);
Patrick Georgi657a6dc2008-10-21 15:08:18 +0000351
352 console_add_input_driver(&cons);
Jordan Crouse63f181f2008-04-25 23:09:39 +0000353}
354