1 /***********************************************************************
4 * DENX Software Engineering
5 * Wolfgang Denk, wd@denx.de
10 * Originally from linux source (drivers/char/pc_keyb.c)
12 ***********************************************************************/
24 #define PRINTF(fmt,args...) printf (fmt ,##args)
26 #define PRINTF(fmt,args...)
31 * This reads the keyboard status port, and does the
35 static unsigned char handle_kbd_event(void)
37 unsigned char status
= kbd_read_status();
38 unsigned int work
= 10000;
40 while ((--work
> 0) && (status
& KBD_STAT_OBF
)) {
41 unsigned char scancode
;
43 scancode
= kbd_read_input();
45 /* Error bytes must be ignored to make the
46 Synaptics touchpads compaq use work */
47 /* Ignore error bytes */
48 if (!(status
& (KBD_STAT_GTO
| KBD_STAT_PERR
))) {
49 if (status
& KBD_STAT_MOUSE_OBF
)
50 ; /* not supported: handle_mouse_event(scancode); */
52 handle_scancode(scancode
);
54 status
= kbd_read_status();
57 PRINTF("pc_keyb: controller jammed (0x%02X).\n", status
);
62 static int kbd_read_data(void)
68 status
= kbd_read_status();
69 if (status
& KBD_STAT_OBF
) {
70 val
= kbd_read_input();
71 if (status
& (KBD_STAT_GTO
| KBD_STAT_PERR
))
77 static int kbd_wait_for_input(void)
79 unsigned long timeout
;
82 timeout
= KBD_TIMEOUT
;
94 static int kb_wait(void)
96 unsigned long timeout
= KBC_TIMEOUT
* 10;
99 unsigned char status
= handle_kbd_event();
100 if (!(status
& KBD_STAT_IBF
))
108 static void kbd_write_command_w(int data
)
111 PRINTF("timeout in kbd_write_command_w\n");
112 kbd_write_command(data
);
115 static void kbd_write_output_w(int data
)
118 PRINTF("timeout in kbd_write_output_w\n");
119 kbd_write_output(data
);
122 static void kbd_send_data(unsigned char data
)
124 kbd_write_output_w(data
);
125 kbd_wait_for_input();
129 static char * kbd_initialize(void)
134 * Test the keyboard interface.
135 * This seems to be the only way to get it going.
136 * If the test is successful a x55 is placed in the input buffer.
138 kbd_write_command_w(KBD_CCMD_SELF_TEST
);
139 if (kbd_wait_for_input() != 0x55)
140 return "Kbd: failed self test";
142 * Perform a keyboard interface test. This causes the controller
143 * to test the keyboard clock and data lines. The results of the
144 * test are placed in the input buffer.
146 kbd_write_command_w(KBD_CCMD_KBD_TEST
);
147 if (kbd_wait_for_input() != 0x00)
148 return "Kbd: interface failed self test";
150 * Enable the keyboard by allowing the keyboard clock to run.
152 kbd_write_command_w(KBD_CCMD_KBD_ENABLE
);
155 * Reset keyboard. If the read times out
156 * then the assumption is that no keyboard is
157 * plugged into the machine.
158 * This defaults the keyboard to scan-code set 2.
160 * Set up to try again if the keyboard asks for RESEND.
163 kbd_write_output_w(KBD_CMD_RESET
);
164 status
= kbd_wait_for_input();
165 if (status
== KBD_REPLY_ACK
)
167 if (status
!= KBD_REPLY_RESEND
) {
168 PRINTF("status: %X\n",status
);
169 return "Kbd: reset failed, no ACK";
172 if (kbd_wait_for_input() != KBD_REPLY_POR
)
173 return "Kbd: reset failed, no POR";
176 * Set keyboard controller mode. During this, the keyboard should be
177 * in the disabled state.
179 * Set up to try again if the keyboard asks for RESEND.
182 kbd_write_output_w(KBD_CMD_DISABLE
);
183 status
= kbd_wait_for_input();
184 if (status
== KBD_REPLY_ACK
)
186 if (status
!= KBD_REPLY_RESEND
)
187 return "Kbd: disable keyboard: no ACK";
190 kbd_write_command_w(KBD_CCMD_WRITE_MODE
);
191 kbd_write_output_w(KBD_MODE_KBD_INT
193 | KBD_MODE_DISABLE_MOUSE
196 /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
197 kbd_write_command_w(KBD_CCMD_READ_MODE
);
198 if (!(kbd_wait_for_input() & KBD_MODE_KCC
)) {
200 * If the controller does not support conversion,
201 * Set the keyboard to scan-code set 1.
203 kbd_write_output_w(0xF0);
204 kbd_wait_for_input();
205 kbd_write_output_w(0x01);
206 kbd_wait_for_input();
208 kbd_write_output_w(KBD_CMD_ENABLE
);
209 if (kbd_wait_for_input() != KBD_REPLY_ACK
)
210 return "Kbd: enable keyboard: no ACK";
213 * Finally, set the typematic rate to maximum.
215 kbd_write_output_w(KBD_CMD_SET_RATE
);
216 if (kbd_wait_for_input() != KBD_REPLY_ACK
)
217 return "Kbd: Set rate: no ACK";
218 kbd_write_output_w(0x00);
219 if (kbd_wait_for_input() != KBD_REPLY_ACK
)
220 return "Kbd: Set rate: no ACK";
224 static void kbd_interrupt(void *dev_id
)
229 /******************************************************************
231 ******************************************************************/
233 int kbd_init_hw(void)
237 kbd_request_region();
239 result
=kbd_initialize();
241 PRINTF("AT Keyboard initialized\n");
242 kbd_request_irq(kbd_interrupt
);
245 printf("%s\n",result
);
250 void pckbd_leds(unsigned char leds
)
252 kbd_send_data(KBD_CMD_SET_LEDS
);
256 #endif /* CONFIG_PS2KBD */