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

4.104.114.84.95
Last change on this file since 0c04c377 was 0c04c377, checked in by Joel Sherrill <joel.sherrill@…>, on 02/18/99 at 16:48:14

./clock/Makefile.in,v
./clock/clock.c,v
./console/Makefile.in,v
./console/config.c,v
./console/console.c,v
./console/console.h,v
./console/debugio.c,v
./console/i8042.c,v
./console/i8042_p.h,v
./console/i8042vga.c,v
./console/i8042vga.h,v
./console/ns16550.c,v
./console/ns16550.h,v
./console/ns16550_p.h,v
./console/ns16550cfg.c,v
./console/ns16550cfg.h,v
./console/vga.c,v
./console/vga_p.h,v
./console/z85c30.c,v
./console/z85c30.h,v
./console/z85c30_p.h,v
./console/z85c30cfg.c,v
./console/z85c30cfg.h,v
./include/Makefile.in,v
./include/bsp.h,v
./include/chain.h,v
./include/coverhd.h,v
./include/extisrdrv.h,v
./include/nvram.h,v
./include/pci.h,v
./include/tod.h,v
./network/Makefile.in,v
./network/amd79c970.c,v
./network/amd79c970.h,v
./nvram/Makefile.in,v
./nvram/ds1385.h,v
./nvram/mk48t18.h,v
./nvram/nvram.c,v
./nvram/prepnvr.h,v
./nvram/stk11c68.h,v
./pci/Makefile.in,v
./pci/pci.c,v
./start/Makefile.in,v
./start/start.s,v
./startup/Makefile.in,v
./startup/bspclean.c,v
./startup/bspstart.c,v
./startup/bsptrap.s,v
./startup/device-tree,v
./startup/genpvec.c,v
./startup/linkcmds,v
./startup/rtems-ctor.cc,v
./startup/sbrk.c,v
./startup/setvec.c,v
./startup/spurious.c,v
./startup/swap.c,v
./timer/Makefile.in,v
./timer/timer.c,v
./tod/Makefile.in,v
./tod/cmos.h,v
./tod/tod.c,v
./universe/Makefile.in,v
./universe/universe.c,v
./vectors/Makefile.in,v
./vectors/README,v
./vectors/align_h.s,v
./vectors/vectors.s,v
./wrapup/Makefile.in,v
./Makefile.in,v
./README,v
./STATUS,v
./bsp_specs,v

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