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: stable/11/sys/dev/evdev/evdev_utils.c 362598 2020-06-25 00:01:24Z wulf $
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
47static 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
118static 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
193static 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
204static uint16_t evdev_led_codes[] = {
205	LED_CAPSL,	/* CLKED */
206	LED_NUML,	/* NLKED */
207	LED_SCROLLL,	/* SLKED */
208};
209
210uint16_t
211evdev_hid2key(int scancode)
212{
213	return evdev_usb_scancodes[scancode];
214}
215
216void
217evdev_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
226uint16_t
227evdev_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
272void
273evdev_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
282void
283evdev_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
295void
296evdev_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
306void
307evdev_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