kernel - Bring in evdev from FreeBSD
[dragonfly.git] / sys / dev / misc / evdev / evdev_utils.c
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/malloc.h>
36 #include <sys/systm.h>
37
38 #include <dev/misc/evdev/evdev.h>
39 #include <dev/misc/evdev/input.h>
40 #include <dev/misc/kbd/kbdreg.h>
41
42 #define NONE    KEY_RESERVED
43
44 static uint16_t evdev_usb_scancodes[256] = {
45         /* 0x00 - 0x27 */
46         NONE,   NONE,   NONE,   NONE,   KEY_A,  KEY_B,  KEY_C,  KEY_D,
47         KEY_E,  KEY_F,  KEY_G,  KEY_H,  KEY_I,  KEY_J,  KEY_K,  KEY_L,
48         KEY_M,  KEY_N,  KEY_O,  KEY_P,  KEY_Q,  KEY_R,  KEY_S,  KEY_T,
49         KEY_U,  KEY_V,  KEY_W,  KEY_X,  KEY_Y,  KEY_Z,  KEY_1,  KEY_2,
50         KEY_3,  KEY_4,  KEY_5,  KEY_6,  KEY_7,  KEY_8,  KEY_9,  KEY_0,
51         /* 0x28 - 0x3f */
52         KEY_ENTER,      KEY_ESC,        KEY_BACKSPACE,  KEY_TAB,
53         KEY_SPACE,      KEY_MINUS,      KEY_EQUAL,      KEY_LEFTBRACE,
54         KEY_RIGHTBRACE, KEY_BACKSLASH,  KEY_BACKSLASH,  KEY_SEMICOLON,
55         KEY_APOSTROPHE, KEY_GRAVE,      KEY_COMMA,      KEY_DOT,
56         KEY_SLASH,      KEY_CAPSLOCK,   KEY_F1,         KEY_F2,
57         KEY_F3,         KEY_F4,         KEY_F5,         KEY_F6,
58         /* 0x40 - 0x5f */
59         KEY_F7,         KEY_F8,         KEY_F9,         KEY_F10,
60         KEY_F11,        KEY_F12,        KEY_SYSRQ,      KEY_SCROLLLOCK,
61         KEY_PAUSE,      KEY_INSERT,     KEY_HOME,       KEY_PAGEUP,
62         KEY_DELETE,     KEY_END,        KEY_PAGEDOWN,   KEY_RIGHT,
63         KEY_LEFT,       KEY_DOWN,       KEY_UP,         KEY_NUMLOCK,
64         KEY_SLASH,      KEY_KPASTERISK, KEY_KPMINUS,    KEY_KPPLUS,
65         KEY_KPENTER,    KEY_KP1,        KEY_KP2,        KEY_KP3,
66         KEY_KP4,        KEY_KP5,        KEY_KP6,        KEY_KP7,
67         /* 0x60 - 0x7f */
68         KEY_KP8,        KEY_KP9,        KEY_KP0,        KEY_KPDOT,
69         KEY_102ND,      KEY_COMPOSE,    KEY_POWER,      KEY_KPEQUAL,
70         KEY_F13,        KEY_F14,        KEY_F15,        KEY_F16,
71         KEY_F17,        KEY_F18,        KEY_F19,        KEY_F20,
72         KEY_F21,        KEY_F22,        KEY_F23,        KEY_F24,
73         KEY_OPEN,       KEY_HELP,       KEY_PROPS,      KEY_FRONT,
74         KEY_STOP,       KEY_AGAIN,      KEY_UNDO,       KEY_CUT,
75         KEY_COPY,       KEY_PASTE,      KEY_FIND,       KEY_MUTE,
76         /* 0x80 - 0x9f */
77         KEY_VOLUMEUP,   KEY_VOLUMEDOWN, NONE,           NONE,
78         NONE,           KEY_KPCOMMA,    NONE,           KEY_RO,
79         KEY_KATAKANAHIRAGANA,   KEY_YEN,KEY_HENKAN,     KEY_MUHENKAN,
80         KEY_KPJPCOMMA,  NONE,           NONE,           NONE,
81         KEY_HANGEUL,    KEY_HANJA,      KEY_KATAKANA,   KEY_HIRAGANA,
82         KEY_ZENKAKUHANKAKU,     NONE,   NONE,           NONE,
83         NONE,           NONE,           NONE,           NONE,
84         NONE,           NONE,           NONE,           NONE,
85         /* 0xa0 - 0xbf */
86         NONE,           NONE,           NONE,           NONE,
87         NONE,           NONE,           NONE,           NONE,
88         NONE,           NONE,           NONE,           NONE,
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         /* 0xc0 - 0xdf */
95         NONE,           NONE,           NONE,           NONE,
96         NONE,           NONE,           NONE,           NONE,
97         NONE,           NONE,           NONE,           NONE,
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         /* 0xe0 - 0xff */
104         KEY_LEFTCTRL,   KEY_LEFTSHIFT,  KEY_LEFTALT,    KEY_LEFTMETA,
105         KEY_RIGHTCTRL,  KEY_RIGHTSHIFT, KEY_RIGHTALT,   KEY_RIGHTMETA,
106         KEY_PLAYPAUSE,  KEY_STOPCD,     KEY_PREVIOUSSONG,KEY_NEXTSONG,
107         KEY_EJECTCD,    KEY_VOLUMEUP,   KEY_VOLUMEDOWN, KEY_MUTE,
108         KEY_WWW,        KEY_BACK,       KEY_FORWARD,    KEY_STOP,
109         KEY_FIND,       KEY_SCROLLUP,   KEY_SCROLLDOWN, KEY_EDIT,
110         KEY_SLEEP,      KEY_COFFEE,     KEY_REFRESH,    KEY_CALC,
111         NONE,           NONE,           NONE,           NONE,
112
113 };
114
115 static uint16_t evdev_at_set1_scancodes[] = {
116         /* 0x00 - 0x1f */
117         NONE,           KEY_ESC,        KEY_1,          KEY_2,
118         KEY_3,          KEY_4,          KEY_5,          KEY_6,
119         KEY_7,          KEY_8,          KEY_9,          KEY_0,
120         KEY_MINUS,      KEY_EQUAL,      KEY_BACKSPACE,  KEY_TAB,
121         KEY_Q,          KEY_W,          KEY_E,          KEY_R,
122         KEY_T,          KEY_Y,          KEY_U,          KEY_I,
123         KEY_O,          KEY_P,          KEY_LEFTBRACE,  KEY_RIGHTBRACE,
124         KEY_ENTER,      KEY_LEFTCTRL,   KEY_A,          KEY_S,
125         /* 0x20 - 0x3f */
126         KEY_D,          KEY_F,          KEY_G,          KEY_H,
127         KEY_J,          KEY_K,          KEY_L,          KEY_SEMICOLON,
128         KEY_APOSTROPHE, KEY_GRAVE,      KEY_LEFTSHIFT,  KEY_BACKSLASH,
129         KEY_Z,          KEY_X,          KEY_C,          KEY_V,
130         KEY_B,          KEY_N,          KEY_M,          KEY_COMMA,
131         KEY_DOT,        KEY_SLASH,      KEY_RIGHTSHIFT, NONE,
132         KEY_LEFTALT,    KEY_SPACE,      KEY_CAPSLOCK,   KEY_F1,
133         KEY_F2,         KEY_F3,         KEY_F4,         KEY_F5,
134         /* 0x40 - 0x5f */
135         KEY_F6,         KEY_F7,         KEY_F8,         KEY_F9,
136         KEY_F10,        KEY_NUMLOCK,    KEY_SCROLLLOCK, KEY_KP7,
137         KEY_KP8,        KEY_KP9,        KEY_KPMINUS,    KEY_KP4,
138         KEY_KP5,        KEY_KP6,        KEY_KPPLUS,     KEY_KP1,
139         KEY_KP2,        KEY_KP3,        KEY_KP0,        KEY_KPDOT,
140         NONE,           NONE,           NONE,           KEY_F11,
141         KEY_F12,        NONE,           NONE,           NONE,
142         NONE,           NONE,           NONE,           NONE,
143         /* 0x60 - 0x7f */
144         NONE,           NONE,           NONE,           NONE,
145         NONE,           NONE,           NONE,           NONE,
146         NONE,           NONE,           NONE,           NONE,
147         NONE,           NONE,           NONE,           NONE,
148         KEY_KATAKANAHIRAGANA,   NONE,   NONE,           KEY_RO,
149         NONE,           NONE,   KEY_ZENKAKUHANKAKU,     KEY_HIRAGANA,
150         KEY_KATAKANA,   KEY_HENKAN,     NONE,           KEY_MUHENKAN,
151         NONE,           KEY_YEN,        KEY_KPCOMMA,    NONE,
152         /* 0x00 - 0x1f. 0xE0 prefixed */
153         NONE,           NONE,           NONE,           NONE,
154         NONE,           NONE,           NONE,           NONE,
155         NONE,           NONE,           NONE,           NONE,
156         NONE,           NONE,           NONE,           NONE,
157         KEY_PREVIOUSSONG,       NONE,   NONE,           NONE,
158         NONE,           NONE,           NONE,           NONE,
159         NONE,           KEY_NEXTSONG,   NONE,           NONE,
160         KEY_KPENTER,    KEY_RIGHTCTRL,  NONE,           NONE,
161         /* 0x20 - 0x3f. 0xE0 prefixed */
162         KEY_MUTE,       KEY_CALC,       KEY_PLAYPAUSE,  NONE,
163         KEY_STOPCD,     NONE,           NONE,           NONE,
164         NONE,           NONE,           NONE,           NONE,
165         NONE,           NONE,           KEY_VOLUMEDOWN, NONE,
166         KEY_VOLUMEUP,   NONE,           KEY_HOMEPAGE,   NONE,
167         NONE,           KEY_KPASTERISK, NONE,           KEY_SYSRQ,
168         KEY_RIGHTALT,   NONE,           NONE,           NONE,
169         NONE,           NONE,           NONE,           NONE,
170         /* 0x40 - 0x5f. 0xE0 prefixed */
171         NONE,           NONE,           NONE,           NONE,
172         NONE,           NONE,           KEY_PAUSE,      KEY_HOME,
173         KEY_UP,         KEY_PAGEUP,     NONE,           KEY_LEFT,
174         NONE,           KEY_RIGHT,      NONE,           KEY_END,
175         KEY_DOWN,       KEY_PAGEDOWN,   KEY_INSERT,     KEY_DELETE,
176         NONE,           NONE,           NONE,           NONE,
177         NONE,           NONE,           NONE,           KEY_LEFTMETA,
178         KEY_RIGHTMETA,  KEY_MENU,       KEY_POWER,      KEY_SLEEP,
179         /* 0x60 - 0x7f. 0xE0 prefixed */
180         NONE,           NONE,           NONE,           KEY_WAKEUP,
181         NONE,           KEY_SEARCH,     KEY_BOOKMARKS,  KEY_REFRESH,
182         KEY_STOP,       KEY_FORWARD,    KEY_BACK,       KEY_COMPUTER,
183         KEY_MAIL,       KEY_MEDIA,      NONE,           NONE,
184         NONE,           NONE,           NONE,           NONE,
185         NONE,           NONE,           NONE,           NONE,
186         NONE,           NONE,           NONE,           NONE,
187         NONE,           NONE,           NONE,           NONE,
188 };
189
190 static uint16_t evdev_mouse_button_codes[] = {
191         BTN_LEFT,
192         BTN_MIDDLE,
193         BTN_RIGHT,
194         BTN_SIDE,
195         BTN_EXTRA,
196         BTN_FORWARD,
197         BTN_BACK,
198         BTN_TASK,
199 };
200
201 static uint16_t evdev_led_codes[] = {
202         LED_CAPSL,      /* CLKED */
203         LED_NUML,       /* NLKED */
204         LED_SCROLLL,    /* SLKED */
205 };
206
207 uint16_t
208 evdev_hid2key(int scancode)
209 {
210         return evdev_usb_scancodes[scancode];
211 }
212
213 void
214 evdev_support_all_known_keys(struct evdev_dev *evdev)
215 {
216         size_t i;
217
218         for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
219                 if (evdev_at_set1_scancodes[i] != NONE)
220                         evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
221 }
222
223 uint16_t
224 evdev_scancode2key(int *state, int scancode)
225 {
226         uint16_t keycode;
227
228         /* translate the scan code into a keycode */
229         keycode = evdev_at_set1_scancodes[scancode & 0x7f];
230         switch (*state) {
231         case 0x00:      /* normal scancode */
232                 switch(scancode) {
233                 case 0xE0:
234                 case 0xE1:
235                         *state = scancode;
236                         return (NONE);
237                 }
238                 break;
239         case 0xE0:              /* 0xE0 prefix */
240                 *state = 0;
241                 keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
242                 break;
243         case 0xE1:      /* 0xE1 prefix */
244                 /*
245                  * The pause/break key on the 101 keyboard produces:
246                  * E1-1D-45 E1-9D-C5
247                  * Ctrl-pause/break produces:
248                  * E0-46 E0-C6 (See above.)
249                  */
250                 *state = 0;
251                 if ((scancode & 0x7f) == 0x1D)
252                         *state = 0x1D;
253                 return (NONE);
254                 /* NOT REACHED */
255         case 0x1D:      /* pause / break */
256                 *state = 0;
257                 if (scancode != 0x45)
258                         return (NONE);
259                 keycode = KEY_PAUSE;
260                 break;
261         }
262
263         return (keycode);
264 }
265
266 void
267 evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
268 {
269         size_t i;
270
271         for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
272                 evdev_push_key(evdev, evdev_mouse_button_codes[i],
273                     buttons & (1 << i));
274 }
275
276 void
277 evdev_push_leds(struct evdev_dev *evdev, int leds)
278 {
279         size_t i;
280
281         /* Some drivers initialize leds before evdev */
282         if (evdev == NULL)
283                 return;
284
285         for (i = 0; i < nitems(evdev_led_codes); i++)
286                 evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
287 }
288
289 void
290 evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
291 {
292         /* Some drivers initialize typematics before evdev */
293         if (evdev == NULL)
294                 return;
295
296         evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
297         evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
298 }
299
300 void
301 evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type,
302     uint16_t code, int32_t value)
303 {
304         keyboard_t *kbd = (keyboard_t *)softc;
305         int delay[2], leds, oleds;
306         size_t i;
307
308         if (type == EV_LED) {
309                 leds = oleds = KBD_LED_VAL(kbd);
310                 for (i = 0; i < nitems(evdev_led_codes); i++) {
311                         if (evdev_led_codes[i] == code) {
312                                 if (value)
313                                         leds |= 1 << i;
314                                 else
315                                         leds &= ~(1 << i);
316                                 if (leds != oleds)
317                                         kbd_ioctl(kbd, KDSETLED,
318                                             (caddr_t)&leds);
319                                 break;
320                         }
321                 }
322         } else if (type == EV_REP && code == REP_DELAY) {
323                 delay[0] = value;
324                 delay[1] = kbd->kb_delay2;
325                 kbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
326         } else if (type == EV_REP && code == REP_PERIOD) {
327                 delay[0] = kbd->kb_delay1;
328                 delay[1] = value;
329                 kbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
330         }
331 }