blob: d4626d69374fe8ae3de2b1b9f3dc520e9288f630 [file] [log] [blame]
Kevin O'Connor3b897192008-07-20 10:08:59 -04001// Support for handling the PS/2 mouse/keyboard ports.
2//
3// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05004// Several ideas taken from code Copyright (c) 1999-2004 Vojtech Pavlik
Kevin O'Connor3b897192008-07-20 10:08:59 -04005//
Kevin O'Connorb1b7c2a2009-01-15 20:52:58 -05006// This file may be distributed under the terms of the GNU LGPLv3 license.
Kevin O'Connor3b897192008-07-20 10:08:59 -04007
8#include "ioport.h" // inb
9#include "util.h" // dprintf
Kevin O'Connor3693af02012-05-13 12:28:55 -040010#include "biosvar.h" // GET_LOW
Kevin O'Connordd5a8a62010-05-01 19:59:34 -040011#include "ps2port.h" // ps2_kbd_command
Kevin O'Connor57877482009-12-09 21:00:41 -050012#include "pic.h" // eoi_pic1
Kevin O'Connor3b897192008-07-20 10:08:59 -040013
14
15/****************************************************************
16 * Low level i8042 commands.
17 ****************************************************************/
18
19// Timeout value.
20#define I8042_CTL_TIMEOUT 10000
21
22#define I8042_BUFFER_SIZE 16
23
Kevin O'Connor3b897192008-07-20 10:08:59 -040024static int
25i8042_wait_read(void)
26{
Kevin O'Connordd3588f2008-11-29 12:41:48 -050027 dprintf(7, "i8042_wait_read\n");
Kevin O'Connor3b897192008-07-20 10:08:59 -040028 int i;
29 for (i=0; i<I8042_CTL_TIMEOUT; i++) {
30 u8 status = inb(PORT_PS2_STATUS);
31 if (status & I8042_STR_OBF)
32 return 0;
33 udelay(50);
34 }
Kevin O'Connorcfdc13f2010-02-14 13:07:54 -050035 warn_timeout();
Kevin O'Connor3b897192008-07-20 10:08:59 -040036 return -1;
37}
38
39static int
40i8042_wait_write(void)
41{
Kevin O'Connordd3588f2008-11-29 12:41:48 -050042 dprintf(7, "i8042_wait_write\n");
Kevin O'Connor3b897192008-07-20 10:08:59 -040043 int i;
44 for (i=0; i<I8042_CTL_TIMEOUT; i++) {
45 u8 status = inb(PORT_PS2_STATUS);
46 if (! (status & I8042_STR_IBF))
47 return 0;
48 udelay(50);
49 }
Kevin O'Connorcfdc13f2010-02-14 13:07:54 -050050 warn_timeout();
Kevin O'Connor3b897192008-07-20 10:08:59 -040051 return -1;
52}
53
Kevin O'Connoradaf3732010-09-13 20:22:07 -040054static int
Kevin O'Connor3b897192008-07-20 10:08:59 -040055i8042_flush(void)
56{
Kevin O'Connordd3588f2008-11-29 12:41:48 -050057 dprintf(7, "i8042_flush\n");
Kevin O'Connor3b897192008-07-20 10:08:59 -040058 int i;
59 for (i=0; i<I8042_BUFFER_SIZE; i++) {
60 u8 status = inb(PORT_PS2_STATUS);
Kevin O'Connor10ad7992009-10-24 11:06:08 -040061 if (! (status & I8042_STR_OBF))
Kevin O'Connor3b897192008-07-20 10:08:59 -040062 return 0;
Kevin O'Connor3b897192008-07-20 10:08:59 -040063 udelay(50);
Kevin O'Connor0234cd92009-01-04 12:20:02 -050064 u8 data = inb(PORT_PS2_DATA);
Kevin O'Connor9e91c7b2009-01-17 02:30:21 -050065 dprintf(7, "i8042 flushed %x (status=%x)\n", data, status);
Kevin O'Connor3b897192008-07-20 10:08:59 -040066 }
67
Kevin O'Connorcfdc13f2010-02-14 13:07:54 -050068 warn_timeout();
Kevin O'Connor3b897192008-07-20 10:08:59 -040069 return -1;
70}
71
72static int
73__i8042_command(int command, u8 *param)
74{
75 int receive = (command >> 8) & 0xf;
76 int send = (command >> 12) & 0xf;
77
78 // Send the command.
79 int ret = i8042_wait_write();
80 if (ret)
81 return ret;
82 outb(command, PORT_PS2_STATUS);
83
84 // Send parameters (if any).
85 int i;
86 for (i = 0; i < send; i++) {
87 ret = i8042_wait_write();
88 if (ret)
89 return ret;
90 outb(param[i], PORT_PS2_DATA);
91 }
92
93 // Receive parameters (if any).
94 for (i = 0; i < receive; i++) {
95 ret = i8042_wait_read();
96 if (ret)
97 return ret;
98 param[i] = inb(PORT_PS2_DATA);
Kevin O'Connor0234cd92009-01-04 12:20:02 -050099 dprintf(7, "i8042 param=%x\n", param[i]);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400100 }
101
102 return 0;
103}
104
Kevin O'Connoradaf3732010-09-13 20:22:07 -0400105static int
Kevin O'Connor3b897192008-07-20 10:08:59 -0400106i8042_command(int command, u8 *param)
107{
Kevin O'Connordd3588f2008-11-29 12:41:48 -0500108 dprintf(7, "i8042_command cmd=%x\n", command);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400109 int ret = __i8042_command(command, param);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400110 if (ret)
111 dprintf(2, "i8042 command %x failed\n", command);
112 return ret;
113}
114
115static int
116i8042_kbd_write(u8 c)
117{
Kevin O'Connordd3588f2008-11-29 12:41:48 -0500118 dprintf(7, "i8042_kbd_write c=%d\n", c);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400119 int ret = i8042_wait_write();
120 if (! ret)
121 outb(c, PORT_PS2_DATA);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400122 return ret;
123}
124
125static int
126i8042_aux_write(u8 c)
127{
128 return i8042_command(I8042_CMD_AUX_SEND, &c);
129}
130
Kevin O'Connoradaf3732010-09-13 20:22:07 -0400131void
132i8042_reboot(void)
133{
Kevin O'Connore216ce82012-01-29 12:25:46 -0500134 if (! CONFIG_PS2PORT)
135 return;
Kevin O'Connoradaf3732010-09-13 20:22:07 -0400136 int i;
137 for (i=0; i<10; i++) {
138 i8042_wait_write();
139 udelay(50);
140 outb(0xfe, PORT_PS2_STATUS); /* pulse reset low */
141 udelay(50);
142 }
143}
144
Kevin O'Connor3b897192008-07-20 10:08:59 -0400145
146/****************************************************************
147 * Device commands.
148 ****************************************************************/
149
150#define PS2_RET_ACK 0xfa
151#define PS2_RET_NAK 0xfe
152
153static int
Kevin O'Connor0234cd92009-01-04 12:20:02 -0500154ps2_recvbyte(int aux, int needack, int timeout)
155{
156 u64 end = calc_future_tsc(timeout);
157 for (;;) {
Kevin O'Connor10ad7992009-10-24 11:06:08 -0400158 u8 status = inb(PORT_PS2_STATUS);
159 if (status & I8042_STR_OBF) {
160 u8 data = inb(PORT_PS2_DATA);
161 dprintf(7, "ps2 read %x\n", data);
162
163 if (!!(status & I8042_STR_AUXDATA) == aux) {
164 if (!needack)
165 return data;
166 if (data == PS2_RET_ACK)
167 return data;
168 if (data == PS2_RET_NAK) {
Kevin O'Connor6080fe02009-12-02 21:19:30 -0500169 dprintf(1, "Got ps2 nak (status=%x)\n", status);
Kevin O'Connor10ad7992009-10-24 11:06:08 -0400170 return data;
171 }
172 }
173
Kevin O'Connorf6282442010-03-13 21:05:12 -0500174 // This data not part of command - just discard it.
175 dprintf(1, "Discarding ps2 data %02x (status=%02x)\n", data, status);
Kevin O'Connor10ad7992009-10-24 11:06:08 -0400176 }
177
Kevin O'Connor144817b2010-05-23 10:46:49 -0400178 if (check_tsc(end)) {
Kevin O'Connorcfdc13f2010-02-14 13:07:54 -0500179 // Don't warn on second byte of a reset
180 if (timeout > 100)
181 warn_timeout();
Kevin O'Connor0234cd92009-01-04 12:20:02 -0500182 return -1;
183 }
Kevin O'Connor10ad7992009-10-24 11:06:08 -0400184 yield();
Kevin O'Connor0234cd92009-01-04 12:20:02 -0500185 }
186}
187
188static int
Kevin O'Connor235df202009-01-18 12:54:51 -0500189ps2_sendbyte(int aux, u8 command, int timeout)
Kevin O'Connor3b897192008-07-20 10:08:59 -0400190{
Kevin O'Connordd3588f2008-11-29 12:41:48 -0500191 dprintf(7, "ps2_sendbyte aux=%d cmd=%x\n", aux, command);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400192 int ret;
193 if (aux)
194 ret = i8042_aux_write(command);
195 else
196 ret = i8042_kbd_write(command);
197 if (ret)
198 return ret;
199
200 // Read ack.
Kevin O'Connorb44a8522009-01-17 23:30:01 -0500201 ret = ps2_recvbyte(aux, 1, timeout);
Kevin O'Connor0234cd92009-01-04 12:20:02 -0500202 if (ret < 0)
Kevin O'Connor3b897192008-07-20 10:08:59 -0400203 return ret;
Kevin O'Connor6080fe02009-12-02 21:19:30 -0500204 if (ret != PS2_RET_ACK)
205 return -1;
Kevin O'Connor3b897192008-07-20 10:08:59 -0400206
207 return 0;
208}
209
Kevin O'Connor3693af02012-05-13 12:28:55 -0400210u8 Ps2ctr VARLOW;
211
Kevin O'Connor3b897192008-07-20 10:08:59 -0400212static int
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400213__ps2_command(int aux, int command, u8 *param)
Kevin O'Connor3b897192008-07-20 10:08:59 -0400214{
Kevin O'Connor6704cf92010-03-13 18:51:46 -0500215 int ret2;
Kevin O'Connor3b897192008-07-20 10:08:59 -0400216 int receive = (command >> 8) & 0xf;
217 int send = (command >> 12) & 0xf;
218
Kevin O'Connor6704cf92010-03-13 18:51:46 -0500219 // Disable interrupts and keyboard/mouse.
Kevin O'Connor3693af02012-05-13 12:28:55 -0400220 u8 ps2ctr = GET_LOW(Ps2ctr);
Kevin O'Connorf6282442010-03-13 21:05:12 -0500221 u8 newctr = ((ps2ctr | I8042_CTR_AUXDIS | I8042_CTR_KBDDIS)
222 & ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT));
Kevin O'Connor6704cf92010-03-13 18:51:46 -0500223 dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr);
224 int ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr);
225 if (ret)
226 return ret;
Kevin O'Connor3b897192008-07-20 10:08:59 -0400227
Kevin O'Connor67a9eec2010-03-13 19:00:02 -0500228 // Flush any interrupts already pending.
229 yield();
230
Kevin O'Connorf6282442010-03-13 21:05:12 -0500231 // Enable port command is being sent to.
232 if (aux)
233 newctr &= ~I8042_CTR_AUXDIS;
234 else
235 newctr &= ~I8042_CTR_KBDDIS;
236 ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr);
237 if (ret)
238 goto fail;
239
Kevin O'Connor235df202009-01-18 12:54:51 -0500240 if (command == ATKBD_CMD_RESET_BAT) {
Kevin O'Connorb9ed5e22010-03-13 19:59:24 -0500241 // Reset is special wrt timeouts and bytes received.
Kevin O'Connor3b897192008-07-20 10:08:59 -0400242
Kevin O'Connor235df202009-01-18 12:54:51 -0500243 // Send command.
244 ret = ps2_sendbyte(aux, command, 1000);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400245 if (ret)
246 goto fail;
Kevin O'Connor235df202009-01-18 12:54:51 -0500247
248 // Receive parameters.
249 ret = ps2_recvbyte(aux, 0, 4000);
250 if (ret < 0)
251 goto fail;
252 param[0] = ret;
253 ret = ps2_recvbyte(aux, 0, 100);
254 if (ret < 0)
255 // Some devices only respond with one byte on reset.
256 ret = 0;
257 param[1] = ret;
Kevin O'Connorb9ed5e22010-03-13 19:59:24 -0500258 } else if (command == ATKBD_CMD_GETID) {
259 // Getid is special wrt bytes received.
260
261 // Send command.
262 ret = ps2_sendbyte(aux, command, 200);
263 if (ret)
264 goto fail;
265
266 // Receive parameters.
267 ret = ps2_recvbyte(aux, 0, 500);
268 if (ret < 0)
269 goto fail;
270 param[0] = ret;
271 if (ret == 0xab || ret == 0xac || ret == 0x2b || ret == 0x5d
272 || ret == 0x60 || ret == 0x47) {
273 // These ids (keyboards) return two bytes.
274 ret = ps2_recvbyte(aux, 0, 500);
275 if (ret < 0)
276 goto fail;
277 param[1] = ret;
278 } else {
279 param[1] = 0;
280 }
Kevin O'Connor235df202009-01-18 12:54:51 -0500281 } else {
282 // Send command.
283 ret = ps2_sendbyte(aux, command, 200);
284 if (ret)
285 goto fail;
286
287 // Send parameters (if any).
288 int i;
289 for (i = 0; i < send; i++) {
290 ret = ps2_sendbyte(aux, param[i], 200);
291 if (ret)
292 goto fail;
293 }
294
295 // Receive parameters (if any).
296 for (i = 0; i < receive; i++) {
297 ret = ps2_recvbyte(aux, 0, 500);
298 if (ret < 0)
299 goto fail;
300 param[i] = ret;
301 }
Kevin O'Connor3b897192008-07-20 10:08:59 -0400302 }
303
Kevin O'Connor235df202009-01-18 12:54:51 -0500304 ret = 0;
Kevin O'Connor3b897192008-07-20 10:08:59 -0400305
306fail:
Kevin O'Connor6704cf92010-03-13 18:51:46 -0500307 // Restore interrupts and keyboard/mouse.
308 ret2 = i8042_command(I8042_CMD_CTL_WCTR, &ps2ctr);
309 if (ret2)
310 return ret2;
Kevin O'Connor3b897192008-07-20 10:08:59 -0400311
312 return ret;
313}
314
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400315static int
316ps2_command(int aux, int command, u8 *param)
Kevin O'Connor3b897192008-07-20 10:08:59 -0400317{
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400318 dprintf(7, "ps2_command aux=%d cmd=%x\n", aux, command);
319 int ret = __ps2_command(aux, command, param);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400320 if (ret)
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400321 dprintf(2, "ps2 command %x failed (aux=%d)\n", command, aux);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400322 return ret;
323}
324
325int
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400326ps2_kbd_command(int command, u8 *param)
Kevin O'Connor3b897192008-07-20 10:08:59 -0400327{
Kevin O'Connore216ce82012-01-29 12:25:46 -0500328 if (! CONFIG_PS2PORT)
329 return -1;
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400330 return ps2_command(0, command, param);
331}
332
333int
334ps2_mouse_command(int command, u8 *param)
335{
Kevin O'Connore216ce82012-01-29 12:25:46 -0500336 if (! CONFIG_PS2PORT)
337 return -1;
338
Kevin O'Connor9ead6fc2011-05-07 14:19:29 -0400339 // Update ps2ctr for mouse enable/disable.
340 if (command == PSMOUSE_CMD_ENABLE || command == PSMOUSE_CMD_DISABLE) {
Kevin O'Connor3693af02012-05-13 12:28:55 -0400341 u8 ps2ctr = GET_LOW(Ps2ctr);
Kevin O'Connor9ead6fc2011-05-07 14:19:29 -0400342 if (command == PSMOUSE_CMD_ENABLE)
343 ps2ctr = (ps2ctr | I8042_CTR_AUXINT) & ~I8042_CTR_AUXDIS;
344 else
345 ps2ctr = (ps2ctr | I8042_CTR_AUXDIS) & ~I8042_CTR_AUXINT;
Kevin O'Connor3693af02012-05-13 12:28:55 -0400346 SET_LOW(Ps2ctr, ps2ctr);
Kevin O'Connor9ead6fc2011-05-07 14:19:29 -0400347 }
348
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400349 return ps2_command(1, command, param);
Kevin O'Connor3b897192008-07-20 10:08:59 -0400350}
Kevin O'Connor57877482009-12-09 21:00:41 -0500351
352
353/****************************************************************
354 * IRQ handlers
355 ****************************************************************/
356
357// INT74h : PS/2 mouse hardware interrupt
358void VISIBLE16
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400359handle_74(void)
Kevin O'Connor57877482009-12-09 21:00:41 -0500360{
361 if (! CONFIG_PS2PORT)
362 return;
363
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400364 debug_isr(DEBUG_ISR_74);
Kevin O'Connora5d84582010-03-13 20:06:34 -0500365
366 u8 v = inb(PORT_PS2_STATUS);
367 if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA))
368 != (I8042_STR_OBF|I8042_STR_AUXDATA)) {
Kevin O'Connorf6282442010-03-13 21:05:12 -0500369 dprintf(1, "ps2 mouse irq but no mouse data.\n");
Kevin O'Connora5d84582010-03-13 20:06:34 -0500370 goto done;
371 }
372 v = inb(PORT_PS2_DATA);
373
Kevin O'Connor3693af02012-05-13 12:28:55 -0400374 if (!(GET_LOW(Ps2ctr) & I8042_CTR_AUXINT))
Kevin O'Connorf6282442010-03-13 21:05:12 -0500375 // Interrupts not enabled.
376 goto done;
377
Kevin O'Connora5d84582010-03-13 20:06:34 -0500378 process_mouse(v);
379
380done:
Kevin O'Connor57877482009-12-09 21:00:41 -0500381 eoi_pic2();
382}
383
384// INT09h : Keyboard Hardware Service Entry Point
385void VISIBLE16
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400386handle_09(void)
Kevin O'Connor57877482009-12-09 21:00:41 -0500387{
388 if (! CONFIG_PS2PORT)
389 return;
390
Kevin O'Connor1297e5d2012-06-02 20:30:58 -0400391 debug_isr(DEBUG_ISR_09);
Kevin O'Connora5d84582010-03-13 20:06:34 -0500392
393 // read key from keyboard controller
394 u8 v = inb(PORT_PS2_STATUS);
Kevin O'Connorf6282442010-03-13 21:05:12 -0500395 if (v & I8042_STR_AUXDATA) {
396 dprintf(1, "ps2 keyboard irq but found mouse data?!\n");
Kevin O'Connora5d84582010-03-13 20:06:34 -0500397 goto done;
398 }
399 v = inb(PORT_PS2_DATA);
400
Kevin O'Connor3693af02012-05-13 12:28:55 -0400401 if (!(GET_LOW(Ps2ctr) & I8042_CTR_KBDINT))
Kevin O'Connorf6282442010-03-13 21:05:12 -0500402 // Interrupts not enabled.
403 goto done;
404
Kevin O'Connora5d84582010-03-13 20:06:34 -0500405 process_key(v);
406
Kevin O'Connor90ce89f2012-03-11 20:45:56 -0400407 // Some old programs expect ISR to turn keyboard back on.
408 i8042_command(I8042_CMD_KBD_ENABLE, NULL);
409
Kevin O'Connora5d84582010-03-13 20:06:34 -0500410done:
Kevin O'Connor57877482009-12-09 21:00:41 -0500411 eoi_pic1();
412}
413
414
415/****************************************************************
416 * Setup
417 ****************************************************************/
418
419static void
Kevin O'Connor1ca05b02010-01-03 17:43:37 -0500420keyboard_init(void *data)
Kevin O'Connor57877482009-12-09 21:00:41 -0500421{
422 /* flush incoming keys */
423 int ret = i8042_flush();
424 if (ret)
425 return;
426
427 // Controller self-test.
428 u8 param[2];
429 ret = i8042_command(I8042_CMD_CTL_TEST, param);
430 if (ret)
431 return;
432 if (param[0] != 0x55) {
433 dprintf(1, "i8042 self test failed (got %x not 0x55)\n", param[0]);
434 return;
435 }
436
437 // Controller keyboard test.
438 ret = i8042_command(I8042_CMD_KBD_TEST, param);
439 if (ret)
440 return;
441 if (param[0] != 0x00) {
442 dprintf(1, "i8042 keyboard test failed (got %x not 0x00)\n", param[0]);
443 return;
444 }
445
Kevin O'Connorf6282442010-03-13 21:05:12 -0500446 // Disable keyboard and mouse events.
Kevin O'Connor3693af02012-05-13 12:28:55 -0400447 SET_LOW(Ps2ctr, I8042_CTR_KBDDIS | I8042_CTR_AUXDIS);
Kevin O'Connor57877482009-12-09 21:00:41 -0500448
449
450 /* ------------------- keyboard side ------------------------*/
451 /* reset keyboard and self test (keyboard side) */
Kevin O'Connoraafe4422011-07-05 20:44:00 -0400452 int spinupdelay = romfile_loadint("etc/ps2-keyboard-spinup", 0);
453 u64 end = calc_future_tsc(spinupdelay);
Kevin O'Connor299dc132011-05-28 11:00:28 -0400454 for (;;) {
455 ret = ps2_kbd_command(ATKBD_CMD_RESET_BAT, param);
456 if (!ret)
457 break;
458 if (check_tsc(end)) {
Kevin O'Connoraafe4422011-07-05 20:44:00 -0400459 if (spinupdelay)
Kevin O'Connor299dc132011-05-28 11:00:28 -0400460 warn_timeout();
461 return;
462 }
463 yield();
464 }
Kevin O'Connor57877482009-12-09 21:00:41 -0500465 if (param[0] != 0xaa) {
466 dprintf(1, "keyboard self test failed (got %x not 0xaa)\n", param[0]);
467 return;
468 }
469
470 /* Disable keyboard */
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400471 ret = ps2_kbd_command(ATKBD_CMD_RESET_DIS, NULL);
Kevin O'Connor57877482009-12-09 21:00:41 -0500472 if (ret)
473 return;
474
475 // Set scancode command (mode 2)
476 param[0] = 0x02;
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400477 ret = ps2_kbd_command(ATKBD_CMD_SSCANSET, param);
Kevin O'Connor57877482009-12-09 21:00:41 -0500478 if (ret)
479 return;
480
Kevin O'Connorf6282442010-03-13 21:05:12 -0500481 // Keyboard Mode: disable mouse, scan code convert, enable kbd IRQ
Kevin O'Connor3693af02012-05-13 12:28:55 -0400482 SET_LOW(Ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT);
Kevin O'Connor57877482009-12-09 21:00:41 -0500483
484 /* Enable keyboard */
Kevin O'Connordd5a8a62010-05-01 19:59:34 -0400485 ret = ps2_kbd_command(ATKBD_CMD_ENABLE, NULL);
Kevin O'Connor57877482009-12-09 21:00:41 -0500486 if (ret)
487 return;
488
Kevin O'Connor357bdfa2010-02-26 08:57:13 -0500489 dprintf(1, "PS2 keyboard initialized\n");
Kevin O'Connor57877482009-12-09 21:00:41 -0500490}
491
492void
Kevin O'Connor1ca05b02010-01-03 17:43:37 -0500493ps2port_setup(void)
Kevin O'Connor57877482009-12-09 21:00:41 -0500494{
Kevin O'Connor59c75742010-02-13 18:49:24 -0500495 ASSERT32FLAT();
Kevin O'Connor57877482009-12-09 21:00:41 -0500496 if (! CONFIG_PS2PORT)
497 return;
498 dprintf(3, "init ps2port\n");
499
Kevin O'Connorcc9e1bf2010-07-28 21:31:38 -0400500 enable_hwirq(1, FUNC16(entry_09));
501 enable_hwirq(12, FUNC16(entry_74));
Kevin O'Connor57877482009-12-09 21:00:41 -0500502
503 run_thread(keyboard_init, NULL);
504}