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