12b3f6d66SOleksandr Tymoshenko /*-
22b3f6d66SOleksandr Tymoshenko * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org>
3e6502802SVladimir Kondratyev * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@FreeBSD.org>
42b3f6d66SOleksandr Tymoshenko * All rights reserved.
52b3f6d66SOleksandr Tymoshenko *
62b3f6d66SOleksandr Tymoshenko * Redistribution and use in source and binary forms, with or without
72b3f6d66SOleksandr Tymoshenko * modification, are permitted provided that the following conditions
82b3f6d66SOleksandr Tymoshenko * are met:
92b3f6d66SOleksandr Tymoshenko * 1. Redistributions of source code must retain the above copyright
102b3f6d66SOleksandr Tymoshenko * notice, this list of conditions and the following disclaimer.
112b3f6d66SOleksandr Tymoshenko * 2. Redistributions in binary form must reproduce the above copyright
122b3f6d66SOleksandr Tymoshenko * notice, this list of conditions and the following disclaimer in the
132b3f6d66SOleksandr Tymoshenko * documentation and/or other materials provided with the distribution.
142b3f6d66SOleksandr Tymoshenko *
152b3f6d66SOleksandr Tymoshenko * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
162b3f6d66SOleksandr Tymoshenko * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
172b3f6d66SOleksandr Tymoshenko * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
182b3f6d66SOleksandr Tymoshenko * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
192b3f6d66SOleksandr Tymoshenko * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
202b3f6d66SOleksandr Tymoshenko * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
212b3f6d66SOleksandr Tymoshenko * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
222b3f6d66SOleksandr Tymoshenko * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
232b3f6d66SOleksandr Tymoshenko * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
242b3f6d66SOleksandr Tymoshenko * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
252b3f6d66SOleksandr Tymoshenko * SUCH DAMAGE.
262b3f6d66SOleksandr Tymoshenko */
272b3f6d66SOleksandr Tymoshenko
282b3f6d66SOleksandr Tymoshenko #include <sys/param.h>
292b3f6d66SOleksandr Tymoshenko #include <sys/bus.h>
302b3f6d66SOleksandr Tymoshenko #include <sys/conf.h>
312b3f6d66SOleksandr Tymoshenko #include <sys/kbio.h>
32ea2e26b1SVladimir Kondratyev #include <sys/kernel.h>
33f7ee4f90SVladimir Kondratyev #include <sys/lock.h>
34ea2e26b1SVladimir Kondratyev #include <sys/malloc.h>
35f7ee4f90SVladimir Kondratyev #include <sys/mutex.h>
36ea2e26b1SVladimir Kondratyev #include <sys/systm.h>
372b3f6d66SOleksandr Tymoshenko
382b3f6d66SOleksandr Tymoshenko #include <dev/evdev/evdev.h>
3998a7606bSVladimir Kondratyev #include <dev/evdev/evdev_private.h>
40ea2e26b1SVladimir Kondratyev #include <dev/evdev/input.h>
412b3f6d66SOleksandr Tymoshenko
422b3f6d66SOleksandr Tymoshenko #define NONE KEY_RESERVED
432b3f6d66SOleksandr Tymoshenko
442b3f6d66SOleksandr Tymoshenko static uint16_t evdev_usb_scancodes[256] = {
452b3f6d66SOleksandr Tymoshenko /* 0x00 - 0x27 */
462b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE, KEY_A, KEY_B, KEY_C, KEY_D,
472b3f6d66SOleksandr Tymoshenko KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
482b3f6d66SOleksandr Tymoshenko KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
492b3f6d66SOleksandr Tymoshenko KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2,
502b3f6d66SOleksandr Tymoshenko KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
512b3f6d66SOleksandr Tymoshenko /* 0x28 - 0x3f */
522b3f6d66SOleksandr Tymoshenko KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB,
532b3f6d66SOleksandr Tymoshenko KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE,
542b3f6d66SOleksandr Tymoshenko KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON,
552b3f6d66SOleksandr Tymoshenko KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA, KEY_DOT,
562b3f6d66SOleksandr Tymoshenko KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2,
572b3f6d66SOleksandr Tymoshenko KEY_F3, KEY_F4, KEY_F5, KEY_F6,
582b3f6d66SOleksandr Tymoshenko /* 0x40 - 0x5f */
592b3f6d66SOleksandr Tymoshenko KEY_F7, KEY_F8, KEY_F9, KEY_F10,
602b3f6d66SOleksandr Tymoshenko KEY_F11, KEY_F12, KEY_SYSRQ, KEY_SCROLLLOCK,
612b3f6d66SOleksandr Tymoshenko KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP,
622b3f6d66SOleksandr Tymoshenko KEY_DELETE, KEY_END, KEY_PAGEDOWN, KEY_RIGHT,
632b3f6d66SOleksandr Tymoshenko KEY_LEFT, KEY_DOWN, KEY_UP, KEY_NUMLOCK,
643e10195cSVladimir Kondratyev KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS,
652b3f6d66SOleksandr Tymoshenko KEY_KPENTER, KEY_KP1, KEY_KP2, KEY_KP3,
662b3f6d66SOleksandr Tymoshenko KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7,
672b3f6d66SOleksandr Tymoshenko /* 0x60 - 0x7f */
682b3f6d66SOleksandr Tymoshenko KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT,
692b3f6d66SOleksandr Tymoshenko KEY_102ND, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL,
702b3f6d66SOleksandr Tymoshenko KEY_F13, KEY_F14, KEY_F15, KEY_F16,
712b3f6d66SOleksandr Tymoshenko KEY_F17, KEY_F18, KEY_F19, KEY_F20,
722b3f6d66SOleksandr Tymoshenko KEY_F21, KEY_F22, KEY_F23, KEY_F24,
732b3f6d66SOleksandr Tymoshenko KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT,
742b3f6d66SOleksandr Tymoshenko KEY_STOP, KEY_AGAIN, KEY_UNDO, KEY_CUT,
752b3f6d66SOleksandr Tymoshenko KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE,
762b3f6d66SOleksandr Tymoshenko /* 0x80 - 0x9f */
772b3f6d66SOleksandr Tymoshenko KEY_VOLUMEUP, KEY_VOLUMEDOWN, NONE, NONE,
782b3f6d66SOleksandr Tymoshenko NONE, KEY_KPCOMMA, NONE, KEY_RO,
792b3f6d66SOleksandr Tymoshenko KEY_KATAKANAHIRAGANA, KEY_YEN,KEY_HENKAN, KEY_MUHENKAN,
802b3f6d66SOleksandr Tymoshenko KEY_KPJPCOMMA, NONE, NONE, NONE,
812b3f6d66SOleksandr Tymoshenko KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA,
822b3f6d66SOleksandr Tymoshenko KEY_ZENKAKUHANKAKU, NONE, NONE, NONE,
832b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
842b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
852b3f6d66SOleksandr Tymoshenko /* 0xa0 - 0xbf */
862b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
872b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
882b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
892b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
902b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
912b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
922b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
932b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
942b3f6d66SOleksandr Tymoshenko /* 0xc0 - 0xdf */
952b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
962b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
972b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
982b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
992b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1002b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1012b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1022b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1032b3f6d66SOleksandr Tymoshenko /* 0xe0 - 0xff */
1042b3f6d66SOleksandr Tymoshenko KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT, KEY_LEFTMETA,
1052b3f6d66SOleksandr Tymoshenko KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT, KEY_RIGHTMETA,
1062b3f6d66SOleksandr Tymoshenko KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG,KEY_NEXTSONG,
1072b3f6d66SOleksandr Tymoshenko KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
1082b3f6d66SOleksandr Tymoshenko KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP,
1092b3f6d66SOleksandr Tymoshenko KEY_FIND, KEY_SCROLLUP, KEY_SCROLLDOWN, KEY_EDIT,
1102b3f6d66SOleksandr Tymoshenko KEY_SLEEP, KEY_COFFEE, KEY_REFRESH, KEY_CALC,
1112b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1122b3f6d66SOleksandr Tymoshenko
1132b3f6d66SOleksandr Tymoshenko };
1142b3f6d66SOleksandr Tymoshenko
1152b3f6d66SOleksandr Tymoshenko static uint16_t evdev_at_set1_scancodes[] = {
1162b3f6d66SOleksandr Tymoshenko /* 0x00 - 0x1f */
1172b3f6d66SOleksandr Tymoshenko NONE, KEY_ESC, KEY_1, KEY_2,
1182b3f6d66SOleksandr Tymoshenko KEY_3, KEY_4, KEY_5, KEY_6,
1192b3f6d66SOleksandr Tymoshenko KEY_7, KEY_8, KEY_9, KEY_0,
1202b3f6d66SOleksandr Tymoshenko KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB,
1212b3f6d66SOleksandr Tymoshenko KEY_Q, KEY_W, KEY_E, KEY_R,
1222b3f6d66SOleksandr Tymoshenko KEY_T, KEY_Y, KEY_U, KEY_I,
1232b3f6d66SOleksandr Tymoshenko KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE,
1242b3f6d66SOleksandr Tymoshenko KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S,
1252b3f6d66SOleksandr Tymoshenko /* 0x20 - 0x3f */
1262b3f6d66SOleksandr Tymoshenko KEY_D, KEY_F, KEY_G, KEY_H,
1272b3f6d66SOleksandr Tymoshenko KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
1282b3f6d66SOleksandr Tymoshenko KEY_APOSTROPHE, KEY_GRAVE, KEY_LEFTSHIFT, KEY_BACKSLASH,
1292b3f6d66SOleksandr Tymoshenko KEY_Z, KEY_X, KEY_C, KEY_V,
1302b3f6d66SOleksandr Tymoshenko KEY_B, KEY_N, KEY_M, KEY_COMMA,
131b12ac17eSVladimir Kondratyev KEY_DOT, KEY_SLASH, KEY_RIGHTSHIFT, KEY_KPASTERISK,
1322b3f6d66SOleksandr Tymoshenko KEY_LEFTALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1,
1332b3f6d66SOleksandr Tymoshenko KEY_F2, KEY_F3, KEY_F4, KEY_F5,
1342b3f6d66SOleksandr Tymoshenko /* 0x40 - 0x5f */
1352b3f6d66SOleksandr Tymoshenko KEY_F6, KEY_F7, KEY_F8, KEY_F9,
1362b3f6d66SOleksandr Tymoshenko KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KP7,
1372b3f6d66SOleksandr Tymoshenko KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4,
1382b3f6d66SOleksandr Tymoshenko KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1,
1392b3f6d66SOleksandr Tymoshenko KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT,
140906b7574SJean-Sébastien Pédron NONE, NONE, KEY_102ND, KEY_F11,
1412b3f6d66SOleksandr Tymoshenko KEY_F12, NONE, NONE, NONE,
14254cca285SVladimir Kondratyev NONE, KEY_F13, NONE, NONE,
1432b3f6d66SOleksandr Tymoshenko /* 0x60 - 0x7f */
1442b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1452b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1462b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1472b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
148*6a26c99fSVladimir Kondratyev KEY_KATAKANAHIRAGANA, KEY_HANJA, KEY_HANGEUL, KEY_RO,
1492b3f6d66SOleksandr Tymoshenko NONE, NONE, KEY_ZENKAKUHANKAKU, KEY_HIRAGANA,
1502b3f6d66SOleksandr Tymoshenko KEY_KATAKANA, KEY_HENKAN, NONE, KEY_MUHENKAN,
1512b3f6d66SOleksandr Tymoshenko NONE, KEY_YEN, KEY_KPCOMMA, NONE,
1522b3f6d66SOleksandr Tymoshenko /* 0x00 - 0x1f. 0xE0 prefixed */
1532b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1542b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1552b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1562b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1572b3f6d66SOleksandr Tymoshenko KEY_PREVIOUSSONG, NONE, NONE, NONE,
1582b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1592b3f6d66SOleksandr Tymoshenko NONE, KEY_NEXTSONG, NONE, NONE,
1605bc82581SOleksandr Tymoshenko KEY_KPENTER, KEY_RIGHTCTRL, NONE, NONE,
1612b3f6d66SOleksandr Tymoshenko /* 0x20 - 0x3f. 0xE0 prefixed */
1622b3f6d66SOleksandr Tymoshenko KEY_MUTE, KEY_CALC, KEY_PLAYPAUSE, NONE,
1632b3f6d66SOleksandr Tymoshenko KEY_STOPCD, NONE, NONE, NONE,
1642b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1652b3f6d66SOleksandr Tymoshenko NONE, NONE, KEY_VOLUMEDOWN, NONE,
1662b3f6d66SOleksandr Tymoshenko KEY_VOLUMEUP, NONE, KEY_HOMEPAGE, NONE,
167b12ac17eSVladimir Kondratyev NONE, KEY_KPSLASH, NONE, KEY_SYSRQ,
1688701adbeSVladimir Kondratyev KEY_RIGHTALT, NONE, NONE, KEY_F13,
1698701adbeSVladimir Kondratyev KEY_F14, KEY_F15, KEY_F16, KEY_F17,
1702b3f6d66SOleksandr Tymoshenko /* 0x40 - 0x5f. 0xE0 prefixed */
1718701adbeSVladimir Kondratyev KEY_F18, KEY_F19, KEY_F20, KEY_F21,
1728701adbeSVladimir Kondratyev KEY_F22, NONE, KEY_PAUSE, KEY_HOME,
1732b3f6d66SOleksandr Tymoshenko KEY_UP, KEY_PAGEUP, NONE, KEY_LEFT,
1742b3f6d66SOleksandr Tymoshenko NONE, KEY_RIGHT, NONE, KEY_END,
1752b3f6d66SOleksandr Tymoshenko KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE,
1768701adbeSVladimir Kondratyev NONE, NONE, NONE, KEY_F23,
1778701adbeSVladimir Kondratyev KEY_F24, NONE, NONE, KEY_LEFTMETA,
1782b3f6d66SOleksandr Tymoshenko KEY_RIGHTMETA, KEY_MENU, KEY_POWER, KEY_SLEEP,
1792b3f6d66SOleksandr Tymoshenko /* 0x60 - 0x7f. 0xE0 prefixed */
1802b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, KEY_WAKEUP,
1812b3f6d66SOleksandr Tymoshenko NONE, KEY_SEARCH, KEY_BOOKMARKS, KEY_REFRESH,
1822b3f6d66SOleksandr Tymoshenko KEY_STOP, KEY_FORWARD, KEY_BACK, KEY_COMPUTER,
1832b3f6d66SOleksandr Tymoshenko KEY_MAIL, KEY_MEDIA, NONE, NONE,
1842b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1852b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1862b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1872b3f6d66SOleksandr Tymoshenko NONE, NONE, NONE, NONE,
1882b3f6d66SOleksandr Tymoshenko };
1892b3f6d66SOleksandr Tymoshenko
1902b3f6d66SOleksandr Tymoshenko static uint16_t evdev_mouse_button_codes[] = {
1912b3f6d66SOleksandr Tymoshenko BTN_LEFT,
1922b3f6d66SOleksandr Tymoshenko BTN_MIDDLE,
1932b3f6d66SOleksandr Tymoshenko BTN_RIGHT,
1942b3f6d66SOleksandr Tymoshenko BTN_SIDE,
1952b3f6d66SOleksandr Tymoshenko BTN_EXTRA,
1962b3f6d66SOleksandr Tymoshenko BTN_FORWARD,
1972b3f6d66SOleksandr Tymoshenko BTN_BACK,
1982b3f6d66SOleksandr Tymoshenko BTN_TASK,
1992b3f6d66SOleksandr Tymoshenko };
2002b3f6d66SOleksandr Tymoshenko
2012b3f6d66SOleksandr Tymoshenko static uint16_t evdev_led_codes[] = {
2022b3f6d66SOleksandr Tymoshenko LED_CAPSL, /* CLKED */
2032b3f6d66SOleksandr Tymoshenko LED_NUML, /* NLKED */
2042b3f6d66SOleksandr Tymoshenko LED_SCROLLL, /* SLKED */
2052b3f6d66SOleksandr Tymoshenko };
2062b3f6d66SOleksandr Tymoshenko
20798a7606bSVladimir Kondratyev static uint16_t evdev_nfinger_codes[] = {
20898a7606bSVladimir Kondratyev BTN_TOOL_FINGER,
20998a7606bSVladimir Kondratyev BTN_TOOL_DOUBLETAP,
21098a7606bSVladimir Kondratyev BTN_TOOL_TRIPLETAP,
21198a7606bSVladimir Kondratyev BTN_TOOL_QUADTAP,
21298a7606bSVladimir Kondratyev BTN_TOOL_QUINTTAP,
21398a7606bSVladimir Kondratyev };
21498a7606bSVladimir Kondratyev
21571546cd9SOleksandr Tymoshenko uint16_t
evdev_hid2key(int scancode)2162b3f6d66SOleksandr Tymoshenko evdev_hid2key(int scancode)
2172b3f6d66SOleksandr Tymoshenko {
2182b3f6d66SOleksandr Tymoshenko return evdev_usb_scancodes[scancode];
2192b3f6d66SOleksandr Tymoshenko }
2202b3f6d66SOleksandr Tymoshenko
22171546cd9SOleksandr Tymoshenko void
evdev_support_all_known_keys(struct evdev_dev * evdev)2222b3f6d66SOleksandr Tymoshenko evdev_support_all_known_keys(struct evdev_dev *evdev)
2232b3f6d66SOleksandr Tymoshenko {
2242b3f6d66SOleksandr Tymoshenko size_t i;
2252b3f6d66SOleksandr Tymoshenko
2262b3f6d66SOleksandr Tymoshenko for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
2272b3f6d66SOleksandr Tymoshenko if (evdev_at_set1_scancodes[i] != NONE)
2282b3f6d66SOleksandr Tymoshenko evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
2292b3f6d66SOleksandr Tymoshenko }
2302b3f6d66SOleksandr Tymoshenko
23171546cd9SOleksandr Tymoshenko uint16_t
evdev_scancode2key(int * state,int scancode)2322b3f6d66SOleksandr Tymoshenko evdev_scancode2key(int *state, int scancode)
2332b3f6d66SOleksandr Tymoshenko {
2342b3f6d66SOleksandr Tymoshenko uint16_t keycode;
2352b3f6d66SOleksandr Tymoshenko
2362b3f6d66SOleksandr Tymoshenko /* translate the scan code into a keycode */
2372b3f6d66SOleksandr Tymoshenko keycode = evdev_at_set1_scancodes[scancode & 0x7f];
2382b3f6d66SOleksandr Tymoshenko switch (*state) {
2392b3f6d66SOleksandr Tymoshenko case 0x00: /* normal scancode */
2402b3f6d66SOleksandr Tymoshenko switch(scancode) {
2412b3f6d66SOleksandr Tymoshenko case 0xE0:
2422b3f6d66SOleksandr Tymoshenko case 0xE1:
2432b3f6d66SOleksandr Tymoshenko *state = scancode;
2442b3f6d66SOleksandr Tymoshenko return (NONE);
2452b3f6d66SOleksandr Tymoshenko }
2462b3f6d66SOleksandr Tymoshenko break;
2472b3f6d66SOleksandr Tymoshenko case 0xE0: /* 0xE0 prefix */
2482b3f6d66SOleksandr Tymoshenko *state = 0;
2492b3f6d66SOleksandr Tymoshenko keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
2502b3f6d66SOleksandr Tymoshenko break;
2512b3f6d66SOleksandr Tymoshenko case 0xE1: /* 0xE1 prefix */
2522b3f6d66SOleksandr Tymoshenko /*
2532b3f6d66SOleksandr Tymoshenko * The pause/break key on the 101 keyboard produces:
2542b3f6d66SOleksandr Tymoshenko * E1-1D-45 E1-9D-C5
2552b3f6d66SOleksandr Tymoshenko * Ctrl-pause/break produces:
2562b3f6d66SOleksandr Tymoshenko * E0-46 E0-C6 (See above.)
2572b3f6d66SOleksandr Tymoshenko */
2582b3f6d66SOleksandr Tymoshenko *state = 0;
2592b3f6d66SOleksandr Tymoshenko if ((scancode & 0x7f) == 0x1D)
260a0e9218cSVladimir Kondratyev *state = scancode;
2612b3f6d66SOleksandr Tymoshenko return (NONE);
2622b3f6d66SOleksandr Tymoshenko /* NOT REACHED */
2632b3f6d66SOleksandr Tymoshenko case 0x1D: /* pause / break */
264a0e9218cSVladimir Kondratyev case 0x9D:
265a0e9218cSVladimir Kondratyev if ((*state ^ scancode) & 0x80)
266a0e9218cSVladimir Kondratyev return (NONE);
2672b3f6d66SOleksandr Tymoshenko *state = 0;
268a0e9218cSVladimir Kondratyev if ((scancode & 0x7f) != 0x45)
2692b3f6d66SOleksandr Tymoshenko return (NONE);
2702b3f6d66SOleksandr Tymoshenko keycode = KEY_PAUSE;
2712b3f6d66SOleksandr Tymoshenko break;
2722b3f6d66SOleksandr Tymoshenko }
2732b3f6d66SOleksandr Tymoshenko
2742b3f6d66SOleksandr Tymoshenko return (keycode);
2752b3f6d66SOleksandr Tymoshenko }
2762b3f6d66SOleksandr Tymoshenko
2772b3f6d66SOleksandr Tymoshenko void
evdev_push_mouse_btn(struct evdev_dev * evdev,int buttons)2782b3f6d66SOleksandr Tymoshenko evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
2792b3f6d66SOleksandr Tymoshenko {
2802b3f6d66SOleksandr Tymoshenko size_t i;
2812b3f6d66SOleksandr Tymoshenko
2822b3f6d66SOleksandr Tymoshenko for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
28373362d0eSOleksandr Tymoshenko evdev_push_key(evdev, evdev_mouse_button_codes[i],
28473362d0eSOleksandr Tymoshenko buttons & (1 << i));
2852b3f6d66SOleksandr Tymoshenko }
2862b3f6d66SOleksandr Tymoshenko
2872b3f6d66SOleksandr Tymoshenko void
evdev_push_leds(struct evdev_dev * evdev,int leds)2882b3f6d66SOleksandr Tymoshenko evdev_push_leds(struct evdev_dev *evdev, int leds)
2892b3f6d66SOleksandr Tymoshenko {
2902b3f6d66SOleksandr Tymoshenko size_t i;
2912b3f6d66SOleksandr Tymoshenko
2922b3f6d66SOleksandr Tymoshenko /* Some drivers initialize leds before evdev */
2932b3f6d66SOleksandr Tymoshenko if (evdev == NULL)
2942b3f6d66SOleksandr Tymoshenko return;
2952b3f6d66SOleksandr Tymoshenko
2962b3f6d66SOleksandr Tymoshenko for (i = 0; i < nitems(evdev_led_codes); i++)
29773362d0eSOleksandr Tymoshenko evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
2982b3f6d66SOleksandr Tymoshenko }
2992b3f6d66SOleksandr Tymoshenko
3002b3f6d66SOleksandr Tymoshenko void
evdev_push_repeats(struct evdev_dev * evdev,keyboard_t * kbd)3012b3f6d66SOleksandr Tymoshenko evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
3022b3f6d66SOleksandr Tymoshenko {
3032b3f6d66SOleksandr Tymoshenko /* Some drivers initialize typematics before evdev */
3042b3f6d66SOleksandr Tymoshenko if (evdev == NULL)
3052b3f6d66SOleksandr Tymoshenko return;
3062b3f6d66SOleksandr Tymoshenko
3072b3f6d66SOleksandr Tymoshenko evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
3082b3f6d66SOleksandr Tymoshenko evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
3092b3f6d66SOleksandr Tymoshenko }
31098a7606bSVladimir Kondratyev
31198a7606bSVladimir Kondratyev void
evdev_support_nfingers(struct evdev_dev * evdev,int nfingers)31298a7606bSVladimir Kondratyev evdev_support_nfingers(struct evdev_dev *evdev, int nfingers)
31398a7606bSVladimir Kondratyev {
31498a7606bSVladimir Kondratyev int i;
31598a7606bSVladimir Kondratyev
31698a7606bSVladimir Kondratyev for (i = 0; i < MIN(nitems(evdev_nfinger_codes), nfingers); i++)
31798a7606bSVladimir Kondratyev evdev_support_key(evdev, evdev_nfinger_codes[i]);
31898a7606bSVladimir Kondratyev }
31998a7606bSVladimir Kondratyev
32098a7606bSVladimir Kondratyev void
evdev_send_nfingers(struct evdev_dev * evdev,int nfingers)32198a7606bSVladimir Kondratyev evdev_send_nfingers(struct evdev_dev *evdev, int nfingers)
32298a7606bSVladimir Kondratyev {
32398a7606bSVladimir Kondratyev int i;
32498a7606bSVladimir Kondratyev
32598a7606bSVladimir Kondratyev EVDEV_LOCK_ASSERT(evdev);
32698a7606bSVladimir Kondratyev
32798a7606bSVladimir Kondratyev if (nfingers > nitems(evdev_nfinger_codes))
32898a7606bSVladimir Kondratyev nfingers = nitems(evdev_nfinger_codes);
32998a7606bSVladimir Kondratyev
33098a7606bSVladimir Kondratyev for (i = 0; i < nitems(evdev_nfinger_codes); i++)
33198a7606bSVladimir Kondratyev evdev_send_event(evdev, EV_KEY, evdev_nfinger_codes[i],
33298a7606bSVladimir Kondratyev nfingers == i + 1);
33398a7606bSVladimir Kondratyev }
33498a7606bSVladimir Kondratyev
33598a7606bSVladimir Kondratyev void
evdev_push_nfingers(struct evdev_dev * evdev,int nfingers)33698a7606bSVladimir Kondratyev evdev_push_nfingers(struct evdev_dev *evdev, int nfingers)
33798a7606bSVladimir Kondratyev {
33898a7606bSVladimir Kondratyev EVDEV_ENTER(evdev);
33998a7606bSVladimir Kondratyev evdev_send_nfingers(evdev, nfingers);
34098a7606bSVladimir Kondratyev EVDEV_EXIT(evdev);
34198a7606bSVladimir Kondratyev }
342