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