Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:41

0001 /*
0002  * linux/drivers/char/pc_keyb.c
0003  *
0004  * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
0005  * See keyboard.c for the whole history.
0006  *
0007  * Major cleanup by Martin Mares, May 1997
0008  *
0009  * Combined the keyboard and PS/2 mouse handling into one file,
0010  * because they share the same hardware.
0011  * Johan Myreen <jem@iki.fi> 1998-10-08.
0012  *
0013  * Code fixes to handle mouse ACKs properly.
0014  * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
0015  *
0016  * Ported to RTEMS by Rosimildo da Silva
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 /* Some configuration switches are present in the include file... */
0032 
0033 /* Simple translation table for the SysRq keys */
0034 
0035 #ifdef CONFIG_MAGIC_SYSRQ
0036 unsigned char pckbd_sysrq_xlate[128] =
0037     "\000\0331234567890-=\177\t"            /* 0x00 - 0x0f */
0038     "qwertyuiop[]\r\000as"              /* 0x10 - 0x1f */
0039     "dfghjkl;'`\000\\zxcv"              /* 0x20 - 0x2f */
0040     "bnm,./\000*\000 \000\201\202\203\204\205"  /* 0x30 - 0x3f */
0041     "\206\207\210\211\212\000\000789-456+1"     /* 0x40 - 0x4f */
0042     "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
0043     "\r\000/";                  /* 0x60 - 0x6f */
0044 #endif
0045 
0046 /* used only by send_data - set by keyboard_interrupt */
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  * Translation of escaped scancodes to keycodes.
0053  * This is now user-settable.
0054  * The keycodes 1-88,96-111,119 are fairly standard, and
0055  * should probably not be changed - changing might confuse X.
0056  * X also interprets scancode 0x5d (KEY_Begin).
0057  *
0058  * For 1-88 keycode equals scancode.
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  /* (control-pause) */
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  * The keycodes below are randomly located in 89-95,112-118,120-127.
0082  * They could be thrown away (and all occurrences below replaced by 0),
0083  * but that would force many users to use the `setkeycodes' utility, where
0084  * they needed not before. It does not matter that there are duplicates, as
0085  * long as no duplication occurs for any single keyboard.
0086  */
0087 #define SC_LIM 89
0088 
0089 #define FOCUS_PF1 85           /* actual code! */
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 /* tfj@olivia.ping.dk:
0104  * The four keys are located over the numeric keypad, and are
0105  * labelled A1-A4. It's an rc930 keyboard, from
0106  * Regnecentralen/RC International, Now ICL.
0107  * Scancodes: 59, 5a, 5b, 5c.
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,                   /* 0x59-0x5f */
0116   0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
0117   0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
0118   0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
0119   FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
0120   FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
0121 };
0122 
0123 /* BTC */
0124 #define E0_MACRO   112
0125 /* LK450 */
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  * My OmniKey generates e0 4c for  the "OMNI" key and the
0134  * right alt key does nada. [kkoller@nyx10.cs.du.edu]
0135  */
0136 #define E0_OK   124
0137 /*
0138  * New microsoft keyboard is rumoured to have
0139  * e0 5b (left window button), e0 5c (right window button),
0140  * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
0141  * [or: Windows_L, Windows_R, TaskMan]
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,                 /* 0x00-0x07 */
0149   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x08-0x0f */
0150   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x10-0x17 */
0151   0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,         /* 0x18-0x1f */
0152   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x20-0x27 */
0153   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x28-0x2f */
0154   0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,         /* 0x30-0x37 */
0155   E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,       /* 0x38-0x3f */
0156   E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,       /* 0x40-0x47 */
0157   E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
0158   E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,       /* 0x50-0x57 */
0159   0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,       /* 0x58-0x5f */
0160   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x60-0x67 */
0161   0, 0, 0, 0, 0, 0, 0, E0_MACRO,              /* 0x68-0x6f */
0162   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x70-0x77 */
0163   0, 0, 0, 0, 0, 0, 0, 0                  /* 0x78-0x7f */
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       /* Unfortunately, we must recognise these codes only if we know they
0194        * are known to be valid (i.e., after sending a command), because there
0195        * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
0196        * keys with such codes :(
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         /* Should not happen... */
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     /* special prefix scancodes.. */
0219     if (scancode == 0xe0 || scancode == 0xe1) {
0220         prev_scancode = scancode;
0221         return 0;
0222     }
0223 
0224     /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
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        * usually it will be 0xe0, but a Pause key generates
0235        * e1 1d 45 e1 9d c5 when pressed, and nothing when released
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            *  The keyboard maintains its own internal caps lock and
0256            *  num lock statuses. In caps lock mode E0 AA precedes make
0257            *  code and E0 2A follows break code. In num lock mode,
0258            *  E0 2A precedes make code and E0 AA follows break code.
0259            *  We do our own book-keeping, so we will just ignore these.
0260            */
0261           /*
0262            *  For my keyboard there is no caps lock mode, but there are
0263            *  both Shift-L and Shift-R modes. The former mode generates
0264            *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
0265            *  So, we should also ignore the latter. - aeb@cwi.nl
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         /* This happens with the FOCUS 9000 keyboard
0283            Its keys PF1..PF12 are reported to generate
0284            55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
0285            Moreover, unless repeated, they do not generate
0286            key-down events, so we have to zero up_flag below */
0287         /* Also, Japanese 86/106 keyboards are reported to
0288            generate 0x73 and 0x7d for \ - and \ | respectively. */
0289         /* Also, some Brazilian keyboard is reported to produce
0290            0x73 and 0x7e for \ ? and KP-dot, respectively. */
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     /* unexpected, but this can happen: maybe this was a key release for a
0310        FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
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          * "handle_kbd_event()" will handle any incoming events
0324          * while we wait - keypresses or mouse movement.
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  * This reads the keyboard status port, and does the
0340  * appropriate action.
0341  *
0342  * It requires that we hold the keyboard controller
0343  * spinlock.
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     * the commands to set the leds for some reason, returns 0x14, 0x16
0376     * and I am intepreting as an ACK, because the original code from
0377     * Linux was timeing out here...
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  * send_data sends a character to the keyboard and waits
0392  * for an acknowledge, possibly retrying if asked to. Returns
0393  * the success status.
0394  *
0395  * Don't use 'jiffies', so that we don't depend on interrupts
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; /* Set by interrupt routine on receipt of ACK. */
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);  /* re-enable kbd if any errors */
0432 }
0433 
0434 /*
0435  * In case we run on a non-x86 hardware we need to initialize both the
0436  * keyboard controller and the keyboard.  On a x86, the BIOS will
0437  * already have initialized them.
0438  *
0439  * Some x86 BIOSes do not correctly initialize the keyboard, so the
0440  * "kbd-reset" command line options can be given to force a reset.
0441  * [Ranger]
0442  */
0443 #ifdef __i386__
0444  int kbd_startup_reset = 0;
0445 #else
0446  int kbd_startup_reset = 1;
0447 #endif
0448 
0449 /* for "kbd-reset" cmdline param */
0450 void kbd_reset_setup(char *str, int *ints)
0451 {
0452     kbd_startup_reset = 1;
0453 }
0454 
0455 #define KBD_NO_DATA (-1)    /* No data */
0456 #define KBD_BAD_DATA    (-2)    /* Parity or other error */
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;  /* Random number */
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      * Test the keyboard interface.
0515      * This seems to be the only way to get it going.
0516      * If the test is successful a x55 is placed in the input buffer.
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      * Perform a keyboard interface test.  This causes the controller
0524      * to test the keyboard clock and data lines.  The results of the
0525      * test are placed in the input buffer.
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      * Enable the keyboard by allowing the keyboard clock to run.
0533      */
0534     kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
0535 
0536     /*
0537      * Reset keyboard. If the read times out
0538      * then the assumption is that no keyboard is
0539      * plugged into the machine.
0540      * This defaults the keyboard to scan-code set 2.
0541      *
0542      * Set up to try again if the keyboard asks for RESEND.
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      * Set keyboard controller mode. During this, the keyboard should be
0558      * in the disabled state.
0559      *
0560      * Set up to try again if the keyboard asks for RESEND.
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     /* ibm powerpc portables need this to use scan-code set 1 -- Cort */
0578     kbd_write_command_w(KBD_CCMD_READ_MODE);
0579     if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
0580         /*
0581          * If the controller does not support conversion,
0582          * Set the keyboard to scan-code set 1.
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      * Finally, set the typematic rate to maximum.
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     /* kbd_request_region();  */
0608 
0609     /*  Flush any pending input. */
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     /* Ok, finally allocate the IRQ, and off we go.. */
0623 #if 0
0624     kbd_request_irq( keyboard_interrupt );
0625 #endif
0626 
0627 }