i8042KbdMse.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:24k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* i8042KbdMse.c - Intel 8042 keyboard/mouse driver routines */
  2. /* Copyright 1993-2002 Wind River System, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02b,14jun02,gav  Fixed storage class warning from DIAB PPC compiler.
  8. 02a,17may02,rfm  Removed static declaration for i8042KbdStatInit
  9. 01a,06dec01,jlb  created
  10. */
  11. /*
  12. DESCRIPTION
  13. This is the driver for the Intel 8042 Keyboard/Mouse Controller Chip. The
  14. Intel 8042 is the most common device that is used to implement the keyboard
  15. and mouse ports.  Although, this device is no longer available, it is emulated 
  16. by various super I/O chips.  Any device specific needs of these super I/O devices
  17. to enable the keyboard/mouse controller must be handled external to this driver. 
  18. That is, this driver only pertains to the Intel 8042  specifics.  
  19.  
  20. This driver requires that the BSP implement the WindML BSP API (sysWindML.c)
  21. to obtain the device addresses and to enable/disable interrupt handling.
  22. Two devices are created, one for the keyboard and one for the pointer/mouse.
  23. USER-CALLABLE ROUTINES
  24. Most of the routines in this driver are accessible only through the I/O
  25. system.  Two routines, however, must be called directly:  i8042MseDevCreate() to
  26. create the  mouse driver, and i8042KbdDevCreate() to create keyboard device.
  27. IOCTL FUNCTIONS
  28. This driver responds to all the same ioctl() codes as a normal tty driver;
  29. for more information, see the manual entry for tyLib.  In addition, the keyboard
  30. driver has ioctls to control the settings of the LEDs on the keyboard.
  31. NOTES
  32. The keyboard driver must be initialized prior to the initialization of the
  33. mouse port.  The keyboard port may be handled by the pcConsole driver that is
  34. present for the Pentium family of processors.  When the PC Console is included
  35. the keyboard driver present within this file is not built, that is when 
  36. INCLUDE_PC_CONSOLE is defined.
  37. */
  38. /* includes */
  39. #include "vxWorks.h"
  40. #include "iv.h"
  41. #include "ioLib.h"
  42. #include "iosLib.h"
  43. #include "memLib.h"
  44. #include "tyLib.h"
  45. #include "errnoLib.h"
  46. #include "wdLib.h"
  47. #include "sysLib.h"
  48. #include "intLib.h"
  49. #include "taskLib.h"
  50. #include "ugl/sysWindML.h"
  51. #include "drv/serial/i8042.h"
  52. #include "drv/serial/pcConsole.h"
  53. LOCAL int       i8042TimeoutCnt;
  54. LOCAL BOOL      i8042Timeout;
  55. LOCAL WDOG_ID   i8042Wdid;
  56. /* forward declarations */
  57. #ifndef INCLUDE_PC_CONSOLE
  58. LOCAL void      i8042KbdLedSet (I8042_KBD_DEVICE * pKbdDv, UCHAR led);
  59. LOCAL void      i8042KbdReset (I8042_KBD_DEVICE * pKbdDv);
  60. LOCAL int       i8042KbdWriteData (I8042_KBD_DEVICE * pKbdDv);
  61. LOCAL void      i8042KbdInt (I8042_KBD_DEVICE * pKbdDv);
  62. LOCAL int       i8042KbdOpen ();
  63. LOCAL STATUS    i8042KbdIoctl (I8042_KBD_DEVICE * pKbdDv, int request, int arg);
  64. LOCAL void      i8042KbdHrdInit (I8042_KBD_DEVICE * pKbdDv);
  65. #endif /* INCLUDE_PC_CONSOLE */
  66. LOCAL int       i8042MseOpen();
  67. LOCAL int       i8042MseClose();
  68. LOCAL void      i8042MseTxStart();
  69. LOCAL void      i8042MseInt (I8042_MSE_DEVICE  *pDev);
  70. LOCAL void      i8042MseHwInit (I8042_MSE_DEVICE  * pI8042MseDevice);
  71. /*******************************************************************************
  72. *
  73. * i8042MseDevCreate - mouse driver initialization routine
  74. *
  75. * This routine creates a device for a mouse.  The 8042 hardware is
  76. * initialized when the keyboard interface is initialized.  Therefore, the
  77. * keyboard port must be initialized prior to the initialization of the mouse
  78. * port.  This may be done either by the use of the keyboard driver contained
  79. * within this file or by the inclusion of the keyboard driver used by the
  80. * PC Console driver.
  81. *
  82. * RETURNS: device number, if successful; otherwise ERROR.
  83. *
  84. * SEE ALSO:
  85. */
  86. int i8042MseDevCreate
  87.     (
  88.     char         *name            /* name to be associated with device   */
  89.     )
  90.     {
  91.     int                 i8042MseDrvNum;
  92.     I8042_MSE_DEVICE  * pI8042MseDevice;
  93.     /* Install the driver and return installation status */
  94.     i8042MseDrvNum = iosDrvInstall(i8042MseOpen, (FUNCPTR) NULL, i8042MseOpen,
  95.                              (FUNCPTR) i8042MseClose, tyRead, tyWrite, tyIoctl);
  96.     /* Allocate device structure */
  97.     pI8042MseDevice = (I8042_MSE_DEVICE *)malloc (sizeof(I8042_MSE_DEVICE));
  98.     /* Create a tty device  */
  99.     if (tyDevInit(&pI8042MseDevice->ty_dev, 512, 512, (FUNCPTR)i8042MseTxStart) != OK)
  100.         return (ERROR);
  101.      /* Get the device access information */
  102.     pI8042MseDevice->pDev = sysWindMLDevGet(WINDML_POINTER_DEVICE, 0, 0, 0);
  103.     if (pI8042MseDevice->pDev == NULL)
  104.         {
  105.         free (pI8042MseDevice);
  106.         return (ERROR);
  107.         }
  108.     /* Set up register access locations */
  109.     pI8042MseDevice->statCmdReg =  (ULONG)pI8042MseDevice->pDev->pRegBase +
  110.                        ((ULONG)pI8042MseDevice->pDev->regDelta * I8042_STAT_CMD);
  111.     pI8042MseDevice->dataReg =  (ULONG)pI8042MseDevice->pDev->pRegBase +
  112.                        ((ULONG)pI8042MseDevice->pDev->regDelta * I8042_DATA);
  113.     /* Connect the interrupt handler */
  114.     sysWindMLIntConnect(pI8042MseDevice->pDev, i8042MseInt, (int)pI8042MseDevice);
  115.     /* initialize the interface */
  116.     i8042MseHwInit (pI8042MseDevice);
  117.     /* enable the pointer interrupt */
  118.     sysWindMLIntEnable (pI8042MseDevice->pDev);
  119.     /* add the device to the I/O system */
  120.     if (iosDevAdd(&pI8042MseDevice->ty_dev.devHdr,name,i8042MseDrvNum) == ERROR)
  121.         return (ERROR);
  122.     return (i8042MseDrvNum);
  123.     }
  124. /*******************************************************************************
  125. *
  126. * i8042MseOpen - open file
  127. *
  128. * This routine opens the mouse port on the i8042 controller.
  129. *
  130. * RETURNS device structure
  131. *
  132. * SEE ALSO:
  133. */
  134. LOCAL int i8042MseOpen
  135.     (
  136.     I8042_MSE_DEVICE  *dev,       /* device structure */ 
  137.     char        *name,
  138.     int         mode
  139.     )
  140.     {
  141.     return ((int)dev);
  142.     }
  143. /*****************************************************************************
  144. *
  145. *  i8042MseTxStart - send data to mouse
  146. *
  147. * This routine transmits data to the mouse port on the i8042 controller
  148. *
  149. * RETURNS  N/A
  150. *
  151. * SEE ALSO:
  152. */
  153. LOCAL void i8042MseTxStart
  154.     (
  155.     I8042_MSE_DEVICE  *dev
  156.     )
  157.     {
  158.     char          out_char;
  159.     while (tyITx(&dev->ty_dev,&out_char) == OK);
  160.     }
  161. /*****************************************************************************
  162. *
  163. * i8042MseClose - close file
  164. *
  165. *  This routine closes the mouse device
  166. *
  167. * RETURNS N/A
  168. *
  169. * SEE ALSO:
  170. */
  171. LOCAL int i8042MseClose
  172.     (
  173.     I8042_MSE_DEVICE  *dev
  174.     )
  175.     {
  176.     return((int)dev);
  177.     }
  178. /******************************************************************************
  179. *
  180. * i8042Wdog - I8042 driver watchdog handler.
  181. *
  182. * i8042 driver watchdog handler.
  183. *
  184. * RETURNS: N/A
  185. */
  186. LOCAL void i8042Wdog (void)
  187.     {
  188.     i8042Timeout = TRUE;
  189.     i8042TimeoutCnt++;
  190.     }
  191. /******************************************************************************
  192. *
  193. * i8042Read - read data from the i8042 keyboard/mouse controller.
  194. *
  195. * Read data from the i8042 keyboard/mouse controller.
  196. *
  197. * RETURNS: OK or ERROR if timed out
  198. */
  199. LOCAL STATUS i8042Read
  200.     (
  201.     ULONG   statCmdReg,         /* location of the status/command register */
  202.     ULONG   dataReg,            /* location of the data register */
  203.     UCHAR * pData               /* location to return read data */
  204.     )
  205.     {
  206.     /* Start watch dog to monitor device access */
  207.     i8042Timeout = FALSE;
  208.     wdStart (i8042Wdid, (sysClkRateGet() * I8042_WAIT_SEC), (FUNCPTR)i8042Wdog, 0);
  209.     /* Wait for device to become ready */
  210.     while (((I8042_KBD_IN (statCmdReg) & I8042_KBD_OBFULL) == 0) && !i8042Timeout)
  211.         ;
  212.     /* Cancel watch dog and delay for data to move up in device h/w queue */
  213.     wdCancel (i8042Wdid);
  214.     taskDelay (sysClkRateGet () >> 4);
  215.     /* read the character from the device */
  216.     *pData = I8042_KBD_IN (dataReg);
  217.     return (i8042Timeout ? ERROR : OK);
  218.     }
  219. /******************************************************************************
  220. *
  221. * i8042Write - write data to the i8042 keyboard/mouse controller.
  222. *
  223. * Write data to the i8042 keyboard/mouse controller.
  224. *
  225. * RETURNS: OK or ERROR if timed out
  226. */
  227. LOCAL STATUS i8042Write
  228.     (
  229.     ULONG   statCmdReg,       /* location of the status/command register */
  230.     ULONG   dataReg,          /* location of the data register */
  231.     UCHAR   data              /* data to write to data register */
  232.     )
  233.     {
  234.     /* Start watch dog to monitor device access */
  235.     i8042Timeout = FALSE;
  236.     wdStart (i8042Wdid, (sysClkRateGet() * I8042_WAIT_SEC), (FUNCPTR)i8042Wdog, 0);
  237.     /* Wait for device to become ready */
  238.     while ((I8042_KBD_IN (statCmdReg) & I8042_KBD_IBFULL) && !i8042Timeout)
  239.         ;
  240.     /* Cancel watch dog */
  241.     wdCancel (i8042Wdid);
  242.     /* Send data */
  243.     I8042_KBD_OUT (dataReg, data);
  244.     return (i8042Timeout ? ERROR : OK);
  245.     }
  246. /******************************************************************************
  247. *
  248. * i8042Command - write command to the i8042 keyboard/mouse controller.
  249. *
  250. * Write command to the i8042 keyboard/mouse controller.
  251. *
  252. * RETURNS: OK or ERROR if timed out
  253. */
  254. LOCAL STATUS i8042Command
  255.     (
  256.     ULONG   statCmdReg,     /* location of the status/command register */
  257.     UCHAR   command         /* command to write to command register */
  258.     )
  259.     {
  260.         
  261.     /* Start watch dog to monitor device access */
  262.     i8042Timeout = FALSE;
  263.     wdStart (i8042Wdid, (sysClkRateGet() * I8042_WAIT_SEC), (FUNCPTR)i8042Wdog, 0);
  264.     /* Wait for device to become ready */
  265.     while ((I8042_KBD_IN (statCmdReg) & I8042_KBD_IBFULL) && !i8042Timeout)
  266.         ;
  267.     /* Issue command */
  268.     I8042_KBD_OUT (statCmdReg, command);
  269.     /* Wait for command to be completed */
  270.     while ((I8042_KBD_IN (statCmdReg) & I8042_KBD_IBFULL) && !i8042Timeout)
  271.         ;
  272.     /* Cancel watch dog */
  273.     wdCancel (i8042Wdid);
  274.     return (i8042Timeout ? ERROR : OK);
  275.     }
  276. /*******************************************************************************
  277. *
  278. * i8042MseHwInit - initialize the 8042 for mouse support
  279. *
  280. * This routine initializes the 8042 mouse port.
  281. *
  282. * RETURNS N/A
  283. *
  284. * SEE ALSO:
  285. */
  286. LOCAL void i8042MseHwInit 
  287.     (
  288.     I8042_MSE_DEVICE  * pI8042MseDevice
  289.     )
  290.     {
  291.     unsigned char      cond;
  292.     unsigned char      conf;
  293.     /* Disable keyboard */
  294.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_DISABLE);
  295.     /* Get current configuration */
  296.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_RD_CONFIG);
  297.     i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, &conf);
  298.     /* Disable interrupt for keyboard */
  299.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_CONFIG);
  300.     i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, conf & 0xFC);
  301.     /* Enable auxiliary device */
  302.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_ENABLE_AUX);
  303.     /* Check interface to device */
  304.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_IF_AUX_TEST);
  305.     if (i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg,
  306.                     &cond) == ERROR)
  307.         return;
  308.     if (cond != I8042_KBD_IF_OK)
  309.         return;
  310.     /* Set Standard mode for mouse */
  311.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_AUX);
  312.     i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, 
  313.                 I8042_KBDM_SETS_CMD);
  314.     if (i8042Read (pI8042MseDevice->statCmdReg, 
  315.                    pI8042MseDevice->dataReg, &cond) == ERROR)
  316.        return;
  317.     if (cond == I8042_KBDM_ACK)
  318.         {
  319.         /* Enable mouse device */
  320.         i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_AUX);
  321.         i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg,  
  322.                     I8042_KBDM_ENABLE_CMD);
  323.         if (i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg,  
  324.                        &cond) == ERROR)
  325.            return;
  326.         if (cond == I8042_KBDM_ACK)
  327.             conf |= I8042_KBD_AUX_INT;
  328.         else
  329.             return;
  330.         }
  331.     else
  332.         return;
  333.     /* reenable 8042 keyboard with  new configuration */
  334.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_CONFIG);
  335.     i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg,  conf);
  336.     /* Enable keyboard */
  337.     i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_ENABLE);
  338.     return;
  339.     }
  340. /*****************************************************************************
  341. *
  342. * i8042MseInt - handle interrupts
  343. *
  344. * This routine is the mouse port interrupt handler
  345. *
  346. * RETURNS  NA
  347. *
  348. * SEE ALSO:
  349. */
  350. LOCAL void i8042MseInt
  351.     (
  352.     I8042_MSE_DEVICE  *pI8042MseDevice       /* device control structure */
  353.     )
  354.     {
  355.     UCHAR in_char;
  356.     
  357.     /* Check if character is ready */
  358.     if (I8042_KBD_IN (pI8042MseDevice->statCmdReg) & 
  359.         (I8042_KBD_OBFULL | I8042_KBD_AUXB))
  360.         {
  361.         /* Character present, so read it and place in read queue */
  362.         in_char = I8042_KBD_IN (pI8042MseDevice->dataReg);
  363.         tyIRd (&pI8042MseDevice->ty_dev,in_char);
  364.         }
  365.     }
  366. /* If the PC Console is included then the keyboard controller is provided
  367.  * by the PC console device.
  368.  */
  369. #ifndef INCLUDE_PC_CONSOLE       
  370. /******************************************************************************
  371. *
  372. * i8042KbdDevCreate - create a device for the on-board ports
  373. *
  374. * This routine creates a device on one of the pcConsole ports.  Each port
  375. * to be used should have only one device associated with it, by calling
  376. * this routine.
  377. *
  378. * RETURNS: OK, or ERROR if there is no driver or one already exists for the
  379. * specified port.
  380. */
  381. STATUS i8042KbdDevCreate
  382.     (
  383.     char *  name       /* name to use for this device */
  384.     )
  385.     {
  386.     int       i8042KbdDrvNum;               /* driver number  */
  387.     I8042_KBD_DEVICE   *  pI8042KbdDevice;  /* device descriptors */
  388.     /* Allocate and initialize driver control structure */
  389.     pI8042KbdDevice = (I8042_KBD_DEVICE *)malloc (sizeof (I8042_KBD_DEVICE));
  390.     /* Obtain the keyboard access info */
  391.     pI8042KbdDevice->pDev = sysWindMLDevGet (WINDML_KEYBOARD_DEVICE, 0, 0, 0);
  392.     /* Set up register access locations */
  393.     pI8042KbdDevice->statCmdReg =  (ULONG)pI8042KbdDevice->pDev->pRegBase +
  394.                        ((ULONG)pI8042KbdDevice->pDev->regDelta * I8042_STAT_CMD);
  395.     pI8042KbdDevice->dataReg =  (ULONG)pI8042KbdDevice->pDev->pRegBase +
  396.                        ((ULONG)pI8042KbdDevice->pDev->regDelta * I8042_DATA);
  397.     /* Connect the keyboard interrupt */
  398.     sysWindMLIntConnect (pI8042KbdDevice->pDev, i8042KbdInt, (int)pI8042KbdDevice);
  399.     /* initialize the controller */
  400.     i8042KbdHrdInit (pI8042KbdDevice);
  401.     /* Install the driver */
  402.     i8042KbdDrvNum = iosDrvInstall (i8042KbdOpen, (FUNCPTR) NULL, i8042KbdOpen,
  403.                     (FUNCPTR) NULL, tyRead, tyWrite, i8042KbdIoctl);
  404.     if (tyDevInit (&pI8042KbdDevice->tyDev, 20, 10, i8042KbdWriteData)
  405.         != OK)
  406.         return (ERROR);
  407.     /* Enable the keyboard interrupt */
  408.     sysWindMLIntEnable (pI8042KbdDevice->pDev);
  409.     /* add the device to the I/O system */
  410.     if (iosDevAdd (&pI8042KbdDevice->tyDev.devHdr, name, i8042KbdDrvNum) == ERROR)
  411.         return (ERROR);
  412.     return (i8042KbdDrvNum);
  413.     }
  414. /*******************************************************************************
  415. *
  416. * i8042KbdOpen - open keyboard device
  417. *
  418. */
  419. LOCAL int i8042KbdOpen
  420.     (
  421.     I8042_KBD_DEVICE *    pKbdDv,
  422.     char *          name,
  423.     int             mode
  424.     )
  425.     {
  426.     return ((int) pKbdDv);
  427.     }
  428. /*******************************************************************************
  429. *
  430. * i8042KbdIoctl - special device control
  431. *
  432. * This routine handles LED change requests and passes all others to tyIoctl.
  433. *
  434. * RETURNS: OK or  whatever tyIoctl returns.
  435. */
  436. LOCAL STATUS i8042KbdIoctl
  437.     (
  438.     I8042_KBD_DEVICE *    pKbdDv,    /* device to control */
  439.     int             request,         /* request code */
  440.     int             arg              /* some argument */
  441.     )
  442.     {
  443.     int     status = OK;
  444.     switch (request)
  445.         {
  446.         case CONIOLEDS:         /* change LEDs */
  447.             i8042KbdLedSet (pKbdDv, arg);
  448.             break;
  449.         default:
  450.             status = tyIoctl (&pKbdDv->tyDev, request, arg);
  451.             break;
  452.         }
  453.     return (status);
  454.     }
  455. /*******************************************************************************
  456. *
  457. * i8042KbdWriteData - write data to device
  458. *
  459. * This routine the write function from the I/O subsystem.
  460. *
  461. * RETURNS:
  462. */
  463. LOCAL int i8042KbdWriteData
  464.     (
  465.     I8042_KBD_DEVICE *    pKbdDv    /* device to control */
  466.     )
  467.     {
  468.         return (0);
  469.     }
  470. #if (CPU_FAMILY != I80X86)
  471. /*******************************************************************************
  472. *
  473. * i8042KbdHrdCheck - check the keyboard connection and verify operation
  474. *
  475. * This routine is called to verify the keyboard connection.  It is only
  476. * on non X86 processor systems. The X86 processors execute the BIOS which
  477. * performs the keyboard basic initialization.
  478. *
  479. * RETURNS: N/A
  480. *
  481. * NOMANUAL
  482. */
  483. LOCAL int i8042KbdHrdCheck
  484.     (
  485.     I8042_KBD_DEVICE   *  pI8042KbdDevice       /* Driver descriptor */
  486.     )
  487.     {
  488.     UCHAR     temp;
  489.     UCHAR     cond;
  490.     if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR) 
  491.         return(ERROR);
  492.     if (i8042Write (pI8042KbdDevice->statCmdReg, 
  493.                     pI8042KbdDevice->dataReg, 0x44) == ERROR)   
  494.         return(ERROR);
  495.     /* 8042 Self Test and Initialize */
  496.     cond = 0x00;
  497.     for (temp=0; (cond != 0x55) && (temp < 5); temp++)
  498.     {
  499.         if (i8042Command (pI8042KbdDevice->statCmdReg, 0xAA) == ERROR) 
  500.             return(ERROR);
  501.         if (i8042Read (pI8042KbdDevice->statCmdReg, 
  502.                        pI8042KbdDevice->dataReg, &cond) == ERROR)   
  503.             return(ERROR);
  504.         if (cond == 0xAA)
  505.             break;
  506.     }
  507.     if (cond != 0x55)
  508.         return(ERROR);
  509.     /* Check interface to keyboard */
  510.     if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_IF_TEST) == ERROR) 
  511.         return(ERROR);
  512.     if (i8042Read (pI8042KbdDevice->statCmdReg, 
  513.                    pI8042KbdDevice->dataReg, &cond) == ERROR) 
  514.         return(ERROR);
  515.     if (cond != 0x00)
  516.         return(ERROR);
  517.     if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR) 
  518.         return(ERROR);
  519.     if (i8042Write (pI8042KbdDevice->statCmdReg, 
  520.                     pI8042KbdDevice->dataReg, 0x45) == ERROR)   
  521.         return(ERROR);
  522.     /* Clean out the FIFO; typically has three return codes in it. */
  523.     /* Must wait a moment for the data to work its way to the surface. */
  524.     taskDelay (sysClkRateGet () >> 4);
  525.     while (I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_OBFULL)
  526.         {
  527.         cond = I8042_KBD_IN (pI8042KbdDevice->dataReg);
  528.         taskDelay (sysClkRateGet () >> 4);
  529.         }
  530.     return(OK);
  531. }
  532. #endif
  533. /*******************************************************************************
  534. *
  535. * i8042KbdHrdInit - initialize the Keyboard
  536. *
  537. * This routine is called to do the key board initialization
  538. *
  539. * RETURNS: N/A
  540. *
  541. * NOMANUAL
  542. */
  543. LOCAL void i8042KbdHrdInit 
  544.     (
  545.     I8042_KBD_DEVICE   *  pI8042KbdDevice       /* Driver descriptor */
  546.     )
  547.     {
  548.     UCHAR    temp;
  549.     FAST int    oldlevel;   /* to hold the oldlevel of interrupt */
  550.     oldlevel= intLock ();
  551.     i8042Wdid = wdCreate ();
  552. #if (CPU_FAMILY != I80X86)         /* BIOS initilizes for X86 */
  553.     if (i8042KbdHrdCheck (pI8042KbdDevice) == ERROR)
  554.         {
  555.         intUnlock (oldlevel);    
  556.         return;
  557.         }
  558. #endif
  559.     /* Reset time outs */
  560.     i8042TimeoutCnt = 0;
  561.     i8042Timeout = FALSE;
  562.         
  563.     do
  564.         {
  565.         if (i8042TimeoutCnt > 3)  /* try 3 times then give up */
  566.             break;
  567.         if (i8042Timeout)         /* reset if we got timeout */
  568.             i8042KbdReset (pI8042KbdDevice);
  569.         if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR)
  570.             continue;
  571.         if (i8042Write (pI8042KbdDevice->statCmdReg, 
  572.                         pI8042KbdDevice->dataReg,0x44) == ERROR)
  573.             continue;
  574.         while (I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_OBFULL)
  575.             if (i8042Read (pI8042KbdDevice->statCmdReg, 
  576.                            pI8042KbdDevice->dataReg, &temp) == ERROR)
  577.                 break;
  578.         if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR)
  579.             continue;
  580.         if (i8042Write (pI8042KbdDevice->statCmdReg, 
  581.                         pI8042KbdDevice->dataReg, 0x45) == ERROR)
  582.             continue;
  583.         if (i8042Command (pI8042KbdDevice->statCmdReg,  I8042_KBD_ENABLE) == ERROR)
  584.             continue;
  585.         } while (i8042Timeout);
  586.     /* Set LEDS to off */
  587.     pI8042KbdDevice->oldLedStat = 7;
  588.     i8042KbdLedSet (pI8042KbdDevice, 0);
  589.     intUnlock (oldlevel);
  590.     }
  591. /*******************************************************************************
  592. *
  593. * i8042KbdInt - interrupt level processing
  594. *
  595. * This routine handles the keyboard interrupts
  596. *
  597. * RETURNS: N/A
  598. *
  599. * NOMANUAL
  600. */
  601. LOCAL void i8042KbdInt 
  602.     (
  603.     I8042_KBD_DEVICE   *  pI8042KbdDevice       /* Driver descriptor */
  604.     )
  605.     {
  606.     FAST UCHAR  scanCode;   /* to hold the scanCode */
  607.     UCHAR stat = I8042_KBD_IN (pI8042KbdDevice->statCmdReg);
  608.     if (stat & I8042_KBD_OBFULL)
  609.         {
  610.         scanCode = I8042_KBD_IN (pI8042KbdDevice->dataReg);
  611.         /* keyboard acknowledge to any valid input, so just return */
  612.         if (scanCode == I8042_KBD_CMD_ACK)
  613.             return;
  614.             
  615.         /* queue scan code */
  616.         tyIRd (&(pI8042KbdDevice->tyDev), scanCode);
  617.         }
  618.     }
  619. /******************************************************************************
  620. *
  621. * i8042KbdLedSet - Keybord LED Set
  622. *
  623. * This routine sets the LEDs on the keyboard as they were set within the 
  624. *
  625. * RETURNS: N/A
  626. */
  627. LOCAL void i8042KbdLedSet 
  628.     (
  629.     I8042_KBD_DEVICE   *  pI8042KbdDevice,       /* Driver descriptor */
  630.     UCHAR                 led                    /* Value to set LEDs */
  631.     )
  632.     {
  633.     int     ix;    
  634.     led &=  0x07;         /* bits 0 1 2 for scroll numlock & capslock */
  635.     /* Only set LEDs if they change from previous */
  636.     if (pI8042KbdDevice->oldLedStat == led)
  637.         return;
  638.     pI8042KbdDevice->oldLedStat = led;
  639.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  640.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  641.             break;
  642.     I8042_KBD_OUT (pI8042KbdDevice->dataReg, 0xed);       /* SET LEDS command */
  643.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  644.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  645.             break;
  646.     I8042_KBD_OUT (pI8042KbdDevice->dataReg, led);       /* set LEDs */
  647.     }
  648. /******************************************************************************
  649. *
  650. * i8042KbdReset - reset a keyboard
  651. *
  652. * This routine resets the keyboard.
  653. *
  654. * RETURNS: N/A
  655. */
  656. LOCAL void i8042KbdReset 
  657.     (
  658.     I8042_KBD_DEVICE   *  pI8042KbdDevice       /* Driver descriptor */
  659.     )
  660.     {
  661.     int     ix;
  662.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  663.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  664.             break;
  665.     I8042_KBD_OUT (pI8042KbdDevice->dataReg, 0xff);
  666.     taskDelay (sysClkRateGet () >> 4);
  667.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  668.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  669.             break;
  670.     I8042_KBD_OUT (pI8042KbdDevice->dataReg, I8042_KBD_WT_CONFIG);
  671.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  672.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  673.             break;
  674.     I8042_KBD_OUT (pI8042KbdDevice->dataReg, 0x45);
  675.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  676.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  677.             break;
  678.     I8042_KBD_OUT (pI8042KbdDevice->statCmdReg, I8042_KBD_ENABLE);
  679.     for (ix = 0; ix < I8042_READ_DELAY; ix++)       /* wait for input buf empty */
  680.         if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0)
  681.             break;
  682.     }
  683. #endif /* INCLUDE_PC_CONSOLE */