xref: /freebsd-11-stable/sys/dev/evdev/evdev_utils.c (revision 0725c8af2d44d63bee945718002be87044927786)
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,	KEY_HANGEUL,	KEY_HANJA,	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,		KEY_F13,
172 	KEY_F14,	KEY_F15,	KEY_F16,	KEY_F17,
173 	/* 0x40 - 0x5f. 0xE0 prefixed */
174 	KEY_F18,	KEY_F19,	KEY_F20,	KEY_F21,
175 	KEY_F22,	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,		KEY_F23,
180 	KEY_F24,	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
evdev_hid2key(int scancode)211 evdev_hid2key(int scancode)
212 {
213 	return evdev_usb_scancodes[scancode];
214 }
215 
216 void
evdev_support_all_known_keys(struct evdev_dev * evdev)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
evdev_scancode2key(int * state,int scancode)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 = scancode;
256 		return (NONE);
257 		/* NOT REACHED */
258 	case 0x1D:	/* pause / break */
259 	case 0x9D:
260 		if ((*state ^ scancode) & 0x80)
261 			return (NONE);
262 		*state = 0;
263 		if ((scancode & 0x7f) != 0x45)
264 			return (NONE);
265 		keycode = KEY_PAUSE;
266 		break;
267 	}
268 
269 	return (keycode);
270 }
271 
272 void
evdev_push_mouse_btn(struct evdev_dev * evdev,int buttons)273 evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
274 {
275 	size_t i;
276 
277 	for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
278 		evdev_push_key(evdev, evdev_mouse_button_codes[i],
279 		    buttons & (1 << i));
280 }
281 
282 void
evdev_push_leds(struct evdev_dev * evdev,int leds)283 evdev_push_leds(struct evdev_dev *evdev, int leds)
284 {
285 	size_t i;
286 
287 	/* Some drivers initialize leds before evdev */
288 	if (evdev == NULL)
289 		return;
290 
291 	for (i = 0; i < nitems(evdev_led_codes); i++)
292 		evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
293 }
294 
295 void
evdev_push_repeats(struct evdev_dev * evdev,keyboard_t * kbd)296 evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
297 {
298 	/* Some drivers initialize typematics before evdev */
299 	if (evdev == NULL)
300 		return;
301 
302 	evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
303 	evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
304 }
305 
306 void
evdev_ev_kbd_event(struct evdev_dev * evdev,void * softc,uint16_t type,uint16_t code,int32_t value)307 evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type,
308     uint16_t code, int32_t value)
309 {
310 	keyboard_t *kbd = (keyboard_t *)softc;
311 	int delay[2], leds, oleds;
312 	size_t i;
313 
314 	if (type == EV_LED) {
315 		leds = oleds = KBD_LED_VAL(kbd);
316 		for (i = 0; i < nitems(evdev_led_codes); i++) {
317 			if (evdev_led_codes[i] == code) {
318 				if (value)
319 					leds |= 1 << i;
320 				else
321 					leds &= ~(1 << i);
322 				if (leds != oleds) {
323 					mtx_lock(&Giant);
324 					kbdd_ioctl(kbd, KDSETLED,
325 					    (caddr_t)&leds);
326 					mtx_unlock(&Giant);
327 				}
328 				break;
329 			}
330 		}
331 	} else if (type == EV_REP && code == REP_DELAY) {
332 		delay[0] = value;
333 		delay[1] = kbd->kb_delay2;
334 		mtx_lock(&Giant);
335 		kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
336 		mtx_unlock(&Giant);
337 	} else if (type == EV_REP && code == REP_PERIOD) {
338 		delay[0] = kbd->kb_delay1;
339 		delay[1] = value;
340 		mtx_lock(&Giant);
341 		kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
342 		mtx_unlock(&Giant);
343 	}
344 }
345