3 * Intel 8042 keyboard controller library.
4 * (C) 2008-2012 Jonathan Campbell.
5 * Hackipedia DOS library.
7 * This code is licensed under the LGPL.
8 * <insert LGPL legal text here>
12 #ifndef __HW_8042_8042_H
13 #define __HW_8042_8042_H
15 #include <hw/cpu/cpu.h>
18 #define K8042_STATUS 0x64 /* (R) */
19 #define K8042_COMMAND 0x64 /* (W) */
20 #define K8042_DATA 0x60 /* (R/W) */
23 #define K8042_STATUS_OUTPUT_FULL 0x01
24 #define K8042_STATUS_INPUT_FULL 0x02
25 #define K8042_STATUS_SYSTEM 0x04
26 #define K8042_STATUS_DATA_WRITE 0x08 /* 1=next write to 0x64 0=next write to 0x60 */
27 #define K8042_STATUS_INHIBIT 0x10
28 #define K8042_STATUS_XMIT_TIMEOUT 0x20
29 #define K8042_STATUS_MOUSE_OUTPUT_FULL 0x20
30 #define K8042_STATUS_RECV_TIMEOUT 0x40
31 #define K8042_STATUS_PARITY_ERR 0x80
34 #define K8042_MOUSE_IRQ 12
37 int k8042_probe_aux();
38 void k8042_drain_buffer();
39 int k8042_write_aux_synaptics_E8(unsigned char c);
40 int k8042_write_aux_synaptics_mode(unsigned char c);
42 extern unsigned char k8042_flags;
43 extern unsigned char k8042_last_status;
45 #define K8042_F_AUX 0x01
47 /* NTS: Do not confuse our input with the controller's input. This reflects the controller's input
48 * meaning: Can we, the host, OUTPUT DATA to the CONTROLLER'S INPUT? */
49 static inline unsigned char k8042_wait_for_input_buffer() {
50 unsigned int patience = 0xFFFFU;
53 do { c = inp(K8042_STATUS);
54 } while ((c&2) && --patience != 0U);
55 k8042_last_status = c;
59 /* NTS: Do not confue our output with the controller's output. This reflects the controller's output
60 * meaning: Can we, the host, INPUT DATA from the CONTROLLER'S OUTPUT? */
61 static inline unsigned char k8042_wait_for_output() {
62 unsigned int patience = 0xFFFFU;
65 do { c = inp(K8042_STATUS);
66 } while ((c&1) == 0 && --patience != 0U);
67 k8042_last_status = c;
71 static inline unsigned char k8042_is_output_ready() {
72 return ((k8042_last_status = inp(K8042_STATUS)) & K8042_STATUS_OUTPUT_FULL);
75 static inline unsigned char k8042_is_mouse_output_ready() {
76 return ((k8042_last_status = inp(K8042_STATUS)) & (K8042_STATUS_OUTPUT_FULL|K8042_STATUS_MOUSE_OUTPUT_FULL)) ==
77 (K8042_STATUS_OUTPUT_FULL|K8042_STATUS_MOUSE_OUTPUT_FULL);
80 static inline unsigned char k8042_output_was_aux() {
81 return (k8042_flags & K8042_F_AUX) != 0 && (k8042_last_status & K8042_STATUS_MOUSE_OUTPUT_FULL) != 0;
84 /* WARNING: caller is expected to use k8042_wait_for_output() prior to calling this */
85 static inline unsigned char k8042_read_output() {
86 return inp(K8042_DATA);
89 static inline int k8042_read_output_wait() {
90 if (k8042_wait_for_output() || k8042_wait_for_output() || k8042_wait_for_output())
91 return k8042_read_output();
96 static inline unsigned char k8042_write_command(unsigned char c) {
97 unsigned char r = k8042_wait_for_input_buffer();
98 if (r) outp(K8042_COMMAND,c);
102 static inline unsigned char k8042_write_data(unsigned char c) {
103 unsigned char r = k8042_wait_for_input_buffer();
104 if (r) outp(K8042_DATA,c);
108 static inline int k8042_read_command_byte() {
109 if (k8042_write_command(0x20))
110 return k8042_read_output_wait();
114 static inline unsigned char k8042_write_command_byte(unsigned char c) {
115 if (k8042_write_command(0x60) && k8042_write_data(c))
121 static inline void k8042_disable_keyboard() {
122 k8042_write_command(0xAD); /* disable keyboard */
125 static inline void k8042_enable_keyboard() {
126 k8042_write_command(0xAE); /* enable keyboard */
129 static inline void k8042_disable_aux() {
130 k8042_write_command(0xA7); /* disable aux */
133 static inline void k8042_enable_aux() {
134 k8042_write_command(0xA8); /* enable aux */
137 static inline unsigned char k8042_write_aux(unsigned char c) {
138 return (k8042_write_command(0xD4) && k8042_write_data(c));
141 #endif /* __HW_8042_8042_H */