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

VxWorks

开发平台:

C/C++

  1. /* smcFdc37b78x.c - a superIO (fdc37b78x) initialization source module */
  2. /* Copyright 1984-2000 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01a,28mar00,ms  written.
  8. */
  9. /*
  10. DESCRIPTION
  11. The FDC37B78x with advanced Consumer IR and IrDA v1.0 support incorporates a
  12. keyboard interface, real-time clock, SMSC's true CMOS 765B floppy disk
  13. controller, advanced digital data separator, 16 byte data FIFO, two 16C550
  14. compatible UARTs, one Multi-Mode parallel port which includes ChiProtect
  15. circuitry plus EPP and ECP support, on-chip 12 mA AT bus drivers, and two
  16. floppy direct drive support, soft power management and SMI support and
  17. Intelligent Power Management including PME and SCI/ACPI support. The true
  18. CMOS 765B core provides 100% compatibility with IBM PC/XT and PC/AT
  19. architectures in addition to providing data overflow and underflow protection.
  20. The SMSC advanced digital data separator incorporates SMSC's patented data
  21. separator technology, allowing for ease of testing and use. Both on-chip UARTs
  22. are compatible with the NS16C550. The parallel port, the IDE interface, and
  23. the game port select logic are compatible with IBM PC/AT architecture,
  24. as well as EPP and ECP.
  25. The FDC37B78x incorporates sophisticated power control circuitry (PCC) which
  26. includes support for keyboard, mouse, modem ring, power button support and
  27. consumer infrared wake-up events. The PCC supports multiple low power down
  28. modes.
  29. The FDC37B78x provides features for compliance with the "Advanced Configuration
  30. and Power Interface Specification" (ACPI). These features include support of
  31. both legacy and ACPI power management models through the selection of SMI or
  32. SCI. It implements a power button override event (4 second button hold to turn
  33. off the system) and either edge triggered interrupts.
  34. The FDC37B78x provides support for the ISA Plug-and-Play Standard (Version 1.0a)
  35. and provides for the recommended functionality to support Windows95, PC97 and
  36. PC98. Through internal configuration registers, each of the FDC37B78x's
  37. logical device's I/O address, DMA channel and IRQ channel may be programmed.
  38. There are 480 I/O address location options, 12 IRQ options or Serial IRQ option,
  39. and four DMA channel options for each logical device.
  40. .I USAGE
  41. This library provides routines to intialize various logical devices on superIO
  42. chip (fdc37b78x).
  43. The functions addressed here include:
  44. .IP "   -"
  45. Creating a logical device and initializing internal database accordingly.
  46. .IP "   -"
  47. Enabling as many device as permitted by this facility by single call. The
  48. user of thie facility can selectively intialize a set of devices on superIO
  49. chip.
  50. .IP "   -"
  51. Intializing keyboard by sending commands to its controller embedded in superIO
  52. chip.
  53. .LP
  54. .I INTERNAL DATABASES
  55. This library provides it's user to changes superIO's config, index, and data
  56. I/O port addresses. The default I/O port addresses are defined in
  57. target/h/drv/smcFdc37b78x.h file. These mnemonics can be overridden by defining
  58. in architecture related BSP header file. These default setting can also be
  59. changed on-the-fly by passing in a pointer of type SMCFDC37B78X_IOPORTS with
  60. different I/O port addresses. If not redefined, they take their default values
  61. as defined in smcFdc37b78x.h file.
  62. .IP "SMCFDC37B78X_CONFIG_PORT"
  63. Defines the config I/O port for SMC-FDC37B78X superIO chip.
  64. .IP "SMCFDC37B78X_INDEX_PORT"
  65. Defines the index I/O port for SMC-FDC37B78X superIO chip.
  66. .IP "SMCFDC37B78X_DATA_PORT"
  67. Defines the data I/O port for SMC-FDC37B78X superIO chip.
  68. .LP
  69. .I USER INTERFACE
  70. .CS
  71. VOID smcFdc37b78xDevCreate
  72.     (
  73.     SMCFDC37B78X_IOPORTS *smcFdc37b78x_iop
  74.     )
  75. .CE
  76. This is a very first routine that should be called by the user of this library.
  77. This routine sets up IO port address that will subsequentally be used later on.
  78. The IO PORT setting could either be overridden by redefining
  79. SMCFDC37B78X_CONFIG_PORT, SMCFDC37B78X_INDEX_PORT and SMCFDC37B78X_DATA_PORT
  80. or on-the-fly by passing in a pointer of type SMCFDC37B78X_IOPORTS.
  81. .CS
  82. VOID smcFdc37b78xInit
  83.     (
  84.     int devInitMask
  85.     )
  86. .CE
  87. This is routine intakes device intialization mask and intializes only those
  88. devices that are requested by user. Device initialization mask holds bitwise
  89. ORed values of all devices that are requested by user to enable on superIO
  90. device.
  91. The mnemonics that are supported in current version of this facility are:
  92. .IP "SMCFDC37B78X_COM1_EN"
  93. Use this mnemonic to enable COM1 only.
  94. .IP "SMCFDC37B78X_COM2_EN"
  95. Use this mnemonic to enable COM2 only.
  96. .IP "SMCFDC37B78X_LPT1_EN"
  97. Use this mnemonic to enable LPT1 only.
  98. .IP "SMCFDC37B78X_KBD_EN"
  99. Use this mnemonic to enable KBD only.
  100. .IP "SMCFDC37B78X_FDD_EN"
  101. Use this mnemonic to enable FDD only.
  102. .LP
  103. The above mentioned can be bitwise ORed to enable more than one device at
  104. a time. e.g. if you want COM1 and COM2 to be enable on superIO chip call:
  105. .CS
  106. smcFdc37b78xInit (SMCFDC37B78X_COM1_EN | SMCFDC37B78X_COM2_EN);
  107. .CE
  108. The prerequisites for above mentioned call, superIO chip library should be
  109. intialized using smcFdc37b78xDevCreate() with parameter as per user's need.
  110. .CS
  111. STATUS smcFdc37b78xKbdInit
  112.     (
  113.     VOID
  114.     )
  115. .CE
  116. This routine sends some keyboard commands to keyboard controller embedded
  117. in superIO chip. Call to this function is required for proper functioning
  118. of keyboard driver.
  119. INCLUDE FILES: smcFdc37b78x.h
  120. */
  121. /* includes */
  122. #include "vxWorks.h"
  123. #include "sysLib.h"
  124. #include "string.h"
  125. #include "drv/multi/smcFdc37b78x.h"
  126. /* globals */
  127. LOCAL SMCFDC37B78X_IOPORTS smcFdc37b78xIoPorts;
  128. LOCAL SMCFDC37B78X_IOPORTS * smcFdc37b78xIopPtr;
  129. /*******************************************************************************
  130. *
  131. * smcFdc37b78xModReg - modifies I/O port contents
  132. *
  133. * This routine will modify contents of a given I/O port
  134. *
  135. * RETURNS: NONE
  136. */
  137. LOCAL VOID smcFdc37b78xModReg
  138.     (
  139.     int ioPort,
  140.     unsigned char value,
  141.     unsigned char mask
  142.     )
  143.     {
  144.     unsigned char c;
  145.     
  146.     c = SMCFDC37B78XRD (ioPort);
  147.     c &= ~mask;
  148.     c |= value;
  149.     SMCFDC37B78XWRT (ioPort, c);
  150.     }
  151. /*******************************************************************************
  152. *
  153. * smcFdc37b78xEnterCfg - enter into super i/o configuration cycle
  154. *
  155. * This routine will begin super i/o configuration mode
  156. *
  157. * RETURNS: NONE
  158. */
  159. LOCAL VOID smcFdc37b78xEnterCfg
  160.     (
  161.     VOID
  162.     )
  163.     {
  164.     SMCFDC37B78XWRT (smcFdc37b78xIopPtr->config, SMCFDC37B78X_CONFIG_START);
  165.     }
  166. /*******************************************************************************
  167. *
  168. * smcFdc37b78xExitCfg - Exits super i/o configuration cycle
  169. *
  170. * This routine will exit from super i/o configuration mode
  171. *
  172. * RETURNS: NONE
  173. */
  174. LOCAL VOID smcFdc37b78xExitCfg
  175.     (
  176.     VOID
  177.     )
  178.     {
  179.     SMCFDC37B78XWRT (smcFdc37b78xIopPtr->config, SMCFDC37B78X_CONFIG_END);
  180.     }
  181. /*******************************************************************************
  182. *
  183. * smcFdc37b78xCfgDevReg - modifies contents of a register 
  184. *
  185. * This routine will modify register content of a given logical device
  186. *
  187. * RETURNS: NONE
  188. */
  189. LOCAL VOID smcFdc37b78xCfgDevReg
  190.     (
  191.     unsigned char logDevice,
  192.     unsigned char regIndex,
  193.     unsigned char regValue,
  194.     unsigned char mask
  195.     )
  196.     {
  197.     unsigned char c;
  198.     
  199.     /* select the logical device register */
  200.     SMCFDC37B78XWRT (smcFdc37b78xIopPtr->config, SMCFDC37B7X_LOGDEVCFGREG);
  201.     
  202.     /* select the logical device */
  203.     SMCFDC37B78XWRT (smcFdc37b78xIopPtr->data, logDevice);
  204.     
  205.     /* select the index */
  206.     SMCFDC37B78XWRT (smcFdc37b78xIopPtr->index, regIndex);
  207.     
  208.     c = SMCFDC37B78XRD (smcFdc37b78xIopPtr->data);
  209.     c &= ~mask;
  210.     c |= regValue;
  211.     SMCFDC37B78XWRT (smcFdc37b78xIopPtr->data, c);
  212.     }
  213. /*******************************************************************************
  214. *
  215. * smcFdc37b78xCfgDev - configures complete device
  216. *
  217. * This routine will activate logical device, sets IO register
  218. * addresses and set up an interrupt for given logical device
  219. *
  220. * RETURNS: NONE
  221. */
  222. LOCAL VOID smcFdc37b78xCfgDev
  223.     (
  224.     unsigned char device,
  225.     unsigned char ioBaseHigh,
  226.     unsigned char ioBaseLow,
  227.     unsigned char intr
  228.     )
  229.     {
  230.     /* activate given device */
  231.     smcFdc37b78xCfgDevReg (device, SMCFDC37B78X_LOGDEV_ACTIVATE,
  232.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  233.     /* set HIGH BYTE of IO base address */
  234.     smcFdc37b78xCfgDevReg (device, SMCFDC37B78X_IOBASE_HIGH,
  235.                            ioBaseHigh, SMCFDC37B78X_MASK_ALL);
  236.     /* set LOW BYTE of IO base address */    
  237.     smcFdc37b78xCfgDevReg (device, SMCFDC37B78X_IOBASE_LOW,
  238.                            ioBaseLow, SMCFDC37B78X_MASK_ALL);
  239.     /* set interrupt # for given device */    
  240.     smcFdc37b78xCfgDevReg (device, SMCFDC37B78X_INTERRUPT, intr,
  241.                            SMCFDC37B78X_MASK_ALL); 
  242.     }
  243. /*******************************************************************************
  244. *
  245. * smcFdc37b78xKbdRdy - indicates if kbd controller is ready to accept
  246. *                   read or write operation
  247. *
  248. * This routine checks if it's a good time to read or write to
  249. * keyboard I/O ports
  250. *
  251. * RETURNS: OK/ERROR
  252. */
  253. LOCAL STATUS smcFdc37b78xKbdRdy
  254.     (
  255.     int oper
  256.     )
  257.     {
  258.     int retry;
  259.     
  260.     for (retry = 0; retry < 100; retry++)
  261.         {
  262.         if (SMCFDC37B78X_KBD_RD_CTLSTS() & oper)
  263.             return (OK);
  264.         }
  265.     
  266.     return (ERROR);
  267.     }
  268. /*******************************************************************************
  269. *
  270. * smcFdc37b78xEnbKbd - enables keyboard on superIO
  271. *
  272. * This routine will enable everything required for keyboard device
  273. *
  274. * RETURNS: OK/ERROR
  275. */
  276. LOCAL STATUS smcFdc37b78xEnbKbd
  277.     (
  278.     VOID
  279.     )
  280.     {
  281.     smcFdc37b78xEnterCfg ();
  282.     /* activate keyboard device */
  283.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_KBD, SMCFDC37B78X_LOGDEV_ACTIVATE,
  284.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  285.     /* assign an interrupt # to keyboard device */
  286.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_KBD, SMCFDC37B78X_INTERRUPT,
  287.                            SMCFDC37B78X_INTR_KBD, SMCFDC37B78X_MASK_ALL);
  288.     /* activate Auxiliary device */
  289.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_LOGDEV_ACTIVATE,
  290.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  291.     
  292.     /* Keyboard IRQ */
  293.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_GP60_INDEX,
  294.                            SMCFDC37B78X_GP60_IRQ1_OUT,
  295.                            SMCFDC37B78X_GP_FUNC_MASK);
  296.     
  297.     /* configure auxiliary device to support parallel interrupts */
  298.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_IRQMUX_IDX,
  299.                            SMCFDC37B78X_IRQ_PARALLEL,
  300.                            SMCFDC37B78X_IRQ_PARALLEL_MASK);
  301.     
  302.     smcFdc37b78xExitCfg ();
  303.     return (OK);
  304.     }
  305. /*******************************************************************************
  306. *
  307. * smcFdc37b78xEnbCom1 - enables COM1 on superIO
  308. *
  309. * This routine will enable everything required for COM1 device
  310. *
  311. * RETURNS: OK/ERROR
  312. */
  313. LOCAL STATUS smcFdc37b78xEnbCom1
  314.     (
  315.     VOID
  316.     )
  317.     {
  318.     smcFdc37b78xEnterCfg ();
  319.     /* configure and activate serial device 1 */
  320.     smcFdc37b78xCfgDev (SMCFDC37B78X_COM1, SMCFDC37B78X_COM1_IOHIGH,
  321.                         SMCFDC37B78X_COM1_IOLOW, SMCFDC37B78X_INTR_COM1);
  322.     /* enable high speed services on serial device 1 */
  323.     smcFdc37b78xModReg (SMCFDC37B78X_COM1_MCR, SMCFDC37B78X_COM_MCROUT2,
  324.                         SMCFDC37B78X_COM_MCROUT2_MASK); 
  325.     /* activate Auxiliary device */
  326.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_LOGDEV_ACTIVATE,
  327.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  328.     /* Serial COM1 IRQ */
  329.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_GP62_INDEX,
  330.                            SMCFDC37B78X_GP62_IRQ4_OUT,
  331.                            SMCFDC37B78X_GP_FUNC_MASK);
  332.     
  333.     /* configure auxiliary device to support parallel interrupts */
  334.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_IRQMUX_IDX,
  335.                            SMCFDC37B78X_IRQ_PARALLEL,
  336.                            SMCFDC37B78X_IRQ_PARALLEL_MASK);
  337.     
  338.     smcFdc37b78xExitCfg ();
  339.     return (OK);
  340.     }
  341. /*******************************************************************************
  342. *
  343. * smcFdc37b78xEnbCom2 - enables COM2 on superIO
  344. *
  345. * This routine will enable everything required for COM2 device
  346. *
  347. * RETURNS: OK/ERROR
  348. */
  349. LOCAL STATUS smcFdc37b78xEnbCom2
  350.     (
  351.     VOID
  352.     )
  353.     {
  354.     smcFdc37b78xEnterCfg ();
  355.     /* configure and activate serial device 2 */
  356.     smcFdc37b78xCfgDev (SMCFDC37B78X_COM2, SMCFDC37B78X_COM2_IOHIGH,
  357.                         SMCFDC37B78X_COM2_IOLOW, SMCFDC37B78X_INTR_COM2);
  358.     /* enable high speed services on serial device 2 */    
  359.     smcFdc37b78xModReg (SMCFDC37B78X_COM2_MCR, SMCFDC37B78X_COM_MCROUT2,
  360.                         SMCFDC37B78X_COM_MCROUT2_MASK);
  361.     /* activate Auxiliary device */
  362.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_LOGDEV_ACTIVATE,
  363.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  364.     /* Serial COM2 IRQ */
  365.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_GP61_INDEX,
  366.                            SMCFDC37B78X_GP61_IRQ3_OUT,
  367.                            SMCFDC37B78X_GP_FUNC_MASK);
  368.     
  369.     /* configure auxiliary device to support parallel interrupts */
  370.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_IRQMUX_IDX,
  371.                            SMCFDC37B78X_IRQ_PARALLEL,
  372.                            SMCFDC37B78X_IRQ_PARALLEL_MASK);
  373.     
  374.     smcFdc37b78xExitCfg ();
  375.     return (OK);
  376.     }
  377. /*******************************************************************************
  378. *
  379. * smcFdc37b78xEnbLpt1 - enables LPT1 on superIO
  380. *
  381. * This routine will enable everything required for LPT1 device
  382. *
  383. * RETURNS: OK/ERROR
  384. */
  385. LOCAL STATUS smcFdc37b78xEnbLpt1
  386.     (
  387.     VOID
  388.     )
  389.     {
  390.     smcFdc37b78xEnterCfg ();
  391.     /* configure and activate parallel device */
  392.     smcFdc37b78xCfgDev (SMCFDC37B78X_LPT1, SMCFDC37B78X_LPT1_IOHIGH,
  393.                         SMCFDC37B78X_LPT1_IOLOW, SMCFDC37B78X_INTR_LPT1);
  394.     /* activate Auxiliary device */
  395.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_LOGDEV_ACTIVATE,
  396.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  397.     /* Parallel Port IRQ */
  398.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_GP65_INDEX,
  399.                            SMCFDC37B78X_GP65_IRQ7_OUT,
  400.                            SMCFDC37B78X_GP_FUNC_MASK); 
  401.     
  402.     /* configure auxiliary device to support parallel interrupts */
  403.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_IRQMUX_IDX,
  404.                            SMCFDC37B78X_IRQ_PARALLEL,
  405.                            SMCFDC37B78X_IRQ_PARALLEL_MASK);
  406.     smcFdc37b78xExitCfg ();
  407.     return (OK);
  408.     }
  409. /*******************************************************************************
  410. *
  411. * smcFdc37b78xEnbFdd - enables FDD on superIO
  412. *
  413. * This routine will enable everything required for FDD device
  414. *
  415. * RETURNS: OK/ERROR
  416. */
  417. LOCAL STATUS smcFdc37b78xEnbFdd
  418.     (
  419.     VOID
  420.     )
  421.     {
  422.     smcFdc37b78xEnterCfg ();
  423.     /* activate floppy device */
  424.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_FDD, SMCFDC37B78X_LOGDEV_ACTIVATE,
  425.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  426.     /* activate Auxiliary device */
  427.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_LOGDEV_ACTIVATE,
  428.                            SMCFDC37B78X_ACT_DEV, SMCFDC37B78X_MASK_ALL);
  429.     /* Floppy Disk Drive IRQ */
  430.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_GP64_INDEX,
  431.                            SMCFDC37B78X_GP64_IRQ6_OUT,
  432.                            SMCFDC37B78X_GP_FUNC_MASK);
  433.     /* configure auxiliary device to support parallel interrupts */
  434.     smcFdc37b78xCfgDevReg (SMCFDC37B78X_AUX, SMCFDC37B78X_IRQMUX_IDX,
  435.                            SMCFDC37B78X_IRQ_PARALLEL,
  436.                            SMCFDC37B78X_IRQ_PARALLEL_MASK);
  437.     
  438.     smcFdc37b78xExitCfg ();
  439.     return (OK);
  440.     }
  441. /*******************************************************************************
  442. *
  443. * smcFdc37b78xDevCreate - set correct IO port addresses for Super I/O chip
  444. *
  445. * This routine will initialize smcFdc37b78xIoPorts data structure. These ioports
  446. * can either be changed on-the-fly or overriding SMCFDC37B78X_CONFIG_PORT, 
  447. * SMCFDC37B78X_INDEX_PORT and SMCFDC37B78X_DATA_PORT. This is a necassary step
  448. * in intialization of superIO chip and logical devices embedded in it.
  449. *
  450. * RETURNS: NONE
  451. */
  452. VOID smcFdc37b78xDevCreate
  453.     (
  454.     SMCFDC37B78X_IOPORTS *smcFdc37b78x_iop
  455.     )
  456.     {
  457.     if (smcFdc37b78x_iop == NULL)
  458.         {
  459.         smcFdc37b78xIopPtr = &smcFdc37b78xIoPorts;
  460.         smcFdc37b78xIopPtr->config = SMCFDC37B78X_CONFIG_PORT;
  461.         smcFdc37b78xIopPtr->index  = SMCFDC37B78X_INDEX_PORT;
  462.         smcFdc37b78xIopPtr->data   = SMCFDC37B78X_DATA_PORT;
  463.         }
  464.     else
  465.         {
  466.         memcpy (&smcFdc37b78xIoPorts, smcFdc37b78x_iop,
  467.                 sizeof (SMCFDC37B78X_IOPORTS));
  468.         }
  469.     }
  470. /*******************************************************************************
  471. *
  472. * smcFdc37b78xInit - initializes Super I/O chip Library
  473. *
  474. * This routine will initialize serial, keyboard, floppy disk,
  475. * parallel port and gpio pins as a part super i/o intialization
  476. *
  477. * RETURNS: NONE
  478. */
  479. VOID smcFdc37b78xInit
  480.     (
  481.     int devInitMask
  482.     )
  483.     {
  484.     if (devInitMask & SMCFDC37B78X_FDD_EN)
  485.         {
  486.         smcFdc37b78xEnbFdd ();
  487.         }
  488.     if (devInitMask & SMCFDC37B78X_KBD_EN)
  489.         {
  490.         smcFdc37b78xEnbKbd ();
  491.         }
  492.     if (devInitMask & SMCFDC37B78X_COM1_EN)
  493.         {
  494.         smcFdc37b78xEnbCom1 ();
  495.         }
  496.     if (devInitMask & SMCFDC37B78X_COM2_EN)
  497.         {
  498.         smcFdc37b78xEnbCom2 ();
  499.         }
  500.     if (devInitMask & SMCFDC37B78X_LPT1_EN)
  501.         {
  502.         smcFdc37b78xEnbLpt1 ();
  503.         }
  504.     }
  505. /*******************************************************************************
  506. *
  507. * smcFdc37b78xKbdInit - initializes the keyboard controller
  508. *
  509. * This routine will initialize keyboard controller
  510. *
  511. * RETURNS: OK/ERROR
  512. */
  513. STATUS smcFdc37b78xKbdInit
  514.     (
  515.     VOID
  516.     )
  517.     {
  518.     /* Self Test */
  519.     SMCFDC37B78X_KBD_WRT_CTLSTS(SMCFDC37B78X_KBD_CCMD_SELFTEST);   
  520.     if (smcFdc37b78xKbdRdy (SMCFDC37B78X_KBD_CTLSTS_OBF) != OK)
  521.         return (ERROR);
  522.     /* Self Test PASSED ? */
  523.     if (SMCFDC37B78X_KBD_RD_DATA() != SMCFDC37B78X_KBD_SELFTEST_PASS) 
  524.         return (ERROR);
  525.     /* Interface Test */
  526.     SMCFDC37B78X_KBD_WRT_CTLSTS(SMCFDC37B78X_KBD_CCMD_IFCTEST); 
  527.     if (smcFdc37b78xKbdRdy (SMCFDC37B78X_KBD_CTLSTS_OBF) != OK)
  528.         return (ERROR);
  529.     /* Interface Test PASSED ? */
  530.     if (SMCFDC37B78X_KBD_RD_DATA() != SMCFDC37B78X_KBD_IFCTEST_PASS)
  531.         return (ERROR);
  532.     
  533.     /* Write to output port 2 */
  534.     SMCFDC37B78X_KBD_WRT_CTLSTS(SMCFDC37B78X_KBD_CCMD_WRTPORT2);
  535.     if (smcFdc37b78xKbdRdy (SMCFDC37B78X_KBD_CTLSTS_IBF) == OK)
  536.         return (ERROR);
  537.     /* P24 ENABLED */
  538.     SMCFDC37B78X_KBD_WRT_DATA(SMCFDC37B78X_KBD_IRQ_KSC_EN);
  539.     return (OK);
  540.     }