xref: /rk3399_rockchip-uboot/drivers/input/pc_keyb.c (revision 16b195c82a18cbfd164800f17a1ef9db2e48331a)
1*16b195c8SJean-Christophe PLAGNIOL-VILLARD /***********************************************************************
2*16b195c8SJean-Christophe PLAGNIOL-VILLARD  *
3*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2004
4*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * DENX Software Engineering
5*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * Wolfgang Denk, wd@denx.de
6*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * All rights reserved.
7*16b195c8SJean-Christophe PLAGNIOL-VILLARD  *
8*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * PS/2 keyboard driver
9*16b195c8SJean-Christophe PLAGNIOL-VILLARD  *
10*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * Originally from linux source (drivers/char/pc_keyb.c)
11*16b195c8SJean-Christophe PLAGNIOL-VILLARD  *
12*16b195c8SJean-Christophe PLAGNIOL-VILLARD  ***********************************************************************/
13*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
14*16b195c8SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
15*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
16*16b195c8SJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_PS2KBD
17*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
18*16b195c8SJean-Christophe PLAGNIOL-VILLARD #include <keyboard.h>
19*16b195c8SJean-Christophe PLAGNIOL-VILLARD #include <pc_keyb.h>
20*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
21*16b195c8SJean-Christophe PLAGNIOL-VILLARD #undef KBG_DEBUG
22*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
23*16b195c8SJean-Christophe PLAGNIOL-VILLARD #ifdef KBG_DEBUG
24*16b195c8SJean-Christophe PLAGNIOL-VILLARD #define	PRINTF(fmt,args...)	printf (fmt ,##args)
25*16b195c8SJean-Christophe PLAGNIOL-VILLARD #else
26*16b195c8SJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)
27*16b195c8SJean-Christophe PLAGNIOL-VILLARD #endif
28*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
29*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
30*16b195c8SJean-Christophe PLAGNIOL-VILLARD /*
31*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * This reads the keyboard status port, and does the
32*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * appropriate action.
33*16b195c8SJean-Christophe PLAGNIOL-VILLARD  *
34*16b195c8SJean-Christophe PLAGNIOL-VILLARD  */
35*16b195c8SJean-Christophe PLAGNIOL-VILLARD static unsigned char handle_kbd_event(void)
36*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
37*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	unsigned char status = kbd_read_status();
38*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	unsigned int work = 10000;
39*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
40*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	while ((--work > 0) && (status & KBD_STAT_OBF)) {
41*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		unsigned char scancode;
42*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
43*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		scancode = kbd_read_input();
44*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
45*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		/* Error bytes must be ignored to make the
46*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		   Synaptics touchpads compaq use work */
47*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		/* Ignore error bytes */
48*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
49*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			if (status & KBD_STAT_MOUSE_OBF)
50*16b195c8SJean-Christophe PLAGNIOL-VILLARD 				; /* not supported: handle_mouse_event(scancode); */
51*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			else
52*16b195c8SJean-Christophe PLAGNIOL-VILLARD 				handle_scancode(scancode);
53*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		}
54*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		status = kbd_read_status();
55*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	}
56*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (!work)
57*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
58*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	return status;
59*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
60*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
61*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
62*16b195c8SJean-Christophe PLAGNIOL-VILLARD static int kbd_read_data(void)
63*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
64*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	int val;
65*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	unsigned char status;
66*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
67*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	val=-1;
68*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	status = kbd_read_status();
69*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (status & KBD_STAT_OBF) {
70*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		val = kbd_read_input();
71*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
72*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			val = -2;
73*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	}
74*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	return val;
75*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
76*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
77*16b195c8SJean-Christophe PLAGNIOL-VILLARD static int kbd_wait_for_input(void)
78*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
79*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	unsigned long timeout;
80*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	int val;
81*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
82*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	timeout = KBD_TIMEOUT;
83*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	val=kbd_read_data();
84*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	while(val < 0) {
85*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if(timeout--==0)
86*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			return -1;
87*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		udelay(1000);
88*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		val=kbd_read_data();
89*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	}
90*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	return val;
91*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
92*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
93*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
94*16b195c8SJean-Christophe PLAGNIOL-VILLARD static int kb_wait(void)
95*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
96*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	unsigned long timeout = KBC_TIMEOUT * 10;
97*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
98*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	do {
99*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		unsigned char status = handle_kbd_event();
100*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (!(status & KBD_STAT_IBF))
101*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			return 0; /* ok */
102*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		udelay(1000);
103*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		timeout--;
104*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	} while (timeout);
105*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	return 1;
106*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
107*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
108*16b195c8SJean-Christophe PLAGNIOL-VILLARD static void kbd_write_command_w(int data)
109*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
110*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if(kb_wait())
111*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		PRINTF("timeout in kbd_write_command_w\n");
112*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_command(data);
113*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
114*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
115*16b195c8SJean-Christophe PLAGNIOL-VILLARD static void kbd_write_output_w(int data)
116*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
117*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if(kb_wait())
118*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		PRINTF("timeout in kbd_write_output_w\n");
119*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_output(data);
120*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
121*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
122*16b195c8SJean-Christophe PLAGNIOL-VILLARD static void kbd_send_data(unsigned char data)
123*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
124*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_output_w(data);
125*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_wait_for_input();
126*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
127*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
128*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
129*16b195c8SJean-Christophe PLAGNIOL-VILLARD static char * kbd_initialize(void)
130*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
131*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	int status;
132*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
133*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/*
134*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Test the keyboard interface.
135*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * This seems to be the only way to get it going.
136*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * If the test is successful a x55 is placed in the input buffer.
137*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 */
138*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_command_w(KBD_CCMD_SELF_TEST);
139*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (kbd_wait_for_input() != 0x55)
140*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return "Kbd:   failed self test";
141*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/*
142*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Perform a keyboard interface test.  This causes the controller
143*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * to test the keyboard clock and data lines.  The results of the
144*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * test are placed in the input buffer.
145*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 */
146*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_command_w(KBD_CCMD_KBD_TEST);
147*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (kbd_wait_for_input() != 0x00)
148*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return "Kbd:   interface failed self test";
149*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/*
150*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Enable the keyboard by allowing the keyboard clock to run.
151*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 */
152*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
153*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
154*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/*
155*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Reset keyboard. If the read times out
156*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * then the assumption is that no keyboard is
157*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * plugged into the machine.
158*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * This defaults the keyboard to scan-code set 2.
159*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 *
160*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Set up to try again if the keyboard asks for RESEND.
161*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 */
162*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	do {
163*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_write_output_w(KBD_CMD_RESET);
164*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		status = kbd_wait_for_input();
165*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (status == KBD_REPLY_ACK)
166*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			break;
167*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (status != KBD_REPLY_RESEND) {
168*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			PRINTF("status: %X\n",status);
169*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			return "Kbd:   reset failed, no ACK";
170*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		}
171*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	} while (1);
172*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (kbd_wait_for_input() != KBD_REPLY_POR)
173*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return "Kbd:   reset failed, no POR";
174*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
175*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/*
176*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Set keyboard controller mode. During this, the keyboard should be
177*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * in the disabled state.
178*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 *
179*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Set up to try again if the keyboard asks for RESEND.
180*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 */
181*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	do {
182*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_write_output_w(KBD_CMD_DISABLE);
183*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		status = kbd_wait_for_input();
184*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (status == KBD_REPLY_ACK)
185*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			break;
186*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		if (status != KBD_REPLY_RESEND)
187*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			return "Kbd:   disable keyboard: no ACK";
188*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	} while (1);
189*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
190*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_command_w(KBD_CCMD_WRITE_MODE);
191*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_output_w(KBD_MODE_KBD_INT
192*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			      | KBD_MODE_SYS
193*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			      | KBD_MODE_DISABLE_MOUSE
194*16b195c8SJean-Christophe PLAGNIOL-VILLARD 			      | KBD_MODE_KCC);
195*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
196*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
197*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_command_w(KBD_CCMD_READ_MODE);
198*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
199*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		/*
200*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		 * If the controller does not support conversion,
201*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		 * Set the keyboard to scan-code set 1.
202*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		 */
203*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_write_output_w(0xF0);
204*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_wait_for_input();
205*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_write_output_w(0x01);
206*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_wait_for_input();
207*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	}
208*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_output_w(KBD_CMD_ENABLE);
209*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (kbd_wait_for_input() != KBD_REPLY_ACK)
210*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return "Kbd:   enable keyboard: no ACK";
211*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
212*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	/*
213*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 * Finally, set the typematic rate to maximum.
214*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	 */
215*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_output_w(KBD_CMD_SET_RATE);
216*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (kbd_wait_for_input() != KBD_REPLY_ACK)
217*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return "Kbd:   Set rate: no ACK";
218*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_write_output_w(0x00);
219*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (kbd_wait_for_input() != KBD_REPLY_ACK)
220*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return "Kbd:   Set rate: no ACK";
221*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	return NULL;
222*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
223*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
224*16b195c8SJean-Christophe PLAGNIOL-VILLARD static void kbd_interrupt(void *dev_id)
225*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
226*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	handle_kbd_event();
227*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
228*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
229*16b195c8SJean-Christophe PLAGNIOL-VILLARD /******************************************************************
230*16b195c8SJean-Christophe PLAGNIOL-VILLARD  * Init
231*16b195c8SJean-Christophe PLAGNIOL-VILLARD  ******************************************************************/
232*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
233*16b195c8SJean-Christophe PLAGNIOL-VILLARD int kbd_init_hw(void)
234*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
235*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	char* result;
236*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
237*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_request_region();
238*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
239*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	result=kbd_initialize();
240*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	if (result==NULL) {
241*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		PRINTF("AT Keyboard initialized\n");
242*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		kbd_request_irq(kbd_interrupt);
243*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return (1);
244*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	} else {
245*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		printf("%s\n",result);
246*16b195c8SJean-Christophe PLAGNIOL-VILLARD 		return (-1);
247*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	}
248*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
249*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
250*16b195c8SJean-Christophe PLAGNIOL-VILLARD void pckbd_leds(unsigned char leds)
251*16b195c8SJean-Christophe PLAGNIOL-VILLARD {
252*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_send_data(KBD_CMD_SET_LEDS);
253*16b195c8SJean-Christophe PLAGNIOL-VILLARD 	kbd_send_data(leds);
254*16b195c8SJean-Christophe PLAGNIOL-VILLARD }
255*16b195c8SJean-Christophe PLAGNIOL-VILLARD 
256*16b195c8SJean-Christophe PLAGNIOL-VILLARD #endif /* CONFIG_PS2KBD */
257