📄 i8042kbdmse.c
字号:
/* i8042KbdMse.c - Intel 8042 keyboard/mouse driver routines *//* Copyright 1993-2002 Wind River System, Inc. */#include "copyright_wrs.h"/*modification history--------------------02b,14jun02,gav Fixed storage class warning from DIAB PPC compiler.02a,17may02,rfm Removed static declaration for i8042KbdStatInit01a,06dec01,jlb created*//*DESCRIPTIONThis is the driver for the Intel 8042 Keyboard/Mouse Controller Chip. TheIntel 8042 is the most common device that is used to implement the keyboardand mouse ports. Although, this device is no longer available, it is emulated by various super I/O chips. Any device specific needs of these super I/O devicesto enable the keyboard/mouse controller must be handled external to this driver. That is, this driver only pertains to the Intel 8042 specifics. This driver requires that the BSP implement the WindML BSP API (sysWindML.c)to obtain the device addresses and to enable/disable interrupt handling.Two devices are created, one for the keyboard and one for the pointer/mouse.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem. Two routines, however, must be called directly: i8042MseDevCreate() tocreate the mouse driver, and i8042KbdDevCreate() to create keyboard device.IOCTL FUNCTIONSThis driver responds to all the same ioctl() codes as a normal tty driver;for more information, see the manual entry for tyLib. In addition, the keyboarddriver has ioctls to control the settings of the LEDs on the keyboard.NOTESThe keyboard driver must be initialized prior to the initialization of themouse port. The keyboard port may be handled by the pcConsole driver that ispresent for the Pentium family of processors. When the PC Console is includedthe keyboard driver present within this file is not built, that is when INCLUDE_PC_CONSOLE is defined.*//* includes */#include "vxWorks.h"#include "iv.h"#include "ioLib.h"#include "iosLib.h"#include "memLib.h"#include "tyLib.h"#include "errnoLib.h"#include "wdLib.h"#include "sysLib.h"#include "intLib.h"#include "taskLib.h"#include "ugl/sysWindML.h"#include "drv/serial/i8042.h"#include "drv/serial/pcConsole.h"LOCAL int i8042TimeoutCnt;LOCAL BOOL i8042Timeout;LOCAL WDOG_ID i8042Wdid;/* forward declarations */#ifndef INCLUDE_PC_CONSOLELOCAL void i8042KbdLedSet (I8042_KBD_DEVICE * pKbdDv, UCHAR led);LOCAL void i8042KbdReset (I8042_KBD_DEVICE * pKbdDv);LOCAL int i8042KbdWriteData (I8042_KBD_DEVICE * pKbdDv);LOCAL void i8042KbdInt (I8042_KBD_DEVICE * pKbdDv);LOCAL int i8042KbdOpen ();LOCAL STATUS i8042KbdIoctl (I8042_KBD_DEVICE * pKbdDv, int request, int arg);LOCAL void i8042KbdHrdInit (I8042_KBD_DEVICE * pKbdDv);#endif /* INCLUDE_PC_CONSOLE */LOCAL int i8042MseOpen();LOCAL int i8042MseClose();LOCAL void i8042MseTxStart();LOCAL void i8042MseInt (I8042_MSE_DEVICE *pDev);LOCAL void i8042MseHwInit (I8042_MSE_DEVICE * pI8042MseDevice);/********************************************************************************* i8042MseDevCreate - mouse driver initialization routine** This routine creates a device for a mouse. The 8042 hardware is* initialized when the keyboard interface is initialized. Therefore, the* keyboard port must be initialized prior to the initialization of the mouse* port. This may be done either by the use of the keyboard driver contained* within this file or by the inclusion of the keyboard driver used by the* PC Console driver.** RETURNS: device number, if successful; otherwise ERROR.** SEE ALSO:*/int i8042MseDevCreate ( char *name /* name to be associated with device */ ) { int i8042MseDrvNum; I8042_MSE_DEVICE * pI8042MseDevice; /* Install the driver and return installation status */ i8042MseDrvNum = iosDrvInstall(i8042MseOpen, (FUNCPTR) NULL, i8042MseOpen, (FUNCPTR) i8042MseClose, tyRead, tyWrite, tyIoctl); /* Allocate device structure */ pI8042MseDevice = (I8042_MSE_DEVICE *)malloc (sizeof(I8042_MSE_DEVICE)); /* Create a tty device */ if (tyDevInit(&pI8042MseDevice->ty_dev, 512, 512, (FUNCPTR)i8042MseTxStart) != OK) return (ERROR); /* Get the device access information */ pI8042MseDevice->pDev = sysWindMLDevGet(WINDML_POINTER_DEVICE, 0, 0, 0); if (pI8042MseDevice->pDev == NULL) { free (pI8042MseDevice); return (ERROR); } /* Set up register access locations */ pI8042MseDevice->statCmdReg = (ULONG)pI8042MseDevice->pDev->pRegBase + ((ULONG)pI8042MseDevice->pDev->regDelta * I8042_STAT_CMD); pI8042MseDevice->dataReg = (ULONG)pI8042MseDevice->pDev->pRegBase + ((ULONG)pI8042MseDevice->pDev->regDelta * I8042_DATA); /* Connect the interrupt handler */ sysWindMLIntConnect(pI8042MseDevice->pDev, i8042MseInt, (int)pI8042MseDevice); /* initialize the interface */ i8042MseHwInit (pI8042MseDevice); /* enable the pointer interrupt */ sysWindMLIntEnable (pI8042MseDevice->pDev); /* add the device to the I/O system */ if (iosDevAdd(&pI8042MseDevice->ty_dev.devHdr,name,i8042MseDrvNum) == ERROR) return (ERROR); return (i8042MseDrvNum); }/********************************************************************************* i8042MseOpen - open file** This routine opens the mouse port on the i8042 controller.** RETURNS device structure** SEE ALSO:*/LOCAL int i8042MseOpen ( I8042_MSE_DEVICE *dev, /* device structure */ char *name, int mode ) { return ((int)dev); }/******************************************************************************* i8042MseTxStart - send data to mouse** This routine transmits data to the mouse port on the i8042 controller** RETURNS N/A** SEE ALSO:*/LOCAL void i8042MseTxStart ( I8042_MSE_DEVICE *dev ) { char out_char; while (tyITx(&dev->ty_dev,&out_char) == OK); }/******************************************************************************* i8042MseClose - close file** This routine closes the mouse device** RETURNS N/A** SEE ALSO:*/LOCAL int i8042MseClose ( I8042_MSE_DEVICE *dev ) { return((int)dev); }/******************************************************************************** i8042Wdog - I8042 driver watchdog handler.** i8042 driver watchdog handler.** RETURNS: N/A*/LOCAL void i8042Wdog (void) { i8042Timeout = TRUE; i8042TimeoutCnt++; }/******************************************************************************** i8042Read - read data from the i8042 keyboard/mouse controller.** Read data from the i8042 keyboard/mouse controller.** RETURNS: OK or ERROR if timed out*/LOCAL STATUS i8042Read ( ULONG statCmdReg, /* location of the status/command register */ ULONG dataReg, /* location of the data register */ UCHAR * pData /* location to return read data */ ) { /* Start watch dog to monitor device access */ i8042Timeout = FALSE; wdStart (i8042Wdid, (sysClkRateGet() * I8042_WAIT_SEC), (FUNCPTR)i8042Wdog, 0); /* Wait for device to become ready */ while (((I8042_KBD_IN (statCmdReg) & I8042_KBD_OBFULL) == 0) && !i8042Timeout) ; /* Cancel watch dog and delay for data to move up in device h/w queue */ wdCancel (i8042Wdid); taskDelay (sysClkRateGet () >> 4); /* read the character from the device */ *pData = I8042_KBD_IN (dataReg); return (i8042Timeout ? ERROR : OK); }/******************************************************************************** i8042Write - write data to the i8042 keyboard/mouse controller.** Write data to the i8042 keyboard/mouse controller.** RETURNS: OK or ERROR if timed out*/LOCAL STATUS i8042Write ( ULONG statCmdReg, /* location of the status/command register */ ULONG dataReg, /* location of the data register */ UCHAR data /* data to write to data register */ ) { /* Start watch dog to monitor device access */ i8042Timeout = FALSE; wdStart (i8042Wdid, (sysClkRateGet() * I8042_WAIT_SEC), (FUNCPTR)i8042Wdog, 0); /* Wait for device to become ready */ while ((I8042_KBD_IN (statCmdReg) & I8042_KBD_IBFULL) && !i8042Timeout) ; /* Cancel watch dog */ wdCancel (i8042Wdid); /* Send data */ I8042_KBD_OUT (dataReg, data); return (i8042Timeout ? ERROR : OK); }/******************************************************************************** i8042Command - write command to the i8042 keyboard/mouse controller.** Write command to the i8042 keyboard/mouse controller.** RETURNS: OK or ERROR if timed out*/LOCAL STATUS i8042Command ( ULONG statCmdReg, /* location of the status/command register */ UCHAR command /* command to write to command register */ ) { /* Start watch dog to monitor device access */ i8042Timeout = FALSE; wdStart (i8042Wdid, (sysClkRateGet() * I8042_WAIT_SEC), (FUNCPTR)i8042Wdog, 0); /* Wait for device to become ready */ while ((I8042_KBD_IN (statCmdReg) & I8042_KBD_IBFULL) && !i8042Timeout) ; /* Issue command */ I8042_KBD_OUT (statCmdReg, command); /* Wait for command to be completed */ while ((I8042_KBD_IN (statCmdReg) & I8042_KBD_IBFULL) && !i8042Timeout) ; /* Cancel watch dog */ wdCancel (i8042Wdid); return (i8042Timeout ? ERROR : OK); }/********************************************************************************* i8042MseHwInit - initialize the 8042 for mouse support** This routine initializes the 8042 mouse port.** RETURNS N/A** SEE ALSO:*/LOCAL void i8042MseHwInit ( I8042_MSE_DEVICE * pI8042MseDevice ) { unsigned char cond; unsigned char conf; /* Disable keyboard */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_DISABLE); /* Get current configuration */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_RD_CONFIG); i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, &conf); /* Disable interrupt for keyboard */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_CONFIG); i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, conf & 0xFC); /* Enable auxiliary device */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_ENABLE_AUX); /* Check interface to device */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_IF_AUX_TEST); if (i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, &cond) == ERROR) return; if (cond != I8042_KBD_IF_OK) return; /* Set Standard mode for mouse */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_AUX); i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, I8042_KBDM_SETS_CMD); if (i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, &cond) == ERROR) return; if (cond == I8042_KBDM_ACK) { /* Enable mouse device */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_AUX); i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, I8042_KBDM_ENABLE_CMD); if (i8042Read (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, &cond) == ERROR) return; if (cond == I8042_KBDM_ACK) conf |= I8042_KBD_AUX_INT; else return; } else return; /* reenable 8042 keyboard with new configuration */ i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_WT_CONFIG); i8042Write (pI8042MseDevice->statCmdReg, pI8042MseDevice->dataReg, conf); /* Enable keyboard */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -