/* $NetBSD: i8042reg.h,v 1.6 2016/07/07 06:55:38 msaitoh Exp $ */ /* * Copyright 1997 * Digital Equipment Corporation. All rights reserved. * * This software is furnished under license and may be used and * copied only in accordance with the following terms and conditions. * Subject to these conditions, you may download, copy, install, * use, modify and distribute this software in source and/or binary * form. No title or ownership is transferred hereby. * * 1) Any source code used, modified or distributed must reproduce * and retain this copyright notice and list of conditions as * they appear in the source file. * * 2) No right is granted to use any trade name, trademark, or logo of * Digital Equipment Corporation. Neither the "Digital Equipment * Corporation" name nor any trademark or logo of Digital Equipment * Corporation may be used to endorse or promote products derived * from this software without the prior written permission of * Digital Equipment Corporation. * * 3) This software is provided "AS-IS" and any express or implied * warranties, including but not limited to, any implied warranties * of merchantability, fitness for a particular purpose, or * non-infringement are disclaimed. In no event shall DIGITAL be * liable for any damages whatsoever, and in particular, DIGITAL * shall not be liable for special, indirect, consequential, or * incidental damages or damages for lost profits, loss of * revenue or loss of use, whether such damages arise in contract, * negligence, tort, under statute, in equity, at law or otherwise, * even if advised of the possibility of such damage. */ #ifndef _I8042_H #define _I8042_H /* Get the standard physical keyboard definitions */ #include /* 8042 Status register location and bit definitions */ #define KBSTATP 0x64 /* kbd controller status port (I) */ #define KBSTATPO 0x04 /* kbd controller status port offset */ /* from base of 8042 registers */ #define KBS_DIB 0x01 /* kbd data in buffer */ #define KBS_IBF 0x02 /* kbd input buffer low */ #define KBS_WARM 0x04 /* kbd input buffer low */ #define KBS_OCMD 0x08 /* kbd output buffer has command */ #define KBS_NOSEC 0x10 /* kbd security lock not engaged */ #define KBS_TERR 0x20 /* kbd transmission error. Note that */ /* some firmware uses this bit to */ /* indicate data in the input buffer */ /* originated from the Auxiliary */ /* device such as the mouse. */ #define KBS_RERR 0x40 /* kbd receive error */ #define KBS_PERR 0x80 /* kbd parity error */ /* 8042 Command register location and command definitions */ #define KBCMDP 0x64 /* kbd controller port (O) */ #define KBCMDPO 0x04 /* kbd controller port offset from */ /* base of 8042 registers */ #define KBC_RAMREAD 0x20 /* read from RAM */ #define KBC_RAMWRITE 0x60 /* write to RAM */ #define KBC_AUXDISABLE 0xa7 /* disable auxiliary port */ #define KBC_AUXENABLE 0xa8 /* enable auxiliary port */ #define KBC_AUXTEST 0xa9 /* test auxiliary port */ #define KBC_KBDECHO 0xd2 /* echo to keyboard port */ #define KBC_AUXECHO 0xd3 /* echo to auxiliary port */ #define KBC_AUXWRITE 0xd4 /* write to auxiliary port */ #define KBC_SELFTEST 0xaa /* start self-test */ #define KBC_KBDTEST 0xab /* test keyboard port */ #define KBC_KBDDISABLE 0xad /* disable keyboard port */ #define KBC_KBDENABLE 0xae /* enable keyboard port */ #define KBC_PULSE0 0xfe /* pulse output bit 0 */ #define KBC_PULSE1 0xfd /* pulse output bit 1 */ #define KBC_PULSE2 0xfb /* pulse output bit 2 */ #define KBC_PULSE3 0xf7 /* pulse output bit 3 */ /* 8042 Command responses. */ #define KBCR_AUXTEST_OK 0x00 /* Test on Aux device successful */ #define KBCR_KBDTEST_OK 0x00 /* Test on keyboard device successful */ #define KBCR_SELFTEST_OK 0x55 /* Controller self test success */ /* Data input and output registers */ #define KBDATAP 0x60 /* kbd data port (I) */ #define KBDATAPO 0x00 /* kbd data port offset(I) */ #define KBOUTP 0x60 /* kbd data port (O) */ #define KBOUTPO 0x00 /* kbd data port offset (O)*/ /* Modify Controller Command Byte (CCB) definitions */ #define K_RDCMDBYTE 0x20 #define K_LDCMDBYTE 0x60 #define KC8_TRANS 0x40 /* convert to old scan codes */ #define KC8_MDISABLE 0x20 /* disable mouse */ #define KC8_KDISABLE 0x10 /* disable keyboard */ #define KC8_IGNSEC 0x08 /* ignore security lock */ #define KC8_CPU 0x04 /* exit from protected mode reset */ #define KC8_MENABLE 0x02 /* enable mouse interrupt */ #define KC8_KENABLE 0x01 /* enable keyboard interrupt */ #define CMDBYTE (KC8_TRANS|KC8_CPU|KC8_MENABLE|KC8_KENABLE) #define NOAUX_CMDBYTE (KC8_TRANS|KC8_MDISABLE|KC8_CPU|KC8_KENABLE) /************************************************************************ ** Macros for controlling the 8042 microprocessor *************************************************************************/ #define I8042_NPORTS 8 #define I8042_AUX_DATA KBS_TERR|KBS_DIB /* Wait for input from mouse */ #define I8042_KBD_DATA KBS_DIB /* Wait for input from keyboard*/ #define I8042_ANY_DATA 0xff /* Wait for any input */ #define I8042_CMD 0 /* Command is for keyboard controller */ #define I8042_AUX_CMD 1 /* Command is for auxiliary port */ #define I8042_KBD_CMD 2 /* Write to keyboard device data area */ #define I8042_WRITE_CCB 3 /* Write Controller Command Byte */ #define I8042_CHECK_RESPONSE 1 /* Check the command response */ #define I8042_NO_RESPONSE 0 /* No response expected from command */ #define I8042_DELAY delay(2) /* delay for waiting for register update*/ #define I8042_WAIT_THRESHOLD 500000 /* Maximum times to loop waiting for*/ /* a change in status. Currently the*/ /* value for this is determined by */ /* the time required for the */ /* keyboard to perform a reset. */ #define I8042_RETRIES 3 /* Number of times to retry nak'd cmds */ /* ** Forward routine declarations */ extern void i8042_flush(bus_space_tag_t, bus_space_handle_t); extern int i8042_cmd(bus_space_tag_t, bus_space_handle_t, u_char, u_char, u_char, u_char); extern int i8042_wait_output(bus_space_tag_t, bus_space_handle_t); extern int i8042_wait_input(bus_space_tag_t, bus_space_handle_t, u_char); /* Macro to map bus space for the 8042 device. ** Returns 0 on success. */ #define I8042_MAP(iot, iobase, ioh) \ (bus_space_map((iot), (iobase), I8042_NPORTS, 0, &(ioh))) /* Macro to unmap bus space for the 8042 device. */ #define I8042_UNMAP(iot, ioh) \ (bus_space_unmap((iot), (ioh), I8042_NPORTS)) /* Macro to wait and retrieve data from the Auxiliary device. ** NOTE: ** We always check the status before reading the data port because some 8042 ** firmware seems to update the status and data AFTER the interrupt has ** been generated. It is nasty because of the number of ISA access it ** requires but then the alternative is failed interrupts. Also very ** important is that there needs to be a delay after reading the data ** since this causes the interrupt line to get cleared but because the 8042 ** is a slow processor we could return out of our interrupt handler and ** bounce straight back in again with no data to read. */ #define I8042_GETAUX_DATA(iot, ioh, status, value) \ { \ if (((status) = i8042_wait_input((iot), (ioh), I8042_AUX_DATA)) != 0) \ { \ (value) = bus_space_read_1(iot, ioh, KBOUTPO); \ I8042_DELAY; \ } \ } /* Macro to wait and retrieve data from the Keyboard device. ** NOTE: ** We always check the status before reading the data port because some 8042 ** firmware seems to update the status and data AFTER the interrupt has ** been generated. It is nasty because of the number of ISA access it ** requires but then the alternative is failed interrupts. Also very ** important is that there needs to be a delay after reading the data ** since this causes the interrupt line to get cleared but because the 8042 ** is a slow processor we could return out of our interrupt handler and ** bounce straight back in again with no data to read. */ #define I8042_GETKBD_DATA(iot, ioh, status, value) \ { \ if (((status) = i8042_wait_input((iot), (ioh), I8042_KBD_DATA)) != 0) \ { \ (value) = bus_space_read_1(iot, ioh, KBOUTPO); \ I8042_DELAY; \ } \ } /* Macro to test whether the controller is already initialised by checking ** the system bit in the status register. */ #define I8042_WARM(iot, ioh) \ ( bus_space_read_1((iot), (ioh), KBSTATPO ) & KBS_WARM ) /* Macro to run self test on the 8042 controller and indicate success or ** failure. */ #define I8042_SELFTEST(iot, ioh) \ ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ KBCR_SELFTEST_OK, KBC_SELFTEST) ) /* Macro to run keyboard diagnostic test and indicate success or failure */ #define I8042_KBDTEST(iot, ioh) \ ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ KBCR_KBDTEST_OK, KBC_KBDTEST) ) /* Macro to run Auxiliary device diagnostic test and indicate success or ** failure. */ #define I8042_AUXTEST(iot, ioh) \ ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ KBCR_AUXTEST_OK, KBC_AUXTEST) ) /* Macro to write the 8042 Controller Command byte */ #define I8042_WRITECCB(iot, ioh, value) \ ( i8042_cmd((iot), (ioh), I8042_WRITE_CCB, I8042_NO_RESPONSE, \ 0, (value)) ) /* Macro to read the 8042 Controller Command Byte */ #define I8042_READCCB(iot, ioh, status, value) \ { \ if ( ((status) = i8042_cmd((iot), (ioh), I8042_CMD, \ I8042_NO_RESPONSE, 0, K_RDCMDBYTE)) != 0 ) \ { \ if (((status) = i8042_wait_input((iot),(ioh),I8042_ANY_DATA)) != 0) \ { \ (value) = bus_space_read_1((iot), (ioh), KBDATAPO); \ } \ } \ } /* Macro to disable the Auxiliary devices clock line */ #define I8042_AUXDISABLE(iot, ioh) \ ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_NO_RESPONSE, \ 0, KBC_AUXDISABLE) ) /* Macro to enable the Auxiliary device clock line. */ #define I8042_AUXENABLE(iot, ioh) \ ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ KBR_ACK, KBC_AUXENABLE) ) /* Macro to perform reset on Keyboard device hanging off the 8042. */ #define I8042_KBDRESET(iot, ioh, status) \ { \ if ( ((status) = i8042_cmd((iot), (ioh), I8042_KBD_CMD, \ I8042_CHECK_RESPONSE, \ KBR_ACK, KBC_RESET)) != 0 ) \ { \ if (((status) = i8042_wait_input((iot),(ioh),I8042_ANY_DATA)) != 0) \ { \ (status) = bus_space_read_1((iot), (ioh), KBDATAPO); \ if ((status) != KBR_RSTDONE) \ { \ printf("I8042_KBDRESET: bad keyboard reset " \ "response of 0x%x\n", \ status); \ (status) = 0; \ } \ } \ } \ } #endif