xref: /freebsd/sys/dev/evdev/evdev_utils.c (revision f7ee4f902906722add89629da9000c01856c8c91)
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  * $FreeBSD$
282b3f6d66SOleksandr Tymoshenko  */
292b3f6d66SOleksandr Tymoshenko 
302b3f6d66SOleksandr Tymoshenko #include <sys/param.h>
312b3f6d66SOleksandr Tymoshenko #include <sys/bus.h>
322b3f6d66SOleksandr Tymoshenko #include <sys/conf.h>
332b3f6d66SOleksandr Tymoshenko #include <sys/kbio.h>
34ea2e26b1SVladimir Kondratyev #include <sys/kernel.h>
35*f7ee4f90SVladimir Kondratyev #include <sys/lock.h>
36ea2e26b1SVladimir Kondratyev #include <sys/malloc.h>
37*f7ee4f90SVladimir Kondratyev #include <sys/mutex.h>
38ea2e26b1SVladimir Kondratyev #include <sys/systm.h>
392b3f6d66SOleksandr Tymoshenko 
402b3f6d66SOleksandr Tymoshenko #include <dev/evdev/evdev.h>
41ea2e26b1SVladimir Kondratyev #include <dev/evdev/input.h>
422b3f6d66SOleksandr Tymoshenko 
432b3f6d66SOleksandr Tymoshenko #include <dev/kbd/kbdreg.h>
442b3f6d66SOleksandr Tymoshenko 
452b3f6d66SOleksandr Tymoshenko #define	NONE	KEY_RESERVED
462b3f6d66SOleksandr Tymoshenko 
472b3f6d66SOleksandr Tymoshenko static uint16_t evdev_usb_scancodes[256] = {
482b3f6d66SOleksandr Tymoshenko 	/* 0x00 - 0x27 */
492b3f6d66SOleksandr Tymoshenko 	NONE,	NONE,	NONE,	NONE,	KEY_A,	KEY_B,	KEY_C,	KEY_D,
502b3f6d66SOleksandr Tymoshenko 	KEY_E,	KEY_F,	KEY_G,	KEY_H,	KEY_I,	KEY_J,	KEY_K,	KEY_L,
512b3f6d66SOleksandr Tymoshenko 	KEY_M,	KEY_N,	KEY_O,	KEY_P,	KEY_Q,	KEY_R,	KEY_S,	KEY_T,
522b3f6d66SOleksandr Tymoshenko 	KEY_U,	KEY_V,	KEY_W,	KEY_X,	KEY_Y,	KEY_Z,	KEY_1,	KEY_2,
532b3f6d66SOleksandr Tymoshenko 	KEY_3,	KEY_4,	KEY_5,	KEY_6,	KEY_7,	KEY_8,	KEY_9,	KEY_0,
542b3f6d66SOleksandr Tymoshenko 	/* 0x28 - 0x3f */
552b3f6d66SOleksandr Tymoshenko 	KEY_ENTER,	KEY_ESC,	KEY_BACKSPACE,	KEY_TAB,
562b3f6d66SOleksandr Tymoshenko 	KEY_SPACE,	KEY_MINUS,	KEY_EQUAL,	KEY_LEFTBRACE,
572b3f6d66SOleksandr Tymoshenko 	KEY_RIGHTBRACE,	KEY_BACKSLASH,	KEY_BACKSLASH,	KEY_SEMICOLON,
582b3f6d66SOleksandr Tymoshenko 	KEY_APOSTROPHE,	KEY_GRAVE,	KEY_COMMA,	KEY_DOT,
592b3f6d66SOleksandr Tymoshenko 	KEY_SLASH,	KEY_CAPSLOCK,	KEY_F1,		KEY_F2,
602b3f6d66SOleksandr Tymoshenko 	KEY_F3,		KEY_F4,		KEY_F5,		KEY_F6,
612b3f6d66SOleksandr Tymoshenko 	/* 0x40 - 0x5f */
622b3f6d66SOleksandr Tymoshenko 	KEY_F7,		KEY_F8,		KEY_F9,		KEY_F10,
632b3f6d66SOleksandr Tymoshenko 	KEY_F11,	KEY_F12,	KEY_SYSRQ,	KEY_SCROLLLOCK,
642b3f6d66SOleksandr Tymoshenko 	KEY_PAUSE,	KEY_INSERT,	KEY_HOME,	KEY_PAGEUP,
652b3f6d66SOleksandr Tymoshenko 	KEY_DELETE,	KEY_END,	KEY_PAGEDOWN,	KEY_RIGHT,
662b3f6d66SOleksandr Tymoshenko 	KEY_LEFT,	KEY_DOWN,	KEY_UP,		KEY_NUMLOCK,
672b3f6d66SOleksandr Tymoshenko 	KEY_SLASH,	KEY_KPASTERISK,	KEY_KPMINUS,	KEY_KPPLUS,
682b3f6d66SOleksandr Tymoshenko 	KEY_KPENTER,	KEY_KP1,	KEY_KP2,	KEY_KP3,
692b3f6d66SOleksandr Tymoshenko 	KEY_KP4,	KEY_KP5,	KEY_KP6,	KEY_KP7,
702b3f6d66SOleksandr Tymoshenko 	/* 0x60 - 0x7f */
712b3f6d66SOleksandr Tymoshenko 	KEY_KP8,	KEY_KP9,	KEY_KP0,	KEY_KPDOT,
722b3f6d66SOleksandr Tymoshenko 	KEY_102ND,	KEY_COMPOSE,	KEY_POWER,	KEY_KPEQUAL,
732b3f6d66SOleksandr Tymoshenko 	KEY_F13,	KEY_F14,	KEY_F15,	KEY_F16,
742b3f6d66SOleksandr Tymoshenko 	KEY_F17,	KEY_F18,	KEY_F19,	KEY_F20,
752b3f6d66SOleksandr Tymoshenko 	KEY_F21,	KEY_F22,	KEY_F23,	KEY_F24,
762b3f6d66SOleksandr Tymoshenko 	KEY_OPEN,	KEY_HELP,	KEY_PROPS,	KEY_FRONT,
772b3f6d66SOleksandr Tymoshenko 	KEY_STOP,	KEY_AGAIN,	KEY_UNDO,	KEY_CUT,
782b3f6d66SOleksandr Tymoshenko 	KEY_COPY,	KEY_PASTE,	KEY_FIND,	KEY_MUTE,
792b3f6d66SOleksandr Tymoshenko 	/* 0x80 - 0x9f */
802b3f6d66SOleksandr Tymoshenko 	KEY_VOLUMEUP,	KEY_VOLUMEDOWN,	NONE,		NONE,
812b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_KPCOMMA,	NONE,		KEY_RO,
822b3f6d66SOleksandr Tymoshenko 	KEY_KATAKANAHIRAGANA,	KEY_YEN,KEY_HENKAN,	KEY_MUHENKAN,
832b3f6d66SOleksandr Tymoshenko 	KEY_KPJPCOMMA,	NONE,		NONE,		NONE,
842b3f6d66SOleksandr Tymoshenko 	KEY_HANGEUL,	KEY_HANJA,	KEY_KATAKANA,	KEY_HIRAGANA,
852b3f6d66SOleksandr Tymoshenko 	KEY_ZENKAKUHANKAKU,	NONE,	NONE,		NONE,
862b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
872b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
882b3f6d66SOleksandr Tymoshenko 	/* 0xa0 - 0xbf */
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 	NONE,		NONE,		NONE,		NONE,
952b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
962b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
972b3f6d66SOleksandr Tymoshenko 	/* 0xc0 - 0xdf */
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 	NONE,		NONE,		NONE,		NONE,
1042b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1052b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1062b3f6d66SOleksandr Tymoshenko 	/* 0xe0 - 0xff */
1072b3f6d66SOleksandr Tymoshenko 	KEY_LEFTCTRL,	KEY_LEFTSHIFT,	KEY_LEFTALT,	KEY_LEFTMETA,
1082b3f6d66SOleksandr Tymoshenko 	KEY_RIGHTCTRL,	KEY_RIGHTSHIFT,	KEY_RIGHTALT,	KEY_RIGHTMETA,
1092b3f6d66SOleksandr Tymoshenko 	KEY_PLAYPAUSE,	KEY_STOPCD,	KEY_PREVIOUSSONG,KEY_NEXTSONG,
1102b3f6d66SOleksandr Tymoshenko 	KEY_EJECTCD,	KEY_VOLUMEUP,	KEY_VOLUMEDOWN,	KEY_MUTE,
1112b3f6d66SOleksandr Tymoshenko 	KEY_WWW,	KEY_BACK,	KEY_FORWARD,	KEY_STOP,
1122b3f6d66SOleksandr Tymoshenko 	KEY_FIND,	KEY_SCROLLUP,	KEY_SCROLLDOWN,	KEY_EDIT,
1132b3f6d66SOleksandr Tymoshenko 	KEY_SLEEP,	KEY_COFFEE,	KEY_REFRESH,	KEY_CALC,
1142b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1152b3f6d66SOleksandr Tymoshenko 
1162b3f6d66SOleksandr Tymoshenko };
1172b3f6d66SOleksandr Tymoshenko 
1182b3f6d66SOleksandr Tymoshenko static uint16_t evdev_at_set1_scancodes[] = {
1192b3f6d66SOleksandr Tymoshenko 	/* 0x00 - 0x1f */
1202b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_ESC,	KEY_1,		KEY_2,
1212b3f6d66SOleksandr Tymoshenko 	KEY_3,		KEY_4,		KEY_5,		KEY_6,
1222b3f6d66SOleksandr Tymoshenko 	KEY_7,		KEY_8,		KEY_9,		KEY_0,
1232b3f6d66SOleksandr Tymoshenko 	KEY_MINUS,	KEY_EQUAL,	KEY_BACKSPACE,	KEY_TAB,
1242b3f6d66SOleksandr Tymoshenko 	KEY_Q,		KEY_W,		KEY_E,		KEY_R,
1252b3f6d66SOleksandr Tymoshenko 	KEY_T,		KEY_Y,		KEY_U,		KEY_I,
1262b3f6d66SOleksandr Tymoshenko 	KEY_O,		KEY_P,		KEY_LEFTBRACE,	KEY_RIGHTBRACE,
1272b3f6d66SOleksandr Tymoshenko 	KEY_ENTER,	KEY_LEFTCTRL,	KEY_A,		KEY_S,
1282b3f6d66SOleksandr Tymoshenko 	/* 0x20 - 0x3f */
1292b3f6d66SOleksandr Tymoshenko 	KEY_D,		KEY_F,		KEY_G,		KEY_H,
1302b3f6d66SOleksandr Tymoshenko 	KEY_J,		KEY_K,		KEY_L,		KEY_SEMICOLON,
1312b3f6d66SOleksandr Tymoshenko 	KEY_APOSTROPHE,	KEY_GRAVE,	KEY_LEFTSHIFT,	KEY_BACKSLASH,
1322b3f6d66SOleksandr Tymoshenko 	KEY_Z,		KEY_X,		KEY_C,		KEY_V,
1332b3f6d66SOleksandr Tymoshenko 	KEY_B,		KEY_N,		KEY_M,		KEY_COMMA,
1342b3f6d66SOleksandr Tymoshenko 	KEY_DOT,	KEY_SLASH,	KEY_RIGHTSHIFT,	NONE,
1352b3f6d66SOleksandr Tymoshenko 	KEY_LEFTALT,	KEY_SPACE,	KEY_CAPSLOCK,	KEY_F1,
1362b3f6d66SOleksandr Tymoshenko 	KEY_F2,		KEY_F3,		KEY_F4,		KEY_F5,
1372b3f6d66SOleksandr Tymoshenko 	/* 0x40 - 0x5f */
1382b3f6d66SOleksandr Tymoshenko 	KEY_F6,		KEY_F7,		KEY_F8,		KEY_F9,
1392b3f6d66SOleksandr Tymoshenko 	KEY_F10,	KEY_NUMLOCK,	KEY_SCROLLLOCK,	KEY_KP7,
1402b3f6d66SOleksandr Tymoshenko 	KEY_KP8,	KEY_KP9,	KEY_KPMINUS,	KEY_KP4,
1412b3f6d66SOleksandr Tymoshenko 	KEY_KP5,	KEY_KP6,	KEY_KPPLUS,	KEY_KP1,
1422b3f6d66SOleksandr Tymoshenko 	KEY_KP2,	KEY_KP3,	KEY_KP0,	KEY_KPDOT,
143906b7574SJean-Sébastien Pédron 	NONE,		NONE,		KEY_102ND,	KEY_F11,
1442b3f6d66SOleksandr Tymoshenko 	KEY_F12,	NONE,		NONE,		NONE,
1452b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1462b3f6d66SOleksandr Tymoshenko 	/* 0x60 - 0x7f */
1472b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1482b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1492b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1502b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1512b3f6d66SOleksandr Tymoshenko 	KEY_KATAKANAHIRAGANA,	NONE,	NONE,		KEY_RO,
1522b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,	KEY_ZENKAKUHANKAKU,	KEY_HIRAGANA,
1532b3f6d66SOleksandr Tymoshenko 	KEY_KATAKANA,	KEY_HENKAN,	NONE,		KEY_MUHENKAN,
1542b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_YEN,	KEY_KPCOMMA,	NONE,
1552b3f6d66SOleksandr Tymoshenko 	/* 0x00 - 0x1f. 0xE0 prefixed */
1562b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1572b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1582b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1592b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1602b3f6d66SOleksandr Tymoshenko 	KEY_PREVIOUSSONG,	NONE,	NONE,		NONE,
1612b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1622b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_NEXTSONG,	NONE,		NONE,
1635bc82581SOleksandr Tymoshenko 	KEY_KPENTER,	KEY_RIGHTCTRL,	NONE,		NONE,
1642b3f6d66SOleksandr Tymoshenko 	/* 0x20 - 0x3f. 0xE0 prefixed */
1652b3f6d66SOleksandr Tymoshenko 	KEY_MUTE,	KEY_CALC,	KEY_PLAYPAUSE,	NONE,
1662b3f6d66SOleksandr Tymoshenko 	KEY_STOPCD,	NONE,		NONE,		NONE,
1672b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1682b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		KEY_VOLUMEDOWN,	NONE,
1692b3f6d66SOleksandr Tymoshenko 	KEY_VOLUMEUP,	NONE,		KEY_HOMEPAGE,	NONE,
1702b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_KPASTERISK,	NONE,		KEY_SYSRQ,
1712b3f6d66SOleksandr Tymoshenko 	KEY_RIGHTALT,	NONE,		NONE,		NONE,
1722b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1732b3f6d66SOleksandr Tymoshenko 	/* 0x40 - 0x5f. 0xE0 prefixed */
1742b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1752b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		KEY_PAUSE,	KEY_HOME,
1762b3f6d66SOleksandr Tymoshenko 	KEY_UP,		KEY_PAGEUP,	NONE,		KEY_LEFT,
1772b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_RIGHT,	NONE,		KEY_END,
1782b3f6d66SOleksandr Tymoshenko 	KEY_DOWN,	KEY_PAGEDOWN,	KEY_INSERT,	KEY_DELETE,
1792b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1802b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		KEY_LEFTMETA,
1812b3f6d66SOleksandr Tymoshenko 	KEY_RIGHTMETA,	KEY_MENU,	KEY_POWER,	KEY_SLEEP,
1822b3f6d66SOleksandr Tymoshenko 	/* 0x60 - 0x7f. 0xE0 prefixed */
1832b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		KEY_WAKEUP,
1842b3f6d66SOleksandr Tymoshenko 	NONE,		KEY_SEARCH,	KEY_BOOKMARKS,	KEY_REFRESH,
1852b3f6d66SOleksandr Tymoshenko 	KEY_STOP,	KEY_FORWARD,	KEY_BACK,	KEY_COMPUTER,
1862b3f6d66SOleksandr Tymoshenko 	KEY_MAIL,	KEY_MEDIA,	NONE,		NONE,
1872b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1882b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1892b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1902b3f6d66SOleksandr Tymoshenko 	NONE,		NONE,		NONE,		NONE,
1912b3f6d66SOleksandr Tymoshenko };
1922b3f6d66SOleksandr Tymoshenko 
1932b3f6d66SOleksandr Tymoshenko static uint16_t evdev_mouse_button_codes[] = {
1942b3f6d66SOleksandr Tymoshenko 	BTN_LEFT,
1952b3f6d66SOleksandr Tymoshenko 	BTN_MIDDLE,
1962b3f6d66SOleksandr Tymoshenko 	BTN_RIGHT,
1972b3f6d66SOleksandr Tymoshenko 	BTN_SIDE,
1982b3f6d66SOleksandr Tymoshenko 	BTN_EXTRA,
1992b3f6d66SOleksandr Tymoshenko 	BTN_FORWARD,
2002b3f6d66SOleksandr Tymoshenko 	BTN_BACK,
2012b3f6d66SOleksandr Tymoshenko 	BTN_TASK,
2022b3f6d66SOleksandr Tymoshenko };
2032b3f6d66SOleksandr Tymoshenko 
2042b3f6d66SOleksandr Tymoshenko static uint16_t evdev_led_codes[] = {
2052b3f6d66SOleksandr Tymoshenko 	LED_CAPSL,	/* CLKED */
2062b3f6d66SOleksandr Tymoshenko 	LED_NUML,	/* NLKED */
2072b3f6d66SOleksandr Tymoshenko 	LED_SCROLLL,	/* SLKED */
2082b3f6d66SOleksandr Tymoshenko };
2092b3f6d66SOleksandr Tymoshenko 
21071546cd9SOleksandr Tymoshenko uint16_t
2112b3f6d66SOleksandr Tymoshenko evdev_hid2key(int scancode)
2122b3f6d66SOleksandr Tymoshenko {
2132b3f6d66SOleksandr Tymoshenko 	return evdev_usb_scancodes[scancode];
2142b3f6d66SOleksandr Tymoshenko }
2152b3f6d66SOleksandr Tymoshenko 
21671546cd9SOleksandr Tymoshenko void
2172b3f6d66SOleksandr Tymoshenko evdev_support_all_known_keys(struct evdev_dev *evdev)
2182b3f6d66SOleksandr Tymoshenko {
2192b3f6d66SOleksandr Tymoshenko 	size_t i;
2202b3f6d66SOleksandr Tymoshenko 
2212b3f6d66SOleksandr Tymoshenko 	for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
2222b3f6d66SOleksandr Tymoshenko 		if (evdev_at_set1_scancodes[i] != NONE)
2232b3f6d66SOleksandr Tymoshenko 			evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
2242b3f6d66SOleksandr Tymoshenko }
2252b3f6d66SOleksandr Tymoshenko 
22671546cd9SOleksandr Tymoshenko uint16_t
2272b3f6d66SOleksandr Tymoshenko evdev_scancode2key(int *state, int scancode)
2282b3f6d66SOleksandr Tymoshenko {
2292b3f6d66SOleksandr Tymoshenko 	uint16_t keycode;
2302b3f6d66SOleksandr Tymoshenko 
2312b3f6d66SOleksandr Tymoshenko 	/* translate the scan code into a keycode */
2322b3f6d66SOleksandr Tymoshenko 	keycode = evdev_at_set1_scancodes[scancode & 0x7f];
2332b3f6d66SOleksandr Tymoshenko 	switch (*state) {
2342b3f6d66SOleksandr Tymoshenko 	case 0x00:	/* normal scancode */
2352b3f6d66SOleksandr Tymoshenko 		switch(scancode) {
2362b3f6d66SOleksandr Tymoshenko 		case 0xE0:
2372b3f6d66SOleksandr Tymoshenko 		case 0xE1:
2382b3f6d66SOleksandr Tymoshenko 			*state = scancode;
2392b3f6d66SOleksandr Tymoshenko 			return (NONE);
2402b3f6d66SOleksandr Tymoshenko 		}
2412b3f6d66SOleksandr Tymoshenko 		break;
2422b3f6d66SOleksandr Tymoshenko 	case 0xE0:		/* 0xE0 prefix */
2432b3f6d66SOleksandr Tymoshenko 		*state = 0;
2442b3f6d66SOleksandr Tymoshenko 		keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
2452b3f6d66SOleksandr Tymoshenko 		break;
2462b3f6d66SOleksandr Tymoshenko 	case 0xE1:	/* 0xE1 prefix */
2472b3f6d66SOleksandr Tymoshenko 		/*
2482b3f6d66SOleksandr Tymoshenko 		 * The pause/break key on the 101 keyboard produces:
2492b3f6d66SOleksandr Tymoshenko 		 * E1-1D-45 E1-9D-C5
2502b3f6d66SOleksandr Tymoshenko 		 * Ctrl-pause/break produces:
2512b3f6d66SOleksandr Tymoshenko 		 * E0-46 E0-C6 (See above.)
2522b3f6d66SOleksandr Tymoshenko 		 */
2532b3f6d66SOleksandr Tymoshenko 		*state = 0;
2542b3f6d66SOleksandr Tymoshenko 		if ((scancode & 0x7f) == 0x1D)
2552b3f6d66SOleksandr Tymoshenko 			*state = 0x1D;
2562b3f6d66SOleksandr Tymoshenko 		return (NONE);
2572b3f6d66SOleksandr Tymoshenko 		/* NOT REACHED */
2582b3f6d66SOleksandr Tymoshenko 	case 0x1D:	/* pause / break */
2592b3f6d66SOleksandr Tymoshenko 		*state = 0;
2602b3f6d66SOleksandr Tymoshenko 		if (scancode != 0x45)
2612b3f6d66SOleksandr Tymoshenko 			return (NONE);
2622b3f6d66SOleksandr Tymoshenko 		keycode = KEY_PAUSE;
2632b3f6d66SOleksandr Tymoshenko 		break;
2642b3f6d66SOleksandr Tymoshenko 	}
2652b3f6d66SOleksandr Tymoshenko 
2662b3f6d66SOleksandr Tymoshenko 	return (keycode);
2672b3f6d66SOleksandr Tymoshenko }
2682b3f6d66SOleksandr Tymoshenko 
2692b3f6d66SOleksandr Tymoshenko void
2702b3f6d66SOleksandr Tymoshenko evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
2712b3f6d66SOleksandr Tymoshenko {
2722b3f6d66SOleksandr Tymoshenko 	size_t i;
2732b3f6d66SOleksandr Tymoshenko 
2742b3f6d66SOleksandr Tymoshenko 	for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
27573362d0eSOleksandr Tymoshenko 		evdev_push_key(evdev, evdev_mouse_button_codes[i],
27673362d0eSOleksandr Tymoshenko 		    buttons & (1 << i));
2772b3f6d66SOleksandr Tymoshenko }
2782b3f6d66SOleksandr Tymoshenko 
2792b3f6d66SOleksandr Tymoshenko void
2802b3f6d66SOleksandr Tymoshenko evdev_push_leds(struct evdev_dev *evdev, int leds)
2812b3f6d66SOleksandr Tymoshenko {
2822b3f6d66SOleksandr Tymoshenko 	size_t i;
2832b3f6d66SOleksandr Tymoshenko 
2842b3f6d66SOleksandr Tymoshenko 	/* Some drivers initialize leds before evdev */
2852b3f6d66SOleksandr Tymoshenko 	if (evdev == NULL)
2862b3f6d66SOleksandr Tymoshenko 		return;
2872b3f6d66SOleksandr Tymoshenko 
2882b3f6d66SOleksandr Tymoshenko 	for (i = 0; i < nitems(evdev_led_codes); i++)
28973362d0eSOleksandr Tymoshenko 		evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
2902b3f6d66SOleksandr Tymoshenko }
2912b3f6d66SOleksandr Tymoshenko 
2922b3f6d66SOleksandr Tymoshenko void
2932b3f6d66SOleksandr Tymoshenko evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
2942b3f6d66SOleksandr Tymoshenko {
2952b3f6d66SOleksandr Tymoshenko 	/* Some drivers initialize typematics before evdev */
2962b3f6d66SOleksandr Tymoshenko 	if (evdev == NULL)
2972b3f6d66SOleksandr Tymoshenko 		return;
2982b3f6d66SOleksandr Tymoshenko 
2992b3f6d66SOleksandr Tymoshenko 	evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
3002b3f6d66SOleksandr Tymoshenko 	evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
3012b3f6d66SOleksandr Tymoshenko }
3022b3f6d66SOleksandr Tymoshenko 
3032b3f6d66SOleksandr Tymoshenko void
3042b3f6d66SOleksandr Tymoshenko evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type,
3052b3f6d66SOleksandr Tymoshenko     uint16_t code, int32_t value)
3062b3f6d66SOleksandr Tymoshenko {
3072b3f6d66SOleksandr Tymoshenko 	keyboard_t *kbd = (keyboard_t *)softc;
3082b3f6d66SOleksandr Tymoshenko 	int delay[2], leds, oleds;
3092b3f6d66SOleksandr Tymoshenko 	size_t i;
3102b3f6d66SOleksandr Tymoshenko 
3112b3f6d66SOleksandr Tymoshenko 	if (type == EV_LED) {
3122b3f6d66SOleksandr Tymoshenko 		leds = oleds = KBD_LED_VAL(kbd);
3132b3f6d66SOleksandr Tymoshenko 		for (i = 0; i < nitems(evdev_led_codes); i++) {
3142b3f6d66SOleksandr Tymoshenko 			if (evdev_led_codes[i] == code) {
3152b3f6d66SOleksandr Tymoshenko 				if (value)
3162b3f6d66SOleksandr Tymoshenko 					leds |= 1 << i;
3172b3f6d66SOleksandr Tymoshenko 				else
3182b3f6d66SOleksandr Tymoshenko 					leds &= ~(1 << i);
319*f7ee4f90SVladimir Kondratyev 				if (leds != oleds) {
320*f7ee4f90SVladimir Kondratyev 					mtx_lock(&Giant);
3212b3f6d66SOleksandr Tymoshenko 					kbdd_ioctl(kbd, KDSETLED,
3222b3f6d66SOleksandr Tymoshenko 					    (caddr_t)&leds);
323*f7ee4f90SVladimir Kondratyev 					mtx_unlock(&Giant);
324*f7ee4f90SVladimir Kondratyev 				}
3252b3f6d66SOleksandr Tymoshenko 				break;
3262b3f6d66SOleksandr Tymoshenko 			}
3272b3f6d66SOleksandr Tymoshenko 		}
3282b3f6d66SOleksandr Tymoshenko 	} else if (type == EV_REP && code == REP_DELAY) {
3292b3f6d66SOleksandr Tymoshenko 		delay[0] = value;
3302b3f6d66SOleksandr Tymoshenko 		delay[1] = kbd->kb_delay2;
331*f7ee4f90SVladimir Kondratyev 		mtx_lock(&Giant);
3322b3f6d66SOleksandr Tymoshenko 		kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
333*f7ee4f90SVladimir Kondratyev 		mtx_unlock(&Giant);
3342b3f6d66SOleksandr Tymoshenko 	} else if (type == EV_REP && code == REP_PERIOD) {
3352b3f6d66SOleksandr Tymoshenko 		delay[0] = kbd->kb_delay1;
3362b3f6d66SOleksandr Tymoshenko 		delay[1] = value;
337*f7ee4f90SVladimir Kondratyev 		mtx_lock(&Giant);
3382b3f6d66SOleksandr Tymoshenko 		kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
339*f7ee4f90SVladimir Kondratyev 		mtx_unlock(&Giant);
3402b3f6d66SOleksandr Tymoshenko 	}
3412b3f6d66SOleksandr Tymoshenko }
342