📄 i8042kbdmse.c
字号:
i8042Command (pI8042MseDevice->statCmdReg, I8042_KBD_ENABLE); return; }/******************************************************************************* i8042MseInt - handle interrupts** This routine is the mouse port interrupt handler** RETURNS NA** SEE ALSO:*/LOCAL void i8042MseInt ( I8042_MSE_DEVICE *pI8042MseDevice /* device control structure */ ) { UCHAR in_char; /* Check if character is ready */ if (I8042_KBD_IN (pI8042MseDevice->statCmdReg) & (I8042_KBD_OBFULL | I8042_KBD_AUXB)) { /* Character present, so read it and place in read queue */ in_char = I8042_KBD_IN (pI8042MseDevice->dataReg); tyIRd (&pI8042MseDevice->ty_dev,in_char); } }/* If the PC Console is included then the keyboard controller is provided * by the PC console device. */#ifndef INCLUDE_PC_CONSOLE /******************************************************************************** i8042KbdDevCreate - create a device for the on-board ports** This routine creates a device on one of the pcConsole ports. Each port* to be used should have only one device associated with it, by calling* this routine.** RETURNS: OK, or ERROR if there is no driver or one already exists for the* specified port.*/STATUS i8042KbdDevCreate ( char * name /* name to use for this device */ ) { int i8042KbdDrvNum; /* driver number */ I8042_KBD_DEVICE * pI8042KbdDevice; /* device descriptors */ /* Allocate and initialize driver control structure */ pI8042KbdDevice = (I8042_KBD_DEVICE *)malloc (sizeof (I8042_KBD_DEVICE)); /* Obtain the keyboard access info */ pI8042KbdDevice->pDev = sysWindMLDevGet (WINDML_KEYBOARD_DEVICE, 0, 0, 0); /* Set up register access locations */ pI8042KbdDevice->statCmdReg = (ULONG)pI8042KbdDevice->pDev->pRegBase + ((ULONG)pI8042KbdDevice->pDev->regDelta * I8042_STAT_CMD); pI8042KbdDevice->dataReg = (ULONG)pI8042KbdDevice->pDev->pRegBase + ((ULONG)pI8042KbdDevice->pDev->regDelta * I8042_DATA); /* Connect the keyboard interrupt */ sysWindMLIntConnect (pI8042KbdDevice->pDev, i8042KbdInt, (int)pI8042KbdDevice); /* initialize the controller */ i8042KbdHrdInit (pI8042KbdDevice); /* Install the driver */ i8042KbdDrvNum = iosDrvInstall (i8042KbdOpen, (FUNCPTR) NULL, i8042KbdOpen, (FUNCPTR) NULL, tyRead, tyWrite, i8042KbdIoctl); if (tyDevInit (&pI8042KbdDevice->tyDev, 20, 10, i8042KbdWriteData) != OK) return (ERROR); /* Enable the keyboard interrupt */ sysWindMLIntEnable (pI8042KbdDevice->pDev); /* add the device to the I/O system */ if (iosDevAdd (&pI8042KbdDevice->tyDev.devHdr, name, i8042KbdDrvNum) == ERROR) return (ERROR); return (i8042KbdDrvNum); }/********************************************************************************* i8042KbdOpen - open keyboard device**/LOCAL int i8042KbdOpen ( I8042_KBD_DEVICE * pKbdDv, char * name, int mode ) { return ((int) pKbdDv); }/********************************************************************************* i8042KbdIoctl - special device control** This routine handles LED change requests and passes all others to tyIoctl.** RETURNS: OK or whatever tyIoctl returns.*/LOCAL STATUS i8042KbdIoctl ( I8042_KBD_DEVICE * pKbdDv, /* device to control */ int request, /* request code */ int arg /* some argument */ ) { int status = OK; switch (request) { case CONIOLEDS: /* change LEDs */ i8042KbdLedSet (pKbdDv, arg); break; default: status = tyIoctl (&pKbdDv->tyDev, request, arg); break; } return (status); }/********************************************************************************* i8042KbdWriteData - write data to device** This routine the write function from the I/O subsystem.** RETURNS:*/LOCAL int i8042KbdWriteData ( I8042_KBD_DEVICE * pKbdDv /* device to control */ ) { return (0); }#if (CPU_FAMILY != I80X86)/********************************************************************************* i8042KbdHrdCheck - check the keyboard connection and verify operation** This routine is called to verify the keyboard connection. It is only* on non X86 processor systems. The X86 processors execute the BIOS which* performs the keyboard basic initialization.** RETURNS: N/A** NOMANUAL*/LOCAL int i8042KbdHrdCheck ( I8042_KBD_DEVICE * pI8042KbdDevice /* Driver descriptor */ ) { UCHAR temp; UCHAR cond; if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR) return(ERROR); if (i8042Write (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg, 0x44) == ERROR) return(ERROR); /* 8042 Self Test and Initialize */ cond = 0x00; for (temp=0; (cond != 0x55) && (temp < 5); temp++) { if (i8042Command (pI8042KbdDevice->statCmdReg, 0xAA) == ERROR) return(ERROR); if (i8042Read (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg, &cond) == ERROR) return(ERROR); if (cond == 0xAA) break; } if (cond != 0x55) return(ERROR); /* Check interface to keyboard */ if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_IF_TEST) == ERROR) return(ERROR); if (i8042Read (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg, &cond) == ERROR) return(ERROR); if (cond != 0x00) return(ERROR); if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR) return(ERROR); if (i8042Write (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg, 0x45) == ERROR) return(ERROR); /* Clean out the FIFO; typically has three return codes in it. */ /* Must wait a moment for the data to work its way to the surface. */ taskDelay (sysClkRateGet () >> 4); while (I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_OBFULL) { cond = I8042_KBD_IN (pI8042KbdDevice->dataReg); taskDelay (sysClkRateGet () >> 4); } return(OK);}#endif/********************************************************************************* i8042KbdHrdInit - initialize the Keyboard** This routine is called to do the key board initialization** RETURNS: N/A** NOMANUAL*/LOCAL void i8042KbdHrdInit ( I8042_KBD_DEVICE * pI8042KbdDevice /* Driver descriptor */ ) { UCHAR temp; FAST int oldlevel; /* to hold the oldlevel of interrupt */ oldlevel= intLock (); i8042Wdid = wdCreate ();#if (CPU_FAMILY != I80X86) /* BIOS initilizes for X86 */ if (i8042KbdHrdCheck (pI8042KbdDevice) == ERROR) { intUnlock (oldlevel); return; }#endif /* Reset time outs */ i8042TimeoutCnt = 0; i8042Timeout = FALSE; do { if (i8042TimeoutCnt > 3) /* try 3 times then give up */ break; if (i8042Timeout) /* reset if we got timeout */ i8042KbdReset (pI8042KbdDevice); if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR) continue; if (i8042Write (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg,0x44) == ERROR) continue; while (I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_OBFULL) if (i8042Read (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg, &temp) == ERROR) break; if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_WT_CONFIG) == ERROR) continue; if (i8042Write (pI8042KbdDevice->statCmdReg, pI8042KbdDevice->dataReg, 0x45) == ERROR) continue; if (i8042Command (pI8042KbdDevice->statCmdReg, I8042_KBD_ENABLE) == ERROR) continue; } while (i8042Timeout); /* Set LEDS to off */ pI8042KbdDevice->oldLedStat = 7; i8042KbdLedSet (pI8042KbdDevice, 0); intUnlock (oldlevel); }/********************************************************************************* i8042KbdInt - interrupt level processing** This routine handles the keyboard interrupts** RETURNS: N/A** NOMANUAL*/LOCAL void i8042KbdInt ( I8042_KBD_DEVICE * pI8042KbdDevice /* Driver descriptor */ ) { FAST UCHAR scanCode; /* to hold the scanCode */ UCHAR stat = I8042_KBD_IN (pI8042KbdDevice->statCmdReg); if (stat & I8042_KBD_OBFULL) { scanCode = I8042_KBD_IN (pI8042KbdDevice->dataReg); /* keyboard acknowledge to any valid input, so just return */ if (scanCode == I8042_KBD_CMD_ACK) return; /* queue scan code */ tyIRd (&(pI8042KbdDevice->tyDev), scanCode); } }/******************************************************************************** i8042KbdLedSet - Keybord LED Set** This routine sets the LEDs on the keyboard as they were set within the ** RETURNS: N/A*/LOCAL void i8042KbdLedSet ( I8042_KBD_DEVICE * pI8042KbdDevice, /* Driver descriptor */ UCHAR led /* Value to set LEDs */ ) { int ix; led &= 0x07; /* bits 0 1 2 for scroll numlock & capslock */ /* Only set LEDs if they change from previous */ if (pI8042KbdDevice->oldLedStat == led) return; pI8042KbdDevice->oldLedStat = led; for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; I8042_KBD_OUT (pI8042KbdDevice->dataReg, 0xed); /* SET LEDS command */ for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; I8042_KBD_OUT (pI8042KbdDevice->dataReg, led); /* set LEDs */ }/******************************************************************************** i8042KbdReset - reset a keyboard** This routine resets the keyboard.** RETURNS: N/A*/LOCAL void i8042KbdReset ( I8042_KBD_DEVICE * pI8042KbdDevice /* Driver descriptor */ ) { int ix; for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; I8042_KBD_OUT (pI8042KbdDevice->dataReg, 0xff); taskDelay (sysClkRateGet () >> 4); for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; I8042_KBD_OUT (pI8042KbdDevice->dataReg, I8042_KBD_WT_CONFIG); for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; I8042_KBD_OUT (pI8042KbdDevice->dataReg, 0x45); for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; I8042_KBD_OUT (pI8042KbdDevice->statCmdReg, I8042_KBD_ENABLE); for (ix = 0; ix < I8042_READ_DELAY; ix++) /* wait for input buf empty */ if ((I8042_KBD_IN (pI8042KbdDevice->statCmdReg) & I8042_KBD_IBFULL) == 0) break; }#endif /* INCLUDE_PC_CONSOLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -