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