1 /***********************************************************************
4 * DENX Software Engineering
5 * Wolfgang Denk, wd@denx.de
10 * Originally from linux source (drivers/char/pc_keyb.c)
12 ***********************************************************************/
22 #define PRINTF(fmt,args...) printf (fmt ,##args)
24 #define PRINTF(fmt,args...)
29 * This reads the keyboard status port, and does the
33 static unsigned char handle_kbd_event(void)
35 unsigned char status = kbd_read_status();
36 unsigned int work = 10000;
38 while ((--work > 0) && (status & KBD_STAT_OBF)) {
39 unsigned char scancode;
41 scancode = kbd_read_input();
43 /* Error bytes must be ignored to make the
44 Synaptics touchpads compaq use work */
45 /* Ignore error bytes */
46 if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
47 if (status & KBD_STAT_MOUSE_OBF)
48 ; /* not supported: handle_mouse_event(scancode); */
50 handle_scancode(scancode);
52 status = kbd_read_status();
55 PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
60 static int kbd_read_data(void)
66 status = kbd_read_status();
67 if (status & KBD_STAT_OBF) {
68 val = kbd_read_input();
69 if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
75 static int kbd_wait_for_input(void)
77 unsigned long timeout;
80 timeout = KBD_TIMEOUT;
92 static int kb_wait(void)
94 unsigned long timeout = KBC_TIMEOUT * 10;
97 unsigned char status = handle_kbd_event();
98 if (!(status & KBD_STAT_IBF))
106 static void kbd_write_command_w(int data)
109 PRINTF("timeout in kbd_write_command_w\n");
110 kbd_write_command(data);
113 static void kbd_write_output_w(int data)
116 PRINTF("timeout in kbd_write_output_w\n");
117 kbd_write_output(data);
120 static void kbd_send_data(unsigned char data)
122 kbd_write_output_w(data);
123 kbd_wait_for_input();
127 static char * kbd_initialize(void)
132 * Test the keyboard interface.
133 * This seems to be the only way to get it going.
134 * If the test is successful a x55 is placed in the input buffer.
136 kbd_write_command_w(KBD_CCMD_SELF_TEST);
137 if (kbd_wait_for_input() != 0x55)
138 return "Kbd: failed self test";
140 * Perform a keyboard interface test. This causes the controller
141 * to test the keyboard clock and data lines. The results of the
142 * test are placed in the input buffer.
144 kbd_write_command_w(KBD_CCMD_KBD_TEST);
145 if (kbd_wait_for_input() != 0x00)
146 return "Kbd: interface failed self test";
148 * Enable the keyboard by allowing the keyboard clock to run.
150 kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
153 * Reset keyboard. If the read times out
154 * then the assumption is that no keyboard is
155 * plugged into the machine.
156 * This defaults the keyboard to scan-code set 2.
158 * Set up to try again if the keyboard asks for RESEND.
161 kbd_write_output_w(KBD_CMD_RESET);
162 status = kbd_wait_for_input();
163 if (status == KBD_REPLY_ACK)
165 if (status != KBD_REPLY_RESEND) {
166 PRINTF("status: %X\n",status);
167 return "Kbd: reset failed, no ACK";
170 if (kbd_wait_for_input() != KBD_REPLY_POR)
171 return "Kbd: reset failed, no POR";
174 * Set keyboard controller mode. During this, the keyboard should be
175 * in the disabled state.
177 * Set up to try again if the keyboard asks for RESEND.
180 kbd_write_output_w(KBD_CMD_DISABLE);
181 status = kbd_wait_for_input();
182 if (status == KBD_REPLY_ACK)
184 if (status != KBD_REPLY_RESEND)
185 return "Kbd: disable keyboard: no ACK";
188 kbd_write_command_w(KBD_CCMD_WRITE_MODE);
189 kbd_write_output_w(KBD_MODE_KBD_INT
191 | KBD_MODE_DISABLE_MOUSE
194 /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
195 kbd_write_command_w(KBD_CCMD_READ_MODE);
196 if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
198 * If the controller does not support conversion,
199 * Set the keyboard to scan-code set 1.
201 kbd_write_output_w(0xF0);
202 kbd_wait_for_input();
203 kbd_write_output_w(0x01);
204 kbd_wait_for_input();
206 kbd_write_output_w(KBD_CMD_ENABLE);
207 if (kbd_wait_for_input() != KBD_REPLY_ACK)
208 return "Kbd: enable keyboard: no ACK";
211 * Finally, set the typematic rate to maximum.
213 kbd_write_output_w(KBD_CMD_SET_RATE);
214 if (kbd_wait_for_input() != KBD_REPLY_ACK)
215 return "Kbd: Set rate: no ACK";
216 kbd_write_output_w(0x00);
217 if (kbd_wait_for_input() != KBD_REPLY_ACK)
218 return "Kbd: Set rate: no ACK";
222 static void kbd_interrupt(void *dev_id)
227 /******************************************************************
229 ******************************************************************/
231 int kbd_init_hw(void)
235 kbd_request_region();
237 result=kbd_initialize();
239 PRINTF("AT Keyboard initialized\n");
240 kbd_request_irq(kbd_interrupt);
243 printf("%s\n",result);
248 void pckbd_leds(unsigned char leds)
250 kbd_send_data(KBD_CMD_SET_LEDS);