1*bf21cd93STycho Nightingale /*- 2*bf21cd93STycho Nightingale * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 3*bf21cd93STycho Nightingale * Copyright (c) 2015 Nahanni Systems Inc. 4*bf21cd93STycho Nightingale * All rights reserved. 5*bf21cd93STycho Nightingale * 6*bf21cd93STycho Nightingale * Redistribution and use in source and binary forms, with or without 7*bf21cd93STycho Nightingale * modification, are permitted provided that the following conditions 8*bf21cd93STycho Nightingale * are met: 9*bf21cd93STycho Nightingale * 1. Redistributions of source code must retain the above copyright 10*bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer. 11*bf21cd93STycho Nightingale * 2. Redistributions in binary form must reproduce the above copyright 12*bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer in the 13*bf21cd93STycho Nightingale * documentation and/or other materials provided with the distribution. 14*bf21cd93STycho Nightingale * 15*bf21cd93STycho Nightingale * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 16*bf21cd93STycho Nightingale * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*bf21cd93STycho Nightingale * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*bf21cd93STycho Nightingale * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*bf21cd93STycho Nightingale * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*bf21cd93STycho Nightingale * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*bf21cd93STycho Nightingale * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*bf21cd93STycho Nightingale * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*bf21cd93STycho Nightingale * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*bf21cd93STycho Nightingale * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*bf21cd93STycho Nightingale * SUCH DAMAGE. 26*bf21cd93STycho Nightingale */ 27*bf21cd93STycho Nightingale 28*bf21cd93STycho Nightingale #include <sys/cdefs.h> 29*bf21cd93STycho Nightingale __FBSDID("$FreeBSD$"); 30*bf21cd93STycho Nightingale 31*bf21cd93STycho Nightingale #include <sys/types.h> 32*bf21cd93STycho Nightingale 33*bf21cd93STycho Nightingale #include <assert.h> 34*bf21cd93STycho Nightingale #include <stdbool.h> 35*bf21cd93STycho Nightingale #include <stdio.h> 36*bf21cd93STycho Nightingale #include <stdlib.h> 37*bf21cd93STycho Nightingale #include <strings.h> 38*bf21cd93STycho Nightingale #include <pthread.h> 39*bf21cd93STycho Nightingale #include <pthread_np.h> 40*bf21cd93STycho Nightingale 41*bf21cd93STycho Nightingale #include "atkbdc.h" 42*bf21cd93STycho Nightingale #include "console.h" 43*bf21cd93STycho Nightingale 44*bf21cd93STycho Nightingale /* keyboard device commands */ 45*bf21cd93STycho Nightingale #define PS2KC_RESET_DEV 0xff 46*bf21cd93STycho Nightingale #define PS2KC_DISABLE 0xf5 47*bf21cd93STycho Nightingale #define PS2KC_ENABLE 0xf4 48*bf21cd93STycho Nightingale #define PS2KC_SET_TYPEMATIC 0xf3 49*bf21cd93STycho Nightingale #define PS2KC_SEND_DEV_ID 0xf2 50*bf21cd93STycho Nightingale #define PS2KC_SET_SCANCODE_SET 0xf0 51*bf21cd93STycho Nightingale #define PS2KC_ECHO 0xee 52*bf21cd93STycho Nightingale #define PS2KC_SET_LEDS 0xed 53*bf21cd93STycho Nightingale 54*bf21cd93STycho Nightingale #define PS2KC_BAT_SUCCESS 0xaa 55*bf21cd93STycho Nightingale #define PS2KC_ACK 0xfa 56*bf21cd93STycho Nightingale 57*bf21cd93STycho Nightingale #define PS2KBD_FIFOSZ 16 58*bf21cd93STycho Nightingale 59*bf21cd93STycho Nightingale struct fifo { 60*bf21cd93STycho Nightingale uint8_t buf[PS2KBD_FIFOSZ]; 61*bf21cd93STycho Nightingale int rindex; /* index to read from */ 62*bf21cd93STycho Nightingale int windex; /* index to write to */ 63*bf21cd93STycho Nightingale int num; /* number of bytes in the fifo */ 64*bf21cd93STycho Nightingale int size; /* size of the fifo */ 65*bf21cd93STycho Nightingale }; 66*bf21cd93STycho Nightingale 67*bf21cd93STycho Nightingale struct ps2kbd_softc { 68*bf21cd93STycho Nightingale struct atkbdc_softc *atkbdc_sc; 69*bf21cd93STycho Nightingale pthread_mutex_t mtx; 70*bf21cd93STycho Nightingale 71*bf21cd93STycho Nightingale bool enabled; 72*bf21cd93STycho Nightingale struct fifo fifo; 73*bf21cd93STycho Nightingale 74*bf21cd93STycho Nightingale uint8_t curcmd; /* current command for next byte */ 75*bf21cd93STycho Nightingale }; 76*bf21cd93STycho Nightingale 77*bf21cd93STycho Nightingale static void 78*bf21cd93STycho Nightingale fifo_init(struct ps2kbd_softc *sc) 79*bf21cd93STycho Nightingale { 80*bf21cd93STycho Nightingale struct fifo *fifo; 81*bf21cd93STycho Nightingale 82*bf21cd93STycho Nightingale fifo = &sc->fifo; 83*bf21cd93STycho Nightingale fifo->size = sizeof(((struct fifo *)0)->buf); 84*bf21cd93STycho Nightingale } 85*bf21cd93STycho Nightingale 86*bf21cd93STycho Nightingale static void 87*bf21cd93STycho Nightingale fifo_reset(struct ps2kbd_softc *sc) 88*bf21cd93STycho Nightingale { 89*bf21cd93STycho Nightingale struct fifo *fifo; 90*bf21cd93STycho Nightingale 91*bf21cd93STycho Nightingale fifo = &sc->fifo; 92*bf21cd93STycho Nightingale bzero(fifo, sizeof(struct fifo)); 93*bf21cd93STycho Nightingale fifo->size = sizeof(((struct fifo *)0)->buf); 94*bf21cd93STycho Nightingale } 95*bf21cd93STycho Nightingale 96*bf21cd93STycho Nightingale static int 97*bf21cd93STycho Nightingale fifo_available(struct ps2kbd_softc *sc) 98*bf21cd93STycho Nightingale { 99*bf21cd93STycho Nightingale struct fifo *fifo; 100*bf21cd93STycho Nightingale 101*bf21cd93STycho Nightingale fifo = &sc->fifo; 102*bf21cd93STycho Nightingale return (fifo->num < fifo->size); 103*bf21cd93STycho Nightingale } 104*bf21cd93STycho Nightingale 105*bf21cd93STycho Nightingale static void 106*bf21cd93STycho Nightingale fifo_put(struct ps2kbd_softc *sc, uint8_t val) 107*bf21cd93STycho Nightingale { 108*bf21cd93STycho Nightingale struct fifo *fifo; 109*bf21cd93STycho Nightingale 110*bf21cd93STycho Nightingale fifo = &sc->fifo; 111*bf21cd93STycho Nightingale if (fifo->num < fifo->size) { 112*bf21cd93STycho Nightingale fifo->buf[fifo->windex] = val; 113*bf21cd93STycho Nightingale fifo->windex = (fifo->windex + 1) % fifo->size; 114*bf21cd93STycho Nightingale fifo->num++; 115*bf21cd93STycho Nightingale } 116*bf21cd93STycho Nightingale } 117*bf21cd93STycho Nightingale 118*bf21cd93STycho Nightingale static int 119*bf21cd93STycho Nightingale fifo_get(struct ps2kbd_softc *sc, uint8_t *val) 120*bf21cd93STycho Nightingale { 121*bf21cd93STycho Nightingale struct fifo *fifo; 122*bf21cd93STycho Nightingale 123*bf21cd93STycho Nightingale fifo = &sc->fifo; 124*bf21cd93STycho Nightingale if (fifo->num > 0) { 125*bf21cd93STycho Nightingale *val = fifo->buf[fifo->rindex]; 126*bf21cd93STycho Nightingale fifo->rindex = (fifo->rindex + 1) % fifo->size; 127*bf21cd93STycho Nightingale fifo->num--; 128*bf21cd93STycho Nightingale return (0); 129*bf21cd93STycho Nightingale } 130*bf21cd93STycho Nightingale 131*bf21cd93STycho Nightingale return (-1); 132*bf21cd93STycho Nightingale } 133*bf21cd93STycho Nightingale 134*bf21cd93STycho Nightingale int 135*bf21cd93STycho Nightingale ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val) 136*bf21cd93STycho Nightingale { 137*bf21cd93STycho Nightingale int retval; 138*bf21cd93STycho Nightingale 139*bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 140*bf21cd93STycho Nightingale retval = fifo_get(sc, val); 141*bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 142*bf21cd93STycho Nightingale 143*bf21cd93STycho Nightingale return (retval); 144*bf21cd93STycho Nightingale } 145*bf21cd93STycho Nightingale 146*bf21cd93STycho Nightingale void 147*bf21cd93STycho Nightingale ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) 148*bf21cd93STycho Nightingale { 149*bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 150*bf21cd93STycho Nightingale if (sc->curcmd) { 151*bf21cd93STycho Nightingale switch (sc->curcmd) { 152*bf21cd93STycho Nightingale case PS2KC_SET_TYPEMATIC: 153*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 154*bf21cd93STycho Nightingale break; 155*bf21cd93STycho Nightingale case PS2KC_SET_SCANCODE_SET: 156*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 157*bf21cd93STycho Nightingale break; 158*bf21cd93STycho Nightingale case PS2KC_SET_LEDS: 159*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 160*bf21cd93STycho Nightingale break; 161*bf21cd93STycho Nightingale default: 162*bf21cd93STycho Nightingale fprintf(stderr, "Unhandled ps2 keyboard current " 163*bf21cd93STycho Nightingale "command byte 0x%02x\n", val); 164*bf21cd93STycho Nightingale break; 165*bf21cd93STycho Nightingale } 166*bf21cd93STycho Nightingale sc->curcmd = 0; 167*bf21cd93STycho Nightingale } else { 168*bf21cd93STycho Nightingale switch (val) { 169*bf21cd93STycho Nightingale case PS2KC_RESET_DEV: 170*bf21cd93STycho Nightingale fifo_reset(sc); 171*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 172*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_BAT_SUCCESS); 173*bf21cd93STycho Nightingale break; 174*bf21cd93STycho Nightingale case PS2KC_DISABLE: 175*bf21cd93STycho Nightingale sc->enabled = false; 176*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 177*bf21cd93STycho Nightingale break; 178*bf21cd93STycho Nightingale case PS2KC_ENABLE: 179*bf21cd93STycho Nightingale sc->enabled = true; 180*bf21cd93STycho Nightingale fifo_reset(sc); 181*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 182*bf21cd93STycho Nightingale break; 183*bf21cd93STycho Nightingale case PS2KC_SET_TYPEMATIC: 184*bf21cd93STycho Nightingale sc->curcmd = val; 185*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 186*bf21cd93STycho Nightingale break; 187*bf21cd93STycho Nightingale case PS2KC_SEND_DEV_ID: 188*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 189*bf21cd93STycho Nightingale fifo_put(sc, 0xab); 190*bf21cd93STycho Nightingale fifo_put(sc, 0x83); 191*bf21cd93STycho Nightingale break; 192*bf21cd93STycho Nightingale case PS2KC_SET_SCANCODE_SET: 193*bf21cd93STycho Nightingale sc->curcmd = val; 194*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 195*bf21cd93STycho Nightingale break; 196*bf21cd93STycho Nightingale case PS2KC_ECHO: 197*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ECHO); 198*bf21cd93STycho Nightingale break; 199*bf21cd93STycho Nightingale case PS2KC_SET_LEDS: 200*bf21cd93STycho Nightingale sc->curcmd = val; 201*bf21cd93STycho Nightingale fifo_put(sc, PS2KC_ACK); 202*bf21cd93STycho Nightingale break; 203*bf21cd93STycho Nightingale default: 204*bf21cd93STycho Nightingale fprintf(stderr, "Unhandled ps2 keyboard command " 205*bf21cd93STycho Nightingale "0x%02x\n", val); 206*bf21cd93STycho Nightingale break; 207*bf21cd93STycho Nightingale } 208*bf21cd93STycho Nightingale } 209*bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 210*bf21cd93STycho Nightingale } 211*bf21cd93STycho Nightingale 212*bf21cd93STycho Nightingale /* 213*bf21cd93STycho Nightingale * Translate keysym to type 2 scancode and insert into keyboard buffer. 214*bf21cd93STycho Nightingale */ 215*bf21cd93STycho Nightingale static void 216*bf21cd93STycho Nightingale ps2kbd_keysym_queue(struct ps2kbd_softc *sc, 217*bf21cd93STycho Nightingale int down, uint32_t keysym) 218*bf21cd93STycho Nightingale { 219*bf21cd93STycho Nightingale /* ASCII to type 2 scancode lookup table */ 220*bf21cd93STycho Nightingale const uint8_t translation[128] = { 221*bf21cd93STycho Nightingale 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222*bf21cd93STycho Nightingale 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223*bf21cd93STycho Nightingale 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224*bf21cd93STycho Nightingale 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 225*bf21cd93STycho Nightingale 0x29, 0x16, 0x52, 0x26, 0x25, 0x2e, 0x3d, 0x52, 226*bf21cd93STycho Nightingale 0x46, 0x45, 0x3e, 0x55, 0x41, 0x4e, 0x49, 0x4a, 227*bf21cd93STycho Nightingale 0x45, 0x16, 0x1e, 0x26, 0x25, 0x2e, 0x36, 0x3d, 228*bf21cd93STycho Nightingale 0x3e, 0x46, 0x4c, 0x4c, 0x41, 0x55, 0x49, 0x4a, 229*bf21cd93STycho Nightingale 0x1e, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, 230*bf21cd93STycho Nightingale 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, 231*bf21cd93STycho Nightingale 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, 232*bf21cd93STycho Nightingale 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x36, 0x4e, 233*bf21cd93STycho Nightingale 0x0e, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, 234*bf21cd93STycho Nightingale 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, 235*bf21cd93STycho Nightingale 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, 236*bf21cd93STycho Nightingale 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x0e, 0x00, 237*bf21cd93STycho Nightingale }; 238*bf21cd93STycho Nightingale 239*bf21cd93STycho Nightingale assert(pthread_mutex_isowned_np(&sc->mtx)); 240*bf21cd93STycho Nightingale 241*bf21cd93STycho Nightingale switch (keysym) { 242*bf21cd93STycho Nightingale case 0x0 ... 0x7f: 243*bf21cd93STycho Nightingale if (!down) 244*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 245*bf21cd93STycho Nightingale fifo_put(sc, translation[keysym]); 246*bf21cd93STycho Nightingale break; 247*bf21cd93STycho Nightingale case 0xff08: /* Back space */ 248*bf21cd93STycho Nightingale if (!down) 249*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 250*bf21cd93STycho Nightingale fifo_put(sc, 0x66); 251*bf21cd93STycho Nightingale break; 252*bf21cd93STycho Nightingale case 0xff09: /* Tab */ 253*bf21cd93STycho Nightingale if (!down) 254*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 255*bf21cd93STycho Nightingale fifo_put(sc, 0x0d); 256*bf21cd93STycho Nightingale break; 257*bf21cd93STycho Nightingale case 0xff0d: /* Return */ 258*bf21cd93STycho Nightingale if (!down) 259*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 260*bf21cd93STycho Nightingale fifo_put(sc, 0x5a); 261*bf21cd93STycho Nightingale break; 262*bf21cd93STycho Nightingale case 0xff1b: /* Escape */ 263*bf21cd93STycho Nightingale if (!down) 264*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 265*bf21cd93STycho Nightingale fifo_put(sc, 0x76); 266*bf21cd93STycho Nightingale break; 267*bf21cd93STycho Nightingale case 0xff51: /* Left arrow */ 268*bf21cd93STycho Nightingale fifo_put(sc, 0xe0); 269*bf21cd93STycho Nightingale if (!down) 270*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 271*bf21cd93STycho Nightingale fifo_put(sc, 0x6b); 272*bf21cd93STycho Nightingale break; 273*bf21cd93STycho Nightingale case 0xff52: /* Up arrow */ 274*bf21cd93STycho Nightingale fifo_put(sc, 0xe0); 275*bf21cd93STycho Nightingale if (!down) 276*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 277*bf21cd93STycho Nightingale fifo_put(sc, 0x75); 278*bf21cd93STycho Nightingale break; 279*bf21cd93STycho Nightingale case 0xff53: /* Right arrow */ 280*bf21cd93STycho Nightingale fifo_put(sc, 0xe0); 281*bf21cd93STycho Nightingale if (!down) 282*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 283*bf21cd93STycho Nightingale fifo_put(sc, 0x74); 284*bf21cd93STycho Nightingale break; 285*bf21cd93STycho Nightingale case 0xff54: /* Down arrow */ 286*bf21cd93STycho Nightingale fifo_put(sc, 0xe0); 287*bf21cd93STycho Nightingale if (!down) 288*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 289*bf21cd93STycho Nightingale fifo_put(sc, 0x72); 290*bf21cd93STycho Nightingale break; 291*bf21cd93STycho Nightingale case 0xffbe: /* F1 */ 292*bf21cd93STycho Nightingale if (!down) 293*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 294*bf21cd93STycho Nightingale fifo_put(sc, 0x05); 295*bf21cd93STycho Nightingale break; 296*bf21cd93STycho Nightingale case 0xffbf: /* F2 */ 297*bf21cd93STycho Nightingale if (!down) 298*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 299*bf21cd93STycho Nightingale fifo_put(sc, 0x06); 300*bf21cd93STycho Nightingale break; 301*bf21cd93STycho Nightingale case 0xffc0: /* F3 */ 302*bf21cd93STycho Nightingale if (!down) 303*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 304*bf21cd93STycho Nightingale fifo_put(sc, 0x04); 305*bf21cd93STycho Nightingale break; 306*bf21cd93STycho Nightingale case 0xffc1: /* F4 */ 307*bf21cd93STycho Nightingale if (!down) 308*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 309*bf21cd93STycho Nightingale fifo_put(sc, 0x0c); 310*bf21cd93STycho Nightingale break; 311*bf21cd93STycho Nightingale case 0xffc2: /* F5 */ 312*bf21cd93STycho Nightingale if (!down) 313*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 314*bf21cd93STycho Nightingale fifo_put(sc, 0x03); 315*bf21cd93STycho Nightingale break; 316*bf21cd93STycho Nightingale case 0xffc3: /* F6 */ 317*bf21cd93STycho Nightingale if (!down) 318*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 319*bf21cd93STycho Nightingale fifo_put(sc, 0x0b); 320*bf21cd93STycho Nightingale break; 321*bf21cd93STycho Nightingale case 0xffc4: /* F7 */ 322*bf21cd93STycho Nightingale if (!down) 323*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 324*bf21cd93STycho Nightingale fifo_put(sc, 0x83); 325*bf21cd93STycho Nightingale break; 326*bf21cd93STycho Nightingale case 0xffc5: /* F8 */ 327*bf21cd93STycho Nightingale if (!down) 328*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 329*bf21cd93STycho Nightingale fifo_put(sc, 0x0a); 330*bf21cd93STycho Nightingale break; 331*bf21cd93STycho Nightingale case 0xffc6: /* F9 */ 332*bf21cd93STycho Nightingale if (!down) 333*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 334*bf21cd93STycho Nightingale fifo_put(sc, 0x01); 335*bf21cd93STycho Nightingale break; 336*bf21cd93STycho Nightingale case 0xffc7: /* F10 */ 337*bf21cd93STycho Nightingale if (!down) 338*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 339*bf21cd93STycho Nightingale fifo_put(sc, 0x09); 340*bf21cd93STycho Nightingale break; 341*bf21cd93STycho Nightingale case 0xffc8: /* F11 */ 342*bf21cd93STycho Nightingale if (!down) 343*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 344*bf21cd93STycho Nightingale fifo_put(sc, 0x78); 345*bf21cd93STycho Nightingale break; 346*bf21cd93STycho Nightingale case 0xffc9: /* F12 */ 347*bf21cd93STycho Nightingale if (!down) 348*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 349*bf21cd93STycho Nightingale fifo_put(sc, 0x07); 350*bf21cd93STycho Nightingale break; 351*bf21cd93STycho Nightingale case 0xffe1: /* Left shift */ 352*bf21cd93STycho Nightingale if (!down) 353*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 354*bf21cd93STycho Nightingale fifo_put(sc, 0x12); 355*bf21cd93STycho Nightingale break; 356*bf21cd93STycho Nightingale case 0xffe2: /* Right shift */ 357*bf21cd93STycho Nightingale /* XXX */ 358*bf21cd93STycho Nightingale break; 359*bf21cd93STycho Nightingale case 0xffe3: /* Left control */ 360*bf21cd93STycho Nightingale if (!down) 361*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 362*bf21cd93STycho Nightingale fifo_put(sc, 0x14); 363*bf21cd93STycho Nightingale break; 364*bf21cd93STycho Nightingale case 0xffe4: /* Right control */ 365*bf21cd93STycho Nightingale /* XXX */ 366*bf21cd93STycho Nightingale break; 367*bf21cd93STycho Nightingale case 0xffe7: /* Left meta */ 368*bf21cd93STycho Nightingale /* XXX */ 369*bf21cd93STycho Nightingale break; 370*bf21cd93STycho Nightingale case 0xffe8: /* Right meta */ 371*bf21cd93STycho Nightingale /* XXX */ 372*bf21cd93STycho Nightingale break; 373*bf21cd93STycho Nightingale case 0xffe9: /* Left alt */ 374*bf21cd93STycho Nightingale if (!down) 375*bf21cd93STycho Nightingale fifo_put(sc, 0xf0); 376*bf21cd93STycho Nightingale fifo_put(sc, 0x11); 377*bf21cd93STycho Nightingale break; 378*bf21cd93STycho Nightingale case 0xffea: /* Right alt */ 379*bf21cd93STycho Nightingale /* XXX */ 380*bf21cd93STycho Nightingale break; 381*bf21cd93STycho Nightingale default: 382*bf21cd93STycho Nightingale fprintf(stderr, "Unhandled ps2 keyboard keysym 0x%x\n", 383*bf21cd93STycho Nightingale keysym); 384*bf21cd93STycho Nightingale break; 385*bf21cd93STycho Nightingale } 386*bf21cd93STycho Nightingale } 387*bf21cd93STycho Nightingale 388*bf21cd93STycho Nightingale static void 389*bf21cd93STycho Nightingale ps2kbd_event(int down, uint32_t keysym, void *arg) 390*bf21cd93STycho Nightingale { 391*bf21cd93STycho Nightingale struct ps2kbd_softc *sc = arg; 392*bf21cd93STycho Nightingale 393*bf21cd93STycho Nightingale pthread_mutex_lock(&sc->mtx); 394*bf21cd93STycho Nightingale if (!sc->enabled) { 395*bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 396*bf21cd93STycho Nightingale return; 397*bf21cd93STycho Nightingale } 398*bf21cd93STycho Nightingale 399*bf21cd93STycho Nightingale ps2kbd_keysym_queue(sc, down, keysym); 400*bf21cd93STycho Nightingale pthread_mutex_unlock(&sc->mtx); 401*bf21cd93STycho Nightingale 402*bf21cd93STycho Nightingale atkbdc_event(sc->atkbdc_sc); 403*bf21cd93STycho Nightingale } 404*bf21cd93STycho Nightingale 405*bf21cd93STycho Nightingale struct ps2kbd_softc * 406*bf21cd93STycho Nightingale ps2kbd_init(struct atkbdc_softc *atkbdc_sc) 407*bf21cd93STycho Nightingale { 408*bf21cd93STycho Nightingale struct ps2kbd_softc *sc; 409*bf21cd93STycho Nightingale 410*bf21cd93STycho Nightingale sc = calloc(1, sizeof (struct ps2kbd_softc)); 411*bf21cd93STycho Nightingale pthread_mutex_init(&sc->mtx, NULL); 412*bf21cd93STycho Nightingale fifo_init(sc); 413*bf21cd93STycho Nightingale sc->atkbdc_sc = atkbdc_sc; 414*bf21cd93STycho Nightingale 415*bf21cd93STycho Nightingale console_kbd_register(ps2kbd_event, sc); 416*bf21cd93STycho Nightingale 417*bf21cd93STycho Nightingale return (sc); 418*bf21cd93STycho Nightingale } 419