xref: /freebsd/sys/dev/evdev/evdev_utils.c (revision 56e53cb8ef000c3ef72337a4095987a932cdedef)
1 /*-
2  * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org>
3  * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #include <sys/param.h>
31 #include <sys/bus.h>
32 #include <sys/conf.h>
33 #include <sys/kbio.h>
34 #include <sys/kernel.h>
35 #include <sys/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/mutex.h>
38 #include <sys/systm.h>
39 
40 #include <dev/evdev/evdev.h>
41 #include <dev/evdev/input.h>
42 
43 #include <dev/kbd/kbdreg.h>
44 
45 #define	NONE	KEY_RESERVED
46 
47 static uint16_t evdev_usb_scancodes[256] = {
48 	/* 0x00 - 0x27 */
49 	NONE,	NONE,	NONE,	NONE,	KEY_A,	KEY_B,	KEY_C,	KEY_D,
50 	KEY_E,	KEY_F,	KEY_G,	KEY_H,	KEY_I,	KEY_J,	KEY_K,	KEY_L,
51 	KEY_M,	KEY_N,	KEY_O,	KEY_P,	KEY_Q,	KEY_R,	KEY_S,	KEY_T,
52 	KEY_U,	KEY_V,	KEY_W,	KEY_X,	KEY_Y,	KEY_Z,	KEY_1,	KEY_2,
53 	KEY_3,	KEY_4,	KEY_5,	KEY_6,	KEY_7,	KEY_8,	KEY_9,	KEY_0,
54 	/* 0x28 - 0x3f */
55 	KEY_ENTER,	KEY_ESC,	KEY_BACKSPACE,	KEY_TAB,
56 	KEY_SPACE,	KEY_MINUS,	KEY_EQUAL,	KEY_LEFTBRACE,
57 	KEY_RIGHTBRACE,	KEY_BACKSLASH,	KEY_BACKSLASH,	KEY_SEMICOLON,
58 	KEY_APOSTROPHE,	KEY_GRAVE,	KEY_COMMA,	KEY_DOT,
59 	KEY_SLASH,	KEY_CAPSLOCK,	KEY_F1,		KEY_F2,
60 	KEY_F3,		KEY_F4,		KEY_F5,		KEY_F6,
61 	/* 0x40 - 0x5f */
62 	KEY_F7,		KEY_F8,		KEY_F9,		KEY_F10,
63 	KEY_F11,	KEY_F12,	KEY_SYSRQ,	KEY_SCROLLLOCK,
64 	KEY_PAUSE,	KEY_INSERT,	KEY_HOME,	KEY_PAGEUP,
65 	KEY_DELETE,	KEY_END,	KEY_PAGEDOWN,	KEY_RIGHT,
66 	KEY_LEFT,	KEY_DOWN,	KEY_UP,		KEY_NUMLOCK,
67 	KEY_KPSLASH,	KEY_KPASTERISK,	KEY_KPMINUS,	KEY_KPPLUS,
68 	KEY_KPENTER,	KEY_KP1,	KEY_KP2,	KEY_KP3,
69 	KEY_KP4,	KEY_KP5,	KEY_KP6,	KEY_KP7,
70 	/* 0x60 - 0x7f */
71 	KEY_KP8,	KEY_KP9,	KEY_KP0,	KEY_KPDOT,
72 	KEY_102ND,	KEY_COMPOSE,	KEY_POWER,	KEY_KPEQUAL,
73 	KEY_F13,	KEY_F14,	KEY_F15,	KEY_F16,
74 	KEY_F17,	KEY_F18,	KEY_F19,	KEY_F20,
75 	KEY_F21,	KEY_F22,	KEY_F23,	KEY_F24,
76 	KEY_OPEN,	KEY_HELP,	KEY_PROPS,	KEY_FRONT,
77 	KEY_STOP,	KEY_AGAIN,	KEY_UNDO,	KEY_CUT,
78 	KEY_COPY,	KEY_PASTE,	KEY_FIND,	KEY_MUTE,
79 	/* 0x80 - 0x9f */
80 	KEY_VOLUMEUP,	KEY_VOLUMEDOWN,	NONE,		NONE,
81 	NONE,		KEY_KPCOMMA,	NONE,		KEY_RO,
82 	KEY_KATAKANAHIRAGANA,	KEY_YEN,KEY_HENKAN,	KEY_MUHENKAN,
83 	KEY_KPJPCOMMA,	NONE,		NONE,		NONE,
84 	KEY_HANGEUL,	KEY_HANJA,	KEY_KATAKANA,	KEY_HIRAGANA,
85 	KEY_ZENKAKUHANKAKU,	NONE,	NONE,		NONE,
86 	NONE,		NONE,		NONE,		NONE,
87 	NONE,		NONE,		NONE,		NONE,
88 	/* 0xa0 - 0xbf */
89 	NONE,		NONE,		NONE,		NONE,
90 	NONE,		NONE,		NONE,		NONE,
91 	NONE,		NONE,		NONE,		NONE,
92 	NONE,		NONE,		NONE,		NONE,
93 	NONE,		NONE,		NONE,		NONE,
94 	NONE,		NONE,		NONE,		NONE,
95 	NONE,		NONE,		NONE,		NONE,
96 	NONE,		NONE,		NONE,		NONE,
97 	/* 0xc0 - 0xdf */
98 	NONE,		NONE,		NONE,		NONE,
99 	NONE,		NONE,		NONE,		NONE,
100 	NONE,		NONE,		NONE,		NONE,
101 	NONE,		NONE,		NONE,		NONE,
102 	NONE,		NONE,		NONE,		NONE,
103 	NONE,		NONE,		NONE,		NONE,
104 	NONE,		NONE,		NONE,		NONE,
105 	NONE,		NONE,		NONE,		NONE,
106 	/* 0xe0 - 0xff */
107 	KEY_LEFTCTRL,	KEY_LEFTSHIFT,	KEY_LEFTALT,	KEY_LEFTMETA,
108 	KEY_RIGHTCTRL,	KEY_RIGHTSHIFT,	KEY_RIGHTALT,	KEY_RIGHTMETA,
109 	KEY_PLAYPAUSE,	KEY_STOPCD,	KEY_PREVIOUSSONG,KEY_NEXTSONG,
110 	KEY_EJECTCD,	KEY_VOLUMEUP,	KEY_VOLUMEDOWN,	KEY_MUTE,
111 	KEY_WWW,	KEY_BACK,	KEY_FORWARD,	KEY_STOP,
112 	KEY_FIND,	KEY_SCROLLUP,	KEY_SCROLLDOWN,	KEY_EDIT,
113 	KEY_SLEEP,	KEY_COFFEE,	KEY_REFRESH,	KEY_CALC,
114 	NONE,		NONE,		NONE,		NONE,
115 
116 };
117 
118 static uint16_t evdev_at_set1_scancodes[] = {
119 	/* 0x00 - 0x1f */
120 	NONE,		KEY_ESC,	KEY_1,		KEY_2,
121 	KEY_3,		KEY_4,		KEY_5,		KEY_6,
122 	KEY_7,		KEY_8,		KEY_9,		KEY_0,
123 	KEY_MINUS,	KEY_EQUAL,	KEY_BACKSPACE,	KEY_TAB,
124 	KEY_Q,		KEY_W,		KEY_E,		KEY_R,
125 	KEY_T,		KEY_Y,		KEY_U,		KEY_I,
126 	KEY_O,		KEY_P,		KEY_LEFTBRACE,	KEY_RIGHTBRACE,
127 	KEY_ENTER,	KEY_LEFTCTRL,	KEY_A,		KEY_S,
128 	/* 0x20 - 0x3f */
129 	KEY_D,		KEY_F,		KEY_G,		KEY_H,
130 	KEY_J,		KEY_K,		KEY_L,		KEY_SEMICOLON,
131 	KEY_APOSTROPHE,	KEY_GRAVE,	KEY_LEFTSHIFT,	KEY_BACKSLASH,
132 	KEY_Z,		KEY_X,		KEY_C,		KEY_V,
133 	KEY_B,		KEY_N,		KEY_M,		KEY_COMMA,
134 	KEY_DOT,	KEY_SLASH,	KEY_RIGHTSHIFT,	KEY_KPASTERISK,
135 	KEY_LEFTALT,	KEY_SPACE,	KEY_CAPSLOCK,	KEY_F1,
136 	KEY_F2,		KEY_F3,		KEY_F4,		KEY_F5,
137 	/* 0x40 - 0x5f */
138 	KEY_F6,		KEY_F7,		KEY_F8,		KEY_F9,
139 	KEY_F10,	KEY_NUMLOCK,	KEY_SCROLLLOCK,	KEY_KP7,
140 	KEY_KP8,	KEY_KP9,	KEY_KPMINUS,	KEY_KP4,
141 	KEY_KP5,	KEY_KP6,	KEY_KPPLUS,	KEY_KP1,
142 	KEY_KP2,	KEY_KP3,	KEY_KP0,	KEY_KPDOT,
143 	NONE,		NONE,		KEY_102ND,	KEY_F11,
144 	KEY_F12,	NONE,		NONE,		NONE,
145 	NONE,		NONE,		NONE,		NONE,
146 	/* 0x60 - 0x7f */
147 	NONE,		NONE,		NONE,		NONE,
148 	NONE,		NONE,		NONE,		NONE,
149 	NONE,		NONE,		NONE,		NONE,
150 	NONE,		NONE,		NONE,		NONE,
151 	KEY_KATAKANAHIRAGANA,	NONE,	NONE,		KEY_RO,
152 	NONE,		NONE,	KEY_ZENKAKUHANKAKU,	KEY_HIRAGANA,
153 	KEY_KATAKANA,	KEY_HENKAN,	NONE,		KEY_MUHENKAN,
154 	NONE,		KEY_YEN,	KEY_KPCOMMA,	NONE,
155 	/* 0x00 - 0x1f. 0xE0 prefixed */
156 	NONE,		NONE,		NONE,		NONE,
157 	NONE,		NONE,		NONE,		NONE,
158 	NONE,		NONE,		NONE,		NONE,
159 	NONE,		NONE,		NONE,		NONE,
160 	KEY_PREVIOUSSONG,	NONE,	NONE,		NONE,
161 	NONE,		NONE,		NONE,		NONE,
162 	NONE,		KEY_NEXTSONG,	NONE,		NONE,
163 	KEY_KPENTER,	KEY_RIGHTCTRL,	NONE,		NONE,
164 	/* 0x20 - 0x3f. 0xE0 prefixed */
165 	KEY_MUTE,	KEY_CALC,	KEY_PLAYPAUSE,	NONE,
166 	KEY_STOPCD,	NONE,		NONE,		NONE,
167 	NONE,		NONE,		NONE,		NONE,
168 	NONE,		NONE,		KEY_VOLUMEDOWN,	NONE,
169 	KEY_VOLUMEUP,	NONE,		KEY_HOMEPAGE,	NONE,
170 	NONE,		KEY_KPSLASH,	NONE,		KEY_SYSRQ,
171 	KEY_RIGHTALT,	NONE,		NONE,		NONE,
172 	NONE,		NONE,		NONE,		NONE,
173 	/* 0x40 - 0x5f. 0xE0 prefixed */
174 	NONE,		NONE,		NONE,		NONE,
175 	NONE,		NONE,		KEY_PAUSE,	KEY_HOME,
176 	KEY_UP,		KEY_PAGEUP,	NONE,		KEY_LEFT,
177 	NONE,		KEY_RIGHT,	NONE,		KEY_END,
178 	KEY_DOWN,	KEY_PAGEDOWN,	KEY_INSERT,	KEY_DELETE,
179 	NONE,		NONE,		NONE,		NONE,
180 	NONE,		NONE,		NONE,		KEY_LEFTMETA,
181 	KEY_RIGHTMETA,	KEY_MENU,	KEY_POWER,	KEY_SLEEP,
182 	/* 0x60 - 0x7f. 0xE0 prefixed */
183 	NONE,		NONE,		NONE,		KEY_WAKEUP,
184 	NONE,		KEY_SEARCH,	KEY_BOOKMARKS,	KEY_REFRESH,
185 	KEY_STOP,	KEY_FORWARD,	KEY_BACK,	KEY_COMPUTER,
186 	KEY_MAIL,	KEY_MEDIA,	NONE,		NONE,
187 	NONE,		NONE,		NONE,		NONE,
188 	NONE,		NONE,		NONE,		NONE,
189 	NONE,		NONE,		NONE,		NONE,
190 	NONE,		NONE,		NONE,		NONE,
191 };
192 
193 static uint16_t evdev_mouse_button_codes[] = {
194 	BTN_LEFT,
195 	BTN_MIDDLE,
196 	BTN_RIGHT,
197 	BTN_SIDE,
198 	BTN_EXTRA,
199 	BTN_FORWARD,
200 	BTN_BACK,
201 	BTN_TASK,
202 };
203 
204 static uint16_t evdev_led_codes[] = {
205 	LED_CAPSL,	/* CLKED */
206 	LED_NUML,	/* NLKED */
207 	LED_SCROLLL,	/* SLKED */
208 };
209 
210 uint16_t
211 evdev_hid2key(int scancode)
212 {
213 	return evdev_usb_scancodes[scancode];
214 }
215 
216 void
217 evdev_support_all_known_keys(struct evdev_dev *evdev)
218 {
219 	size_t i;
220 
221 	for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
222 		if (evdev_at_set1_scancodes[i] != NONE)
223 			evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
224 }
225 
226 uint16_t
227 evdev_scancode2key(int *state, int scancode)
228 {
229 	uint16_t keycode;
230 
231 	/* translate the scan code into a keycode */
232 	keycode = evdev_at_set1_scancodes[scancode & 0x7f];
233 	switch (*state) {
234 	case 0x00:	/* normal scancode */
235 		switch(scancode) {
236 		case 0xE0:
237 		case 0xE1:
238 			*state = scancode;
239 			return (NONE);
240 		}
241 		break;
242 	case 0xE0:		/* 0xE0 prefix */
243 		*state = 0;
244 		keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
245 		break;
246 	case 0xE1:	/* 0xE1 prefix */
247 		/*
248 		 * The pause/break key on the 101 keyboard produces:
249 		 * E1-1D-45 E1-9D-C5
250 		 * Ctrl-pause/break produces:
251 		 * E0-46 E0-C6 (See above.)
252 		 */
253 		*state = 0;
254 		if ((scancode & 0x7f) == 0x1D)
255 			*state = 0x1D;
256 		return (NONE);
257 		/* NOT REACHED */
258 	case 0x1D:	/* pause / break */
259 		*state = 0;
260 		if (scancode != 0x45)
261 			return (NONE);
262 		keycode = KEY_PAUSE;
263 		break;
264 	}
265 
266 	return (keycode);
267 }
268 
269 void
270 evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
271 {
272 	size_t i;
273 
274 	for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
275 		evdev_push_key(evdev, evdev_mouse_button_codes[i],
276 		    buttons & (1 << i));
277 }
278 
279 void
280 evdev_push_leds(struct evdev_dev *evdev, int leds)
281 {
282 	size_t i;
283 
284 	/* Some drivers initialize leds before evdev */
285 	if (evdev == NULL)
286 		return;
287 
288 	for (i = 0; i < nitems(evdev_led_codes); i++)
289 		evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
290 }
291 
292 void
293 evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
294 {
295 	/* Some drivers initialize typematics before evdev */
296 	if (evdev == NULL)
297 		return;
298 
299 	evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
300 	evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
301 }
302 
303 void
304 evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type,
305     uint16_t code, int32_t value)
306 {
307 	keyboard_t *kbd = (keyboard_t *)softc;
308 	int delay[2], leds, oleds;
309 	size_t i;
310 
311 	if (type == EV_LED) {
312 		leds = oleds = KBD_LED_VAL(kbd);
313 		for (i = 0; i < nitems(evdev_led_codes); i++) {
314 			if (evdev_led_codes[i] == code) {
315 				if (value)
316 					leds |= 1 << i;
317 				else
318 					leds &= ~(1 << i);
319 				if (leds != oleds) {
320 					mtx_lock(&Giant);
321 					kbdd_ioctl(kbd, KDSETLED,
322 					    (caddr_t)&leds);
323 					mtx_unlock(&Giant);
324 				}
325 				break;
326 			}
327 		}
328 	} else if (type == EV_REP && code == REP_DELAY) {
329 		delay[0] = value;
330 		delay[1] = kbd->kb_delay2;
331 		mtx_lock(&Giant);
332 		kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
333 		mtx_unlock(&Giant);
334 	} else if (type == EV_REP && code == REP_PERIOD) {
335 		delay[0] = kbd->kb_delay1;
336 		delay[1] = value;
337 		mtx_lock(&Giant);
338 		kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
339 		mtx_unlock(&Giant);
340 	}
341 }
342