xref: /netbsd/sys/arch/shark/shark/i8042reg.h (revision 6550d01e)
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