1 /* $NetBSD: i8042reg.h,v 1.5 2009/03/14 14:46:07 dsl Exp $ */ 2 3 /* 4 * Copyright 1997 5 * Digital Equipment Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and 8 * copied only in accordance with the following terms and conditions. 9 * Subject to these conditions, you may download, copy, install, 10 * use, modify and distribute this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce 14 * and retain this copyright notice and list of conditions as 15 * they appear in the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Digital Equipment Corporation. Neither the "Digital Equipment 19 * Corporation" name nor any trademark or logo of Digital Equipment 20 * Corporation may be used to endorse or promote products derived 21 * from this software without the prior written permission of 22 * Digital Equipment Corporation. 23 * 24 * 3) This software is provided "AS-IS" and any express or implied 25 * warranties, including but not limited to, any implied warranties 26 * of merchantability, fitness for a particular purpose, or 27 * non-infringement are disclaimed. In no event shall DIGITAL be 28 * liable for any damages whatsoever, and in particular, DIGITAL 29 * shall not be liable for special, indirect, consequential, or 30 * incidental damages or damages for lost profits, loss of 31 * revenue or loss of use, whether such damages arise in contract, 32 * negligence, tort, under statute, in equity, at law or otherwise, 33 * even if advised of the possibility of such damage. 34 */ 35 36 #ifndef _I8042_H 37 #define _I8042_H 38 39 /* Get the standard physical keyboard definitions 40 */ 41 #include <shark/shark/kbdreg.h> 42 43 /* 8042 Status register location and bit definitions 44 */ 45 #define KBSTATP 0x64 /* kbd controller status port (I) */ 46 #define KBSTATPO 0x04 /* kbd controller status port offset */ 47 /* from base of 8042 registers */ 48 #define KBS_DIB 0x01 /* kbd data in buffer */ 49 #define KBS_IBF 0x02 /* kbd input buffer low */ 50 #define KBS_WARM 0x04 /* kbd input buffer low */ 51 #define KBS_OCMD 0x08 /* kbd output buffer has command */ 52 #define KBS_NOSEC 0x10 /* kbd security lock not engaged */ 53 #define KBS_TERR 0x20 /* kbd transmission error. Note that */ 54 /* some firmware uses this bit to */ 55 /* indicate data in the input buffer */ 56 /* originated from the Auxiliary */ 57 /* device such as the mouse. */ 58 #define KBS_RERR 0x40 /* kbd receive error */ 59 #define KBS_PERR 0x80 /* kbd parity error */ 60 61 /* 8042 Command register location and command definitions 62 */ 63 #define KBCMDP 0x64 /* kbd controller port (O) */ 64 #define KBCMDPO 0x04 /* kbd controller port offset from */ 65 /* base of 8042 registers */ 66 #define KBC_RAMREAD 0x20 /* read from RAM */ 67 #define KBC_RAMWRITE 0x60 /* write to RAM */ 68 #define KBC_AUXDISABLE 0xa7 /* disable auxiliary port */ 69 #define KBC_AUXENABLE 0xa8 /* enable auxiliary port */ 70 #define KBC_AUXTEST 0xa9 /* test auxiliary port */ 71 #define KBC_KBDECHO 0xd2 /* echo to keyboard port */ 72 #define KBC_AUXECHO 0xd3 /* echo to auxiliary port */ 73 #define KBC_AUXWRITE 0xd4 /* write to auxiliary port */ 74 #define KBC_SELFTEST 0xaa /* start self-test */ 75 #define KBC_KBDTEST 0xab /* test keyboard port */ 76 #define KBC_KBDDISABLE 0xad /* disable keyboard port */ 77 #define KBC_KBDENABLE 0xae /* enable keyboard port */ 78 #define KBC_PULSE0 0xfe /* pulse output bit 0 */ 79 #define KBC_PULSE1 0xfd /* pulse output bit 1 */ 80 #define KBC_PULSE2 0xfb /* pulse output bit 2 */ 81 #define KBC_PULSE3 0xf7 /* pulse output bit 3 */ 82 83 84 /* 8042 Command responses. 85 */ 86 #define KBCR_AUXTEST_OK 0x00 /* Test on Aux device successful */ 87 #define KBCR_KBDTEST_OK 0x00 /* Test on keyboard device successful */ 88 #define KBCR_SELFTEST_OK 0x55 /* Controller self test success */ 89 90 /* Data input and output registers 91 */ 92 #define KBDATAP 0x60 /* kbd data port (I) */ 93 #define KBDATAPO 0x00 /* kbd data port offset(I) */ 94 #define KBOUTP 0x60 /* kbd data port (O) */ 95 #define KBOUTPO 0x00 /* kbd data port offset (O)*/ 96 97 /* Modify Controller Command Byte (CCB) definitions 98 */ 99 #define K_RDCMDBYTE 0x20 100 #define K_LDCMDBYTE 0x60 101 102 #define KC8_TRANS 0x40 /* convert to old scan codes */ 103 #define KC8_MDISABLE 0x20 /* disable mouse */ 104 #define KC8_KDISABLE 0x10 /* disable keyboard */ 105 #define KC8_IGNSEC 0x08 /* ignore security lock */ 106 #define KC8_CPU 0x04 /* exit from protected mode reset */ 107 #define KC8_MENABLE 0x02 /* enable mouse interrupt */ 108 #define KC8_KENABLE 0x01 /* enable keyboard interrupt */ 109 #define CMDBYTE (KC8_TRANS|KC8_CPU|KC8_MENABLE|KC8_KENABLE) 110 #define NOAUX_CMDBYTE (KC8_TRANS|KC8_MDISABLE|KC8_CPU|KC8_KENABLE) 111 112 /************************************************************************ 113 ** Macros for controlling the 8042 microprocessor 114 *************************************************************************/ 115 116 #define I8042_NPORTS 8 117 #define I8042_AUX_DATA KBS_TERR|KBS_DIB /* Wait for input from mouse */ 118 #define I8042_KBD_DATA KBS_DIB /* Wait for input from keyboard*/ 119 #define I8042_ANY_DATA 0xff /* Wait for any input */ 120 121 #define I8042_CMD 0 /* Command is for keyboard controller */ 122 #define I8042_AUX_CMD 1 /* Command is for auxiliary port */ 123 #define I8042_KBD_CMD 2 /* Write to keyboard device data area */ 124 #define I8042_WRITE_CCB 3 /* Write Controller Command Byte */ 125 126 127 #define I8042_CHECK_RESPONSE 1 /* Check the command response */ 128 #define I8042_NO_RESPONSE 0 /* No response expected from command */ 129 130 #define I8042_DELAY delay(2) /* delay for waiting for register update*/ 131 #define I8042_WAIT_THRESHOLD 500000 /* Maximum times to loop waiting for*/ 132 /* a change in status. Currently the*/ 133 /* value for this is determined by */ 134 /* the time required for the */ 135 /* keyboard to perform a reset. */ 136 #define I8042_RETRIES 3 /* Number of times to retry nak'd cmds */ 137 138 139 /* 140 ** Forward routine declarations 141 */ 142 extern void i8042_flush(bus_space_tag_t, 143 bus_space_handle_t); 144 extern int i8042_cmd(bus_space_tag_t, 145 bus_space_handle_t, 146 u_char, 147 u_char, 148 u_char, 149 u_char); 150 extern int i8042_wait_output(bus_space_tag_t, 151 bus_space_handle_t); 152 extern int i8042_wait_input(bus_space_tag_t, 153 bus_space_handle_t, 154 u_char); 155 156 /* Macro to map bus space for the 8042 device. 157 ** Returns 0 on success. 158 */ 159 #define I8042_MAP(iot, iobase, ioh) \ 160 (bus_space_map((iot), (iobase), I8042_NPORTS, 0, &(ioh))) 161 162 /* Macro to unmap bus space for the 8042 device. 163 */ 164 #define I8042_UNMAP(iot, ioh) \ 165 (bus_space_unmap((iot), (ioh), I8042_NPORTS)) 166 167 /* Macro to wait and retrieve data from the Auxiliary device. 168 ** NOTE: 169 ** We always check the status before reading the data port because some 8042 170 ** firmware seems to update the status and data AFTER the interrupt has 171 ** been generated. It is nasty because of the number of ISA access it 172 ** requires but then the alternative is failed interrupts. Also very 173 ** important is that there needs to be a delay after reading the data 174 ** since this causes the interrupt line to get cleared but because the 8042 175 ** is a slow processor we could return out of our interrupt handler and 176 ** bounce straight back in again with no data to read. 177 */ 178 #define I8042_GETAUX_DATA(iot, ioh, status, value) \ 179 { \ 180 if (((status) = i8042_wait_input((iot), (ioh), I8042_AUX_DATA)) != 0) \ 181 { \ 182 (value) = bus_space_read_1(iot, ioh, KBOUTPO); \ 183 I8042_DELAY; \ 184 } \ 185 } 186 187 /* Macro to wait and retrieve data from the Keyboard device. 188 ** NOTE: 189 ** We always check the status before reading the data port because some 8042 190 ** firmware seems to update the status and data AFTER the interrupt has 191 ** been generated. It is nasty because of the number of ISA access it 192 ** requires but then the alternative is failed interrupts. Also very 193 ** important is that there needs to be a delay after reading the data 194 ** since this causes the interrupt line to get cleared but because the 8042 195 ** is a slow processor we could return out of our interrupt handler and 196 ** bounce straight back in again with no data to read. 197 */ 198 #define I8042_GETKBD_DATA(iot, ioh, status, value) \ 199 { \ 200 if (((status) = i8042_wait_input((iot), (ioh), I8042_KBD_DATA)) != 0) \ 201 { \ 202 (value) = bus_space_read_1(iot, ioh, KBOUTPO); \ 203 I8042_DELAY; \ 204 } \ 205 } 206 207 /* Macro to test whether the controller is already initialised by checking 208 ** the system bit in the status register. 209 */ 210 #define I8042_WARM(iot, ioh) \ 211 ( bus_space_read_1((iot), (ioh), KBSTATPO ) & KBS_WARM ) 212 213 /* Macro to run self test on the 8042 controller and indicate success or 214 ** failure. 215 */ 216 #define I8042_SELFTEST(iot, ioh) \ 217 ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ 218 KBCR_SELFTEST_OK, KBC_SELFTEST) ) 219 220 /* Macro to run keyboard diagnostic test and indicate success or failure 221 */ 222 #define I8042_KBDTEST(iot, ioh) \ 223 ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ 224 KBCR_KBDTEST_OK, KBC_KBDTEST) ) 225 226 /* Macro to run Auxiliary device diagnostic test and indicate success or 227 ** failure. 228 */ 229 #define I8042_AUXTEST(iot, ioh) \ 230 ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ 231 KBCR_AUXTEST_OK, KBC_AUXTEST) ) 232 233 /* Macro to write the 8042 Controller Command byte 234 */ 235 #define I8042_WRITECCB(iot, ioh, value) \ 236 ( i8042_cmd((iot), (ioh), I8042_WRITE_CCB, I8042_NO_RESPONSE, \ 237 0, (value)) ) 238 239 /* Macro to read the 8042 Controller Command Byte 240 */ 241 #define I8042_READCCB(iot, ioh, status, value) \ 242 { \ 243 if ( ((status) = i8042_cmd((iot), (ioh), I8042_CMD, \ 244 I8042_NO_RESPONSE, 0, K_RDCMDBYTE)) != 0 ) \ 245 { \ 246 if (((status) = i8042_wait_input((iot),(ioh),I8042_ANY_DATA)) != 0) \ 247 { \ 248 (value) = bus_space_read_1((iot), (ioh), KBDATAPO); \ 249 } \ 250 } \ 251 } 252 253 /* Macro to disable the Auxiliary devices clock line 254 */ 255 #define I8042_AUXDISABLE(iot, ioh) \ 256 ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_NO_RESPONSE, \ 257 0, KBC_AUXDISABLE) ) 258 259 /* Macro to enable the Auxiliary device clock line. 260 */ 261 #define I8042_AUXENABLE(iot, ioh) \ 262 ( i8042_cmd((iot), (ioh), I8042_CMD, I8042_CHECK_RESPONSE, \ 263 KBR_ACK, KBC_AUXENABLE) ) 264 265 /* Macro to perform reset on Keyboard device hanging off the 8042. 266 */ 267 #define I8042_KBDRESET(iot, ioh, status) \ 268 { \ 269 if ( ((status) = i8042_cmd((iot), (ioh), I8042_KBD_CMD, \ 270 I8042_CHECK_RESPONSE, \ 271 KBR_ACK, KBC_RESET)) != 0 ) \ 272 { \ 273 if (((status) = i8042_wait_input((iot),(ioh),I8042_ANY_DATA)) != 0) \ 274 { \ 275 (status) = bus_space_read_1((iot), (ioh), KBDATAPO); \ 276 if ((status) != KBR_RSTDONE) \ 277 { \ 278 printf("I8042_KBDRESET: bad keyboard reset " \ 279 "response of 0x%x\n", \ 280 status); \ 281 (status) = 0; \ 282 } \ 283 } \ 284 } \ 285 } 286 287 #endif 288 289 290 291 292 293 294 295 296