source: rtems/c/src/lib/libbsp/powerpc/ppcn_60x/console/i8042.c @ 0505504

4.104.114.84.95
Last change on this file since 0505504 was 0505504, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/01/04 at 10:11:00

2004-04-01 Ralf Corsepius <ralf_corsepius@…>

  • startup/genpvec.c: Include <rtems/chain.h> instead of <chain.h>.
  • include/bsp.h: Include <rtems/clockdrv.h> instead of <clockdrv.h>.
  • include/bsp.h: Include <rtems/console.h> instead of <console.h>.
  • include/bsp.h: Include <rtems/iosupp.h> instead of <iosupp.h>.
  • console/i8042.c: Include <rtems/ringbuf.h> instead of <ringbuf.h>.
  • console/console.h: Include <rtems/ringbuf.h> instead of <ringbuf.h>.
  • Property mode set to 100644
File size: 17.1 KB
RevLine 
[0c04c377]1/*
2 *  This file contains the PS2 keyboard driver for the i8042
3 *
4 *  Note that this driver will only handle a single i8042 device
5 *
6 *  COPYRIGHT (c) 1998 by Radstone Technology
7 *
8 *
9 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
10 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
11 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
12 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
13 *
14 * You are hereby granted permission to use, copy, modify, and distribute
15 * this file, provided that this notice, plus the above copyright notice
16 * and disclaimer, appears in all copies. Radstone Technology will provide
17 * no support for this code.
18 *
19 *  This driver uses the termios pseudo driver.
20 *
21 *  $Id$
22 */
23
24#include <rtems.h>
25#include <bsp.h>
26#include <rtems/libio.h>
[d55af6d]27#include <libchip/serial.h>
[0505504]28#include <rtems/ringbuf.h>
[0c04c377]29
30#include "console.h"
31#include "i8042_p.h"
32#include "vga_p.h"
33
34/*
35 * UK style keyboard
36 */
37char pcUKNormalLookup[] = "1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;\'"
38                          "`\0#zxcvbnm,./\0*\0 \0\0\0\0\0\0\0\0\0\0\0\0"
39                          "\000789-456+1230.\0\0\\";
40char pcUKShiftedLookup[]= "!\"£$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:"
41                          "@\0\0~ZXCVBNM<>?\0*\0 \0\0\0\0\0\0\0\0\0\0\0"
42                          "\0\000789-456+1230.\0\0|";
43/*
44 * US style keyboard
45 */
46char pcUSNormalLookup[] = "1234567890-=\b\tqwertyuiop[]\n\0asdfghjkl;\'"
47                          "`\0\\zxcvbnm,./\0*\0 \0\0\0\0\0\0\0\0\0\0\0"
48                          "\0\000789-456+1230.\0\0\\";
49char pcUSShiftedLookup[]= "!@#$%^&*()_+\b\tQWERTYUIOP{}\n\0ASDFGHJKL:@~"
50                          "\0|ZXCVBNM<>?\0*\0 \0\0\0\0\0\0\0\0\0\0\0\0"
51                          "\000789-456+1230.\0\0|";
52
53static char *pcNormalLookup;
54static char *pcShiftedLookup;
55
56/*
57 * This is exported to vga.c to provide flow control
58 */
59volatile boolean bScrollLock=FALSE;
60
61/*
62 * If multiple devices are to be supported then a private copy of
63 * the following will be required for each instance
64 */
65static boolean bCtrlPressed=FALSE;
66static boolean bAltPressed=FALSE;
67static boolean bAltGrPressed=FALSE;
68static boolean bLShiftPressed=FALSE;
69static boolean bRShiftPressed=FALSE;
70static boolean bCapsLock=FALSE;
71static boolean bNumLock=FALSE;
72static boolean bTwoCode=FALSE;
73
74#if CONSOLE_USE_INTERRUPTS
75static volatile Ring_buffer_t KbdOutputBuffer;
76static volatile boolean bProcessInterruptInput=FALSE;
77static boolean bInterruptsEnabled=FALSE;
78static volatile boolean bReceivedAck=TRUE;
79
80static void i8042_process(
81        int minor
82);
83
84static void i8042_scan_code(
85        int minor,
[bad8092c]86        uint8_t     ucScan
[0c04c377]87);
88#endif
89
90static volatile Ring_buffer_t KbdInputBuffer;
91
92/*
93 * The following routines enable an interrupt driver to switch
94 * to polled mode as required for command processing
95 */
96void i8042_polled_on(
97        int minor
98)
99{
100#if CONSOLE_USE_INTERRUPTS
101        bProcessInterruptInput=FALSE;
102#endif
103}
104
105void i8042_polled_off(
106        int minor
107)
108{
109#if CONSOLE_USE_INTERRUPTS
[bad8092c]110        uint32_t        Irql;
111        uint8_t         ucScan;
[0c04c377]112
113        /*
114         * Make sure we have processed everything outstanding
115         */
116        rtems_interrupt_disable(Irql);
117        while(!Ring_buffer_Is_empty(&KbdInputBuffer))
118        {
119                rtems_interrupt_enable(Irql);
120                Ring_buffer_Remove_character(&KbdInputBuffer,
121                                             ucScan);
122                i8042_scan_code(minor, ucScan);
123                rtems_interrupt_disable(Irql);
124        }
125        bProcessInterruptInput=TRUE;
126        rtems_interrupt_enable(Irql);
127#endif
128}
129
130/*
131 * Send data to the keyboard
132 */
133static rtems_status_code
134i8042_outbyte_raw(
135        int minor,
[bad8092c]136        uint8_t   ucData
[0c04c377]137)
138{
[bad8092c]139        uint32_t   i;
140        uint8_t   Status;
[0c04c377]141
142#if CONSOLE_USE_INTERRUPTS
[bad8092c]143        uint32_t        Irql;
[0c04c377]144
145        if(bInterruptsEnabled)
146        {
147                Ring_buffer_Add_character(&KbdOutputBuffer,
148                                          ucData);
149                if(!Console_Port_Data[minor].bActive)
150                {
151                        /*
152                         * Wake up the device
153                         */
154                        rtems_interrupt_disable(Irql);
155                        Console_Port_Data[minor].bActive=TRUE;
156                        i8042_process(minor);
157                        rtems_interrupt_enable(Irql);
158
159                }
160                return RTEMS_SUCCESSFUL;
161        }
162#endif
163        for (i=0; i<KBD_TIMEOUT; i++)
164        {
165                inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
166                if((Status & KBD_IBF_MASK)==0)
167                {
168                        outport_byte(Console_Port_Tbl[minor].ulDataPort,
169                                     ucData);
170                        return RTEMS_SUCCESSFUL;
171                }
172        }
173        return RTEMS_TIMEOUT;
174}
175
176/*
177 * Read data from the keyboard
178 */
179static rtems_status_code
180i8042_inbyte_polled(
181        int minor,
[bad8092c]182        uint8_t   *pucData
[0c04c377]183)
184{
[bad8092c]185        uint8_t   Status;
[0c04c377]186
187        inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
188        if(Status & KBD_OBF_MASK)
189        {
190                inport_byte(Console_Port_Tbl[minor].ulDataPort,
191                            *pucData);
192                return RTEMS_SUCCESSFUL;
193        }
194        return RTEMS_TIMEOUT;
195}
196
197/*
198 * Blocking read data from the keyboard
199 */
200static rtems_status_code
201i8042_inbyte_raw(
202        int minor,
[bad8092c]203        uint8_t   *pucData
[0c04c377]204)
205{
206        int i;
207
208#if CONSOLE_USE_INTERRUPTS
209        if(bInterruptsEnabled)
210        {
211                i=0;
212                while(Ring_buffer_Is_empty(&KbdInputBuffer))
213                {
214                        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
215                        if(i++==KBD_TIMEOUT)
216                        {
217                                return RTEMS_TIMEOUT;
218                        }
219                }
220                Ring_buffer_Remove_character(&KbdInputBuffer,
221                                             *pucData);
222        }
223        else
224#endif
225        {
226                for (i=0; i<KBD_TIMEOUT; i++)
227                {
228                        if(i8042_inbyte_polled(minor, pucData)==
229                              RTEMS_SUCCESSFUL)
230                        {
231                                return RTEMS_SUCCESSFUL;
232                        }
233                        /*
234                         * Wait for a character to be recieved
235                         */
236                }
237
238                return RTEMS_TIMEOUT;
239        }
240
241        return RTEMS_SUCCESSFUL;
242}
243
[ae8c709e]244#if CONSOLE_USE_INTERRUPTS
245
[0c04c377]246/*
247 * Send a command to the keyboard controller
248 */
249static rtems_status_code
250i8042_outbyte_cmd_polled(
251        int minor,
[bad8092c]252        uint8_t   ucCommand
[0c04c377]253)
254{
[bad8092c]255        uint32_t   i;
256        uint8_t   Status;
[0c04c377]257
258        /*
259         * This routine may be called when no clock driver is available
260         * so the timeout is dependant on the ISA bus timing used to access
261         * the i8042 which will not vary (much) across platforms.
262         */
263        for (i=0; i<KBD_TIMEOUT; i++)
264        {
265                inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
266                if((Status & KBD_IBF_MASK)==0)
267                {
268                        outport_byte(Console_Port_Tbl[minor].ulCtrlPort1,
269                                     ucCommand);
270                        return RTEMS_SUCCESSFUL;
271                }
272        }
273        return RTEMS_TIMEOUT;
274}
[ae8c709e]275#endif
[0c04c377]276
277void EnqueueKbdChar(
278        int minor,
279        char cChar
280)
281{
282#if CONSOLE_USE_INTERRUPTS
283        rtems_termios_enqueue_raw_characters(
284                Console_Port_Data[minor].termios_data,
285                &cChar,
286                1);
287#else
288        Ring_buffer_Add_character(&KbdInputBuffer, cChar);
289#endif
290}
291/*
292 * Process second code in a two code sequence
293 */
294static void i8042_process_two_code(
295        int minor,
[bad8092c]296        uint8_t   ucScan,
[0c04c377]297        boolean bMakenBreak
298)
299{
300        char cASCIICtrlCode;
301        char cASCIICode;
302
303        cASCIICtrlCode='\0';
304        cASCIICode='\0';
305
306        switch(ucScan)
307        {
308                case KEY_ALT:
309                {
310                        bAltGrPressed=bMakenBreak;
311                        break;
312                }
313
314                case KEY_CONTROL:
315                {
316                        bCtrlPressed=bMakenBreak;
317                        break;
318                }
319
320                case KEY_INSERT:
321                {
322                        cASCIICtrlCode='@';
323                        break;
324                }
325
326                case KEY_DELETE:
327                {
328                        cASCIICode=ASCII_DEL;
329                        break;
330                }
331
332                case KEY_LEFT_ARROW:
333                {
334                        cASCIICtrlCode='D';
335                        break;
336                }
337
338                case KEY_HOME:
339                {
340                        cASCIICtrlCode='H';
341                        break;
342                }
343
344                case KEY_END:
345                {
346                        cASCIICtrlCode='K';
347                        break;
348                }
349
350                case KEY_UP_ARROW:
351                {
352                        cASCIICtrlCode='A';
353                        break;
354                }
355
356                case KEY_DOWN_ARROW:
357                {
358                        cASCIICtrlCode='B';
359                        break;
360                }
361
362                case KEY_PAGE_UP:
363                {
364                        cASCIICtrlCode='?';
365                        break;
366                }
367
368                case KEY_PAGE_DOWN:
369                {
370                        cASCIICtrlCode='/';
371                        break;
372                }
373
374                case KEY_RIGHT_ARROW:
375                {
376                        cASCIICtrlCode='C';
377                        break;
378                }
379
380                case KEY_KEYPAD_SLASH:
381                {
382                        cASCIICode='/';
383                        break;
384                }
385
386                case KEY_KEYPAD_ENTER:
387                {
388                        cASCIICode=ASCII_CR;
389                        break;
390                }
391
392                case KEY_PRINT_SCREEN:
393                {
394                        cASCIICode=ASCII_SYSRQ;
395                        break;
396                }
397
398                default:
399                {
400                        /*
401                         * Ignore this code
402                         */
403                        break;
404                }
405        }
406
407        if(bMakenBreak && cASCIICode)
408        {
409                EnqueueKbdChar(minor, cASCIICode);
410        }
411        else if(bMakenBreak && cASCIICtrlCode)
412        {
413                EnqueueKbdChar(minor, ASCII_CSI);
414                EnqueueKbdChar(minor, cASCIICtrlCode);
415        }
416}
417
418static boolean i8042_process_qualifiers(
[bad8092c]419        uint8_t   ucScan,
[0c04c377]420        boolean bMakenBreak
421)
422{
423        boolean bProcessed;
424
425        /*
426         * Check for scan codes for shift, control, or alt keys.
427         */
428        bProcessed=TRUE;
429
430        switch (ucScan)
431        {
432                case KEY_LEFT_SHIFT:
433                {
434                        bLShiftPressed=bMakenBreak;
435                        break;
436                }
437
438                case KEY_RIGHT_SHIFT:
439                {
440                        bRShiftPressed=bMakenBreak;
441                        break;
442                }
443
444                case KEY_CONTROL:
445                {
446                        bCtrlPressed=bMakenBreak;
447                        break;
448                }
449
450                case KEY_ALT:
451                {
452                        bAltPressed=bMakenBreak;
453                        break;
454                }
455
456                default:
457                {
458                        /*
459                         * Something else needs to process this code
460                         */
461                        bProcessed=FALSE;
462                        break;
463                }
464        }
465
466        return(bProcessed);
467}
468
469static boolean i8042_process_top_row(
470        int             minor,
[bad8092c]471        uint8_t         ucScan
[0c04c377]472)
473{
474        boolean bProcessed;
475        char    cASCIIFnCode;
476#if CONSOLE_USE_INTERRUPTS==0
[bad8092c]477        uint8_t         ucKeyboardAck;
[0c04c377]478#endif
479
480        /*
481         * Check for keys on the top row
482         */
483        bProcessed=TRUE;
484        cASCIIFnCode='\0';
485
486        switch (ucScan)
487        {
488                case KEY_ESC:
489                {
490                        EnqueueKbdChar(minor, ASCII_ESC);
491                        break;
492                }
493
494                case KEY_F1:
495                {
496                        cASCIIFnCode='P';
497                        break;
498                }
499
500                case KEY_F2:
501                {
502                        cASCIIFnCode='Q';
503                        break;
504                }
505
506                case KEY_F3:
507                {
508                        cASCIIFnCode='w';
509                        break;
510                }
511
512                case KEY_F4:
513                {
514                        cASCIIFnCode='x';
515                        break;
516                }
517
518                case KEY_F5:
519                {
520                        cASCIIFnCode='t';
521                        break;
522                }
523
524                case KEY_F6:
525                {
526                        cASCIIFnCode='u';
527                        break;
528                }
529
530                case KEY_F7:
531                {
532                        cASCIIFnCode='q';
533                        break;
534                }
535
536                case KEY_F8:
537                {
538                        cASCIIFnCode='r';
539                        break;
540                }
541
542                case KEY_F9:
543                {
544                        cASCIIFnCode='p';
545                        break;
546                }
547
548                case KEY_F10:
549                {
550                        cASCIIFnCode='M';
551                        break;
552                }
553
554                case KEY_F11:
555                {
556                        cASCIIFnCode='A';
557                        break;
558                }
559
560                case KEY_F12:
561                {
562                        cASCIIFnCode='B';
563                        break;
564                }
565
566                case KEY_SYS_REQUEST:
567                {
568                        EnqueueKbdChar(minor, ASCII_SYSRQ);
569                        break;
570                }
571
572                case KEY_CAPS_LOCK:
573                case KEY_NUM_LOCK:
574                case KEY_SCROLL_LOCK:
575                {
576                        switch(ucScan)
577                        {
578                                case KEY_CAPS_LOCK:
579                                {
580                                        bCapsLock=!bCapsLock;
581                                        break;
582                                }
583
584                                case KEY_NUM_LOCK:
585                                {
586                                        bNumLock=!bNumLock;
587                                        break;
588                                }
589
590                                case KEY_SCROLL_LOCK:
591                                {
592#if CONSOLE_USE_INTERRUPTS
593                                        bScrollLock=!bScrollLock;
594#endif
595                                        break;
596                                }
597                        }
598
599                        i8042_outbyte_raw(minor, KBD_CMD_SET_LEDS);
600#if CONSOLE_USE_INTERRUPTS==0
601                        i8042_inbyte_raw(minor, &ucKeyboardAck);
602#endif
603                        i8042_outbyte_raw(minor,
604                                          (bCapsLock ? KBD_LED_CAPS : 0) |
605                                          (bNumLock ? KBD_LED_NUM : 0) |
606                                          (bScrollLock ? KBD_LED_SCROLL : 0));
607#if CONSOLE_USE_INTERRUPTS==0
608                        i8042_inbyte_raw(minor, &ucKeyboardAck);
609#endif
610
611                        break;
612                }
613
614                default:
615                {
616                        /*
617                         * Something else needs to process this code
618                         */
619                        bProcessed=FALSE;
620                        break;
621                }
622        }
623
624        if(cASCIIFnCode)
625        {
626                EnqueueKbdChar(minor, ASCII_CSI);
627                EnqueueKbdChar(minor, 'O');
628                EnqueueKbdChar(minor, cASCIIFnCode);
629        }
630
631        return(bProcessed);
632}
633
634static boolean i8042_process_keypad(
635        int     minor,
[bad8092c]636        uint8_t   ucScan
[0c04c377]637)
638{
639        char cASCIICtrlCode;
640
641        /*
642         * Process keys on the keypad
643         */
644        cASCIICtrlCode='\0';
645
646        switch(ucScan)
647        {
648                case KEY_UP_ARROW:
649                {
650                        cASCIICtrlCode='A';
651                        break;
652                }
653
654                case KEY_DOWN_ARROW:
655                {
656                        cASCIICtrlCode='B';
657                        break;
658                }
659
660                case KEY_RIGHT_ARROW:
661                {
662                        cASCIICtrlCode='C';
663                        break;
664                }
665
666                case KEY_LEFT_ARROW:
667                {
668                        cASCIICtrlCode='D';
669                        break;
670                }
671
672                case KEY_HOME:
673                {
674                        cASCIICtrlCode='H';
675                        break;
676                }
677
678                case KEY_END:
679                {
680                        cASCIICtrlCode='K';
681                        break;
682                }
683
684                case KEY_PAGE_UP:
685                {
686                        cASCIICtrlCode='?';
687                        break;
688                }
689
690                case KEY_PAGE_DOWN:
691                {
692                        cASCIICtrlCode='/';
693                        break;
694                }
695
696                case KEY_INSERT:
697                {
698                        cASCIICtrlCode='@';
699                        break;
700                }
701
702                case KEY_DELETE:
703                {
704                        /*
705                         * This is a special case not requiring an ASCII_CSI
706                         */
707                        EnqueueKbdChar(minor, ASCII_DEL);
708                        return(TRUE);
709                }
710
711                default:
712                {
713                        /*
714                         * Something else needs to process this code
715                         */
716                        break;
717                }
718        }
719
720        if(cASCIICtrlCode)
721        {
722                EnqueueKbdChar(minor, ASCII_CSI);
723                EnqueueKbdChar(minor, cASCIICtrlCode);
724                return(TRUE);
725        }
726        else
727        {
728                return(FALSE);
729        }
730}
731
732/*
733 * This routine translates the keyboard scan code into an
734 * ASCII character (or sequence) and queues it
735 */
736static void i8042_scan_code(
737        int minor,
[bad8092c]738        uint8_t     ucScan
[0c04c377]739)
740{
741        char cChar;
742        boolean bMakenBreak;
743
744        /*
745         * Check for code 0xe0, which introduces a two key sequence.
746         */
747
748        if(ucScan==KEY_TWO_KEY)
749        {
750                bTwoCode=TRUE;
751                return;
752        }
753
754        /*
755         * Bit 7 of scan code indicates make or break
756         */
757        if(ucScan & 0x80)
758        {
759                bMakenBreak=FALSE;
760                ucScan&=0x7f;
761        }
762        else
763        {
764                bMakenBreak=TRUE;
765        }
766
767        /*
768         * If we are in a multikey sequence then process the second keypress
769         */
770        if(bTwoCode)
771        {
772                i8042_process_two_code(minor, ucScan, bMakenBreak);
773
774                /*
775                 * Revert to prcessing single key sequences
776                 */
777                bTwoCode=FALSE;
778                return;
779        }
780
781        if(i8042_process_qualifiers(ucScan, bMakenBreak))
782        {
783                /*
784                 * We are all done
785                 */
786                return;
787        }
788
789        /*
790         * The remaining keys are only processed for make
791         */
792        if(!bMakenBreak)
793        {
794                return;
795        }
796
797        if(i8042_process_top_row(minor, ucScan))
798        {
799                /*
800                 * We are all done
801                 */
802                return;
803        }
804
805        if(!bNumLock && i8042_process_keypad(minor, ucScan))
806        {
807                /*
808                 * We are all done
809                 */
810                return;
811        }
812
813        /*
814         * Process "normal" keys
815         */
816
817        cChar=0;
818
819        /*
820         * Check to see if the scan code corresponds to an ASCII
821         * character.
822         */
823        if(((ucScan >= 16) && (ucScan <= 25)) ||
824           ((ucScan >= 30) && (ucScan <= 38)) ||
825           ((ucScan >= 44) && (ucScan <= 50)))
826        {
827                if(bCtrlPressed)
828                {
829                        cChar=pcNormalLookup[ucScan - 2]-'a'+1;
830                }
831                else
832                {
833                        if(((bLShiftPressed || bRShiftPressed) && !bCapsLock) ||
834                           (!(bLShiftPressed || bRShiftPressed) && bCapsLock))
835                        {
836                                cChar=pcShiftedLookup[ucScan - 2];
837                        }
838                        else
839                        {
840                                cChar=pcNormalLookup[ucScan - 2];
841                        }
842                }
843        }
844        else if((ucScan > 1) && (ucScan <= 0x56))
845        {
846                /*
847                 * Its ASCII but not alpha, so don't shift on CapsLock.
848                 */
849                if(bLShiftPressed || bRShiftPressed)
850                {
851                        cChar=pcShiftedLookup[ucScan - 2];
852                }
853                else
854                {
855                        cChar=pcNormalLookup[ucScan - 2];
856                }
857        }
858
859        /*
860         * If we got a character then queue it
861         */
862        if(cChar)
863        {
864                EnqueueKbdChar(minor, cChar);
865        }
866}
867
868/*
869 *  Console Device Driver Entry Points
870 */
871boolean i8042_probe(int minor)
872{
[bad8092c]873        uint8_t   ucKeyboardAck;
874        uint8_t   ucKeyboardID1, ucKeyboardID2;
[0c04c377]875
876        if(!vga_probe(minor))
877        {
878                /*
879                 * There is no VGA adaptor so fail probe
880                 */
881                return(FALSE);
882        }
883
884        Ring_buffer_Initialize(&KbdInputBuffer);
885#if CONSOLE_USE_INTERRUPTS
886        Ring_buffer_Initialize(&KbdOutputBuffer);
887#endif
888
889        i8042_polled_on(minor);
890        /*
891         * Determine keyboard type
892         */
893        i8042_outbyte_raw(minor, KBD_CMD_READ_ID);
894        ucKeyboardAck=0;
895        if((i8042_inbyte_raw(minor, &ucKeyboardAck)==RTEMS_TIMEOUT) ||
896           (ucKeyboardAck==KBD_CMD_RESEND))
897        {
898                /*
899                 * No or incorrect keyboard response so fail probe
900                 */
901                return(FALSE);
902        }
903
904        i8042_inbyte_raw(minor, &ucKeyboardID1);
905        i8042_inbyte_raw(minor, &ucKeyboardID2);
906        if((ucKeyboardID1==0xab) && (ucKeyboardID2==0x41))
907        {
908                pcNormalLookup=&pcUKNormalLookup[0];
909                pcShiftedLookup=&pcUKShiftedLookup[0];
910        }
911        else
912        {
913                pcNormalLookup=&pcUSNormalLookup[0];
914                pcShiftedLookup=&pcUSShiftedLookup[0];
915        }
916        i8042_polled_off(minor);
917
918        return(TRUE);
919}
920
921void i8042_init(int minor)
922{
[bad8092c]923        uint8_t   ucKeyboardAck;
[0c04c377]924
925        vga_init(minor);
926
927        i8042_polled_on(minor);
928        /*
929         * Switch all LEDs off
930         */
931        i8042_outbyte_raw(minor, KBD_CMD_SET_LEDS);
932        i8042_inbyte_raw(minor, &ucKeyboardAck);
933        i8042_outbyte_raw(minor, 0);
934        i8042_inbyte_raw(minor, &ucKeyboardAck);
935        /*
936         * Select scan code set 1
937         */
938        i8042_outbyte_raw(minor, KBD_CMD_SEL_SCAN_CODE);
939        i8042_inbyte_raw(minor, &ucKeyboardAck);
940        i8042_outbyte_raw(minor, 1);
941        i8042_inbyte_raw(minor, &ucKeyboardAck);
942        i8042_polled_off(minor);
943}
944
945/* PAGE
946 *
947 *  i8042_inbyte_nonblocking_polled
948 *
949 *  Console Termios polling input entry point.
950 */
951
952int i8042_inbyte_nonblocking_polled(
953        int minor
954)
955{
[bad8092c]956        uint8_t         ucScan;
[0c04c377]957        char    ucData;
958
959        if(i8042_inbyte_polled(minor, &ucScan)==RTEMS_SUCCESSFUL)
960        {
961                i8042_scan_code(minor, ucScan);
962        }
963
964        if(!Ring_buffer_Is_empty(&KbdInputBuffer))
965        {
966                Ring_buffer_Remove_character(&KbdInputBuffer,
967                                             ucData);
968                return(ucData);
969        }
970
971        return(-1);
972}
973
974#if CONSOLE_USE_INTERRUPTS
975/*
976 *  i8042_isr
977 *
978 *  This routine is the console interrupt handler for the keyboard
979 *
980 *  Input parameters:
981 *    vector - vector number
982 *
983 *  Output parameters: NONE
984 *
985 *  Return values:     NONE
986 */
987static void i8042_process(
988        int     minor
989)
990{
[bad8092c]991        uint8_t         Status;
992        uint8_t         ucData;
[0c04c377]993
994        inport_byte(Console_Port_Tbl[minor].ulCtrlPort1, Status);
995
996        if(Status & KBD_OBF_MASK)
997        {
998                inport_byte(Console_Port_Tbl[minor].ulDataPort, ucData);
999
1000                if(bProcessInterruptInput)
1001                {
1002                        /*
1003                         * Every byte written to the keyboard should be followed
1004                         * by an acknowledge
1005                         */
1006                        if(ucData==KBD_CMD_ACK)
1007                        {
1008                                bReceivedAck=TRUE;
1009                        }
1010                        else
1011                        {
1012                                i8042_scan_code(minor, ucData);
1013                        }
1014                }
1015                else
1016                {
1017                        /*
1018                         * Store the scan code into the ring buffer where it
1019                         * can be read using i8042_inbyte_raw()
1020                         */
1021                        Ring_buffer_Add_character(&KbdInputBuffer, ucData);
1022                }
1023        }
1024
1025        if(((Status & KBD_IBF_MASK)==0) &&
1026           bReceivedAck)
1027        {
1028                if(Ring_buffer_Is_empty(&KbdOutputBuffer))
1029                {
1030                        Console_Port_Data[minor].bActive=FALSE;
1031                }
1032                else
1033                {
1034                        Ring_buffer_Remove_character(&KbdOutputBuffer,
1035                                                     ucData);
1036                        outport_byte(Console_Port_Tbl[minor].ulDataPort,
1037                                     ucData);
1038                        bReceivedAck=FALSE;
1039                }
1040        }
1041}
1042
1043static rtems_isr i8042_isr(
1044  rtems_vector_number vector
1045)
1046{
1047        int     minor;
1048
1049        for(minor=0;minor<Console_Port_Count;minor++)
1050        {
1051                if(vector==Console_Port_Tbl[minor].ulIntVector)
1052                {
1053                        i8042_process(minor);
1054                }
1055        }
1056}
1057
1058void i8042_initialize_interrupts(int minor)
1059{
1060        i8042_init(minor);
1061
1062        Console_Port_Data[minor].bActive=FALSE;
1063
1064        set_vector(i8042_isr,
1065                   Console_Port_Tbl[minor].ulIntVector,
1066                   1);
1067
1068        i8042_outbyte_cmd_polled(minor, KBD_CTR_WRITE_COMMAND);
1069        i8042_outbyte_raw(minor, KBD_CMD_ENABLE_KBD_INT);
1070
1071        /*
1072         * At this point interrupts should spring into life
1073         */
1074        bInterruptsEnabled=TRUE;
1075}
1076
1077#endif /* CONSOLE_USE_INTERRUPTS */
Note: See TracBrowser for help on using the repository browser.