File indexing completed on 2025-05-11 08:23:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <stdio.h>
0020 #include <stdlib.h>
0021 #include <errno.h>
0022
0023 #include <bsp.h>
0024 #include <rtems/keyboard.h>
0025 #include "i386kbd.h"
0026
0027 static unsigned char handle_kbd_event(void);
0028 static void kbd_write_command_w(int data);
0029 static void kbd_write_output_w(int data);
0030
0031
0032
0033
0034
0035 #ifdef CONFIG_MAGIC_SYSRQ
0036 unsigned char pckbd_sysrq_xlate[128] =
0037 "\000\0331234567890-=\177\t"
0038 "qwertyuiop[]\r\000as"
0039 "dfghjkl;'`\000\\zxcv"
0040 "bnm,./\000*\000 \000\201\202\203\204\205"
0041 "\206\207\210\211\212\000\000789-456+1"
0042 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000"
0043 "\r\000/";
0044 #endif
0045
0046
0047 static volatile unsigned char reply_expected = 0;
0048 static volatile unsigned char acknowledge = 0;
0049 static volatile unsigned char resend = 0;
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 #define E0_KPENTER 96
0062 #define E0_RCTRL 97
0063 #define E0_KPSLASH 98
0064 #define E0_PRSCR 99
0065 #define E0_RALT 100
0066 #define E0_BREAK 101
0067 #define E0_HOME 102
0068 #define E0_UP 103
0069 #define E0_PGUP 104
0070 #define E0_LEFT 105
0071 #define E0_RIGHT 106
0072 #define E0_END 107
0073 #define E0_DOWN 108
0074 #define E0_PGDN 109
0075 #define E0_INS 110
0076 #define E0_DEL 111
0077
0078 #define E1_PAUSE 119
0079
0080
0081
0082
0083
0084
0085
0086
0087 #define SC_LIM 89
0088
0089 #define FOCUS_PF1 85
0090 #define FOCUS_PF2 89
0091 #define FOCUS_PF3 90
0092 #define FOCUS_PF4 91
0093 #define FOCUS_PF5 92
0094 #define FOCUS_PF6 93
0095 #define FOCUS_PF7 94
0096 #define FOCUS_PF8 95
0097 #define FOCUS_PF9 120
0098 #define FOCUS_PF10 121
0099 #define FOCUS_PF11 122
0100 #define FOCUS_PF12 123
0101
0102 #define JAP_86 124
0103
0104
0105
0106
0107
0108
0109 #define RGN1 124
0110 #define RGN2 125
0111 #define RGN3 126
0112 #define RGN4 127
0113
0114 static unsigned char high_keys[128 - SC_LIM] = {
0115 RGN1, RGN2, RGN3, RGN4, 0, 0, 0,
0116 0, 0, 0, 0, 0, 0, 0, 0,
0117 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,
0118 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,
0119 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,
0120 FOCUS_PF8, JAP_86, FOCUS_PF10, 0
0121 };
0122
0123
0124 #define E0_MACRO 112
0125
0126 #define E0_F13 113
0127 #define E0_F14 114
0128 #define E0_HELP 115
0129 #define E0_DO 116
0130 #define E0_F17 117
0131 #define E0_KPMINPLUS 118
0132
0133
0134
0135
0136 #define E0_OK 124
0137
0138
0139
0140
0141
0142
0143 #define E0_MSLW 125
0144 #define E0_MSRW 126
0145 #define E0_MSTM 127
0146
0147 static unsigned char e0_keys[128] = {
0148 0, 0, 0, 0, 0, 0, 0, 0,
0149 0, 0, 0, 0, 0, 0, 0, 0,
0150 0, 0, 0, 0, 0, 0, 0, 0,
0151 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,
0152 0, 0, 0, 0, 0, 0, 0, 0,
0153 0, 0, 0, 0, 0, 0, 0, 0,
0154 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,
0155 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,
0156 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,
0157 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
0158 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,
0159 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,
0160 0, 0, 0, 0, 0, 0, 0, 0,
0161 0, 0, 0, 0, 0, 0, 0, E0_MACRO,
0162 0, 0, 0, 0, 0, 0, 0, 0,
0163 0, 0, 0, 0, 0, 0, 0, 0
0164 };
0165
0166 static void mdelay( unsigned long t )
0167 {
0168 Wait_X_ms( t );
0169 }
0170
0171 int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
0172 {
0173 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
0174 return -EINVAL;
0175 if (scancode < 128)
0176 high_keys[scancode - SC_LIM] = keycode;
0177 else
0178 e0_keys[scancode - 128] = keycode;
0179 return 0;
0180 }
0181
0182 int pckbd_getkeycode(unsigned int scancode)
0183 {
0184 return
0185 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
0186 (scancode < 128) ? high_keys[scancode - SC_LIM] :
0187 e0_keys[scancode - 128];
0188 }
0189
0190 static int do_acknowledge(unsigned char scancode)
0191 {
0192 if (reply_expected) {
0193
0194
0195
0196
0197
0198 if (scancode == KBD_REPLY_ACK) {
0199 acknowledge = 1;
0200 reply_expected = 0;
0201 return 0;
0202 } else if (scancode == KBD_REPLY_RESEND) {
0203 resend = 1;
0204 reply_expected = 0;
0205 return 0;
0206 }
0207
0208 printk( "keyboard reply expected - got %02x\n", scancode);
0209 }
0210 return 1;
0211 }
0212
0213 int pckbd_translate(unsigned char scancode, unsigned char *keycode,
0214 char raw_mode)
0215 {
0216 static int prev_scancode = 0;
0217
0218
0219 if (scancode == 0xe0 || scancode == 0xe1) {
0220 prev_scancode = scancode;
0221 return 0;
0222 }
0223
0224
0225 if (scancode == 0x00 || scancode == 0xff) {
0226 prev_scancode = 0;
0227 return 0;
0228 }
0229
0230 scancode &= 0x7f;
0231
0232 if (prev_scancode) {
0233
0234
0235
0236
0237 if (prev_scancode != 0xe0) {
0238 if (prev_scancode == 0xe1 && scancode == 0x1d) {
0239 prev_scancode = 0x100;
0240 return 0;
0241 } else if (prev_scancode == 0x100 && scancode == 0x45) {
0242 *keycode = E1_PAUSE;
0243 prev_scancode = 0;
0244 } else {
0245 #ifdef KBD_REPORT_UNKN
0246 if (!raw_mode)
0247 printk("keyboard: unknown e1 escape sequence\n");
0248 #endif
0249 prev_scancode = 0;
0250 return 0;
0251 }
0252 } else {
0253 prev_scancode = 0;
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267 if (scancode == 0x2a || scancode == 0x36)
0268 return 0;
0269
0270 if (e0_keys[scancode])
0271 *keycode = e0_keys[scancode];
0272 else {
0273 #ifdef KBD_REPORT_UNKN
0274 if (!raw_mode)
0275 printk( "keyboard: unknown scancode e0 %02x\n",
0276 scancode);
0277 #endif
0278 return 0;
0279 }
0280 }
0281 } else if (scancode >= SC_LIM) {
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 *keycode = high_keys[scancode - SC_LIM];
0293 if (!*keycode) {
0294 if (!raw_mode) {
0295 #ifdef KBD_REPORT_UNKN
0296 printk( "keyboard: unrecognized scancode (%02x)"
0297 " - ignored\n", scancode);
0298 #endif
0299 }
0300 return 0;
0301 }
0302 } else
0303 *keycode = scancode;
0304 return 1;
0305 }
0306
0307 char pckbd_unexpected_up(unsigned char keycode)
0308 {
0309
0310
0311 if (keycode >= SC_LIM || keycode == 85)
0312 return 0;
0313 else
0314 return 0200;
0315 }
0316
0317 static void kb_wait(void)
0318 {
0319 unsigned long timeout = KBC_TIMEOUT;
0320
0321 do {
0322
0323
0324
0325
0326 unsigned char status = handle_kbd_event();
0327
0328 if (! (status & KBD_STAT_IBF))
0329 return;
0330 mdelay(1);
0331 timeout--;
0332 } while (timeout);
0333 #ifdef KBD_REPORT_TIMEOUTS
0334 printk( "Keyboard timed out[1]\n");
0335 #endif
0336 }
0337
0338
0339
0340
0341
0342
0343
0344
0345 static unsigned char handle_kbd_event(void)
0346 {
0347 unsigned char status = kbd_read_status();
0348 unsigned int work = 10000;
0349
0350 while (status & KBD_STAT_OBF) {
0351 unsigned char scancode;
0352
0353 scancode = kbd_read_input();
0354 if (status & KBD_STAT_MOUSE_OBF) {
0355 #if 0
0356 handle_mouse_event(scancode);
0357 #endif
0358 } else {
0359 if (do_acknowledge(scancode))
0360 handle_scancode(scancode, !(scancode & 0x80));
0361 mark_bh(KEYBOARD_BH);
0362 }
0363
0364 status = kbd_read_status();
0365
0366 if(!work--)
0367 {
0368 printk( "pc_keyb: controller jammed (0x%02X).\n", status);
0369 break;
0370 }
0371 return status;
0372 }
0373
0374
0375
0376
0377
0378
0379 acknowledge = 1;
0380 reply_expected = 0;
0381 resend = 0;
0382 return status;
0383 }
0384
0385 void keyboard_interrupt(void *unused)
0386 {
0387 handle_kbd_event();
0388 }
0389
0390
0391
0392
0393
0394
0395
0396
0397 static int send_data(unsigned char data)
0398 {
0399 int retries = 3;
0400
0401 do {
0402 unsigned long timeout = KBD_TIMEOUT;
0403
0404 acknowledge = 0;
0405 resend = 0;
0406 reply_expected = 1;
0407 kbd_write_output_w(data);
0408 for (;;) {
0409 if (acknowledge)
0410 return 1;
0411 if (resend)
0412 break;
0413 mdelay(1);
0414 if (!--timeout) {
0415 #ifdef KBD_REPORT_TIMEOUTS
0416 printk("Keyboard timeout[2]\n");
0417 #endif
0418 return 0;
0419 }
0420 }
0421 } while (retries-- > 0);
0422 #ifdef KBD_REPORT_TIMEOUTS
0423 printk( "keyboard: Too many NACKs -- noisy kbd cable?\n");
0424 #endif
0425 return 0;
0426 }
0427
0428 void pckbd_leds(unsigned char leds)
0429 {
0430 if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
0431 send_data(KBD_CMD_ENABLE);
0432 }
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443 #ifdef __i386__
0444 int kbd_startup_reset = 0;
0445 #else
0446 int kbd_startup_reset = 1;
0447 #endif
0448
0449
0450 void kbd_reset_setup(char *str, int *ints)
0451 {
0452 kbd_startup_reset = 1;
0453 }
0454
0455 #define KBD_NO_DATA (-1)
0456 #define KBD_BAD_DATA (-2)
0457
0458 static int kbd_read_data(void)
0459 {
0460 int retval = KBD_NO_DATA;
0461 unsigned char status;
0462
0463 status = kbd_read_status();
0464 if (status & KBD_STAT_OBF) {
0465 unsigned char data = kbd_read_input();
0466
0467 retval = data;
0468 if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
0469 retval = KBD_BAD_DATA;
0470 }
0471 return retval;
0472 }
0473
0474 static void kbd_clear_input(void)
0475 {
0476 int maxread = 100;
0477
0478 do {
0479 if (kbd_read_data() == KBD_NO_DATA)
0480 break;
0481 } while (--maxread);
0482 }
0483
0484 static int kbd_wait_for_input(void)
0485 {
0486 long timeout = KBD_INIT_TIMEOUT;
0487
0488 do {
0489 int retval = kbd_read_data();
0490 if (retval >= 0)
0491 return retval;
0492 mdelay(1);
0493 } while (--timeout);
0494 return -1;
0495 }
0496
0497 static void kbd_write_command_w(int data)
0498 {
0499 kb_wait();
0500 kbd_write_command(data);
0501 }
0502
0503 static void kbd_write_output_w(int data)
0504 {
0505 kb_wait();
0506 kbd_write_output(data);
0507 }
0508
0509 static char * initialize_kbd(void)
0510 {
0511 int status;
0512
0513
0514
0515
0516
0517
0518 kbd_write_command_w(KBD_CCMD_SELF_TEST);
0519 if (kbd_wait_for_input() != 0x55)
0520 return "Keyboard failed self test";
0521
0522
0523
0524
0525
0526
0527 kbd_write_command_w(KBD_CCMD_KBD_TEST);
0528 if (kbd_wait_for_input() != 0x00)
0529 return "Keyboard interface failed self test";
0530
0531
0532
0533
0534 kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544 do {
0545 kbd_write_output_w(KBD_CMD_RESET);
0546 status = kbd_wait_for_input();
0547 if (status == KBD_REPLY_ACK)
0548 break;
0549 if (status != KBD_REPLY_RESEND)
0550 return "Keyboard reset failed, no ACK";
0551 } while (1);
0552
0553 if (kbd_wait_for_input() != KBD_REPLY_POR)
0554 return "Keyboard reset failed, no POR";
0555
0556
0557
0558
0559
0560
0561
0562 do {
0563 kbd_write_output_w(KBD_CMD_DISABLE);
0564 status = kbd_wait_for_input();
0565 if (status == KBD_REPLY_ACK)
0566 break;
0567 if (status != KBD_REPLY_RESEND)
0568 return "Disable keyboard: no ACK";
0569 } while (1);
0570
0571 kbd_write_command_w(KBD_CCMD_WRITE_MODE);
0572 kbd_write_output_w(KBD_MODE_KBD_INT
0573 | KBD_MODE_SYS
0574 | KBD_MODE_DISABLE_MOUSE
0575 | KBD_MODE_KCC);
0576
0577
0578 kbd_write_command_w(KBD_CCMD_READ_MODE);
0579 if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
0580
0581
0582
0583
0584 kbd_write_output_w(0xF0);
0585 kbd_wait_for_input();
0586 kbd_write_output_w(0x01);
0587 kbd_wait_for_input();
0588 }
0589
0590 kbd_write_output_w(KBD_CMD_ENABLE);
0591 if (kbd_wait_for_input() != KBD_REPLY_ACK)
0592 return "Enable keyboard: no ACK";
0593
0594
0595
0596 kbd_write_output_w(KBD_CMD_SET_RATE);
0597 if (kbd_wait_for_input() != KBD_REPLY_ACK)
0598 return "Set rate: no ACK";
0599 kbd_write_output_w(0x00);
0600 if (kbd_wait_for_input() != KBD_REPLY_ACK)
0601 return "Set rate: no ACK";
0602 return NULL;
0603 }
0604
0605 void pckbd_init_hw(void)
0606 {
0607
0608
0609
0610 kbd_clear_input();
0611
0612 if (kbd_startup_reset) {
0613 char *msg = initialize_kbd();
0614 if (msg)
0615 printk( "initialize_kbd: %s\n", msg);
0616 }
0617
0618 #if defined CONFIG_PSMOUSE
0619 psaux_init();
0620 #endif
0621
0622
0623 #if 0
0624 kbd_request_irq( keyboard_interrupt );
0625 #endif
0626
0627 }