The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/adb/adb_kbd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (C) 2008 Nathan Whitehorn
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  *
   25  * $FreeBSD$
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/module.h>
   32 #include <sys/bus.h>
   33 #include <sys/conf.h>
   34 #include <sys/kbio.h>
   35 #include <sys/condvar.h>
   36 #include <sys/callout.h>
   37 #include <sys/kernel.h>
   38 #include <sys/sysctl.h>
   39 
   40 #include <machine/bus.h>
   41 
   42 #include "opt_kbd.h"
   43 #include <dev/kbd/kbdreg.h>
   44 #include <dev/kbd/kbdtables.h>
   45 #include <dev/ofw/openfirm.h>
   46 #include <dev/ofw/ofw_bus.h>
   47 
   48 #include <vm/vm.h>
   49 #include <vm/pmap.h>
   50 
   51 #include "adb.h"
   52 
   53 #define KBD_DRIVER_NAME "akbd"
   54 
   55 #define AKBD_EMULATE_ATKBD 1
   56 
   57 static int adb_kbd_probe(device_t dev);
   58 static int adb_kbd_attach(device_t dev);
   59 static int adb_kbd_detach(device_t dev);
   60 static void akbd_repeat(void *xsc);
   61 static int adb_fn_keys(SYSCTL_HANDLER_ARGS);
   62 
   63 static u_int adb_kbd_receive_packet(device_t dev, u_char status, 
   64         u_char command, u_char reg, int len, u_char *data);
   65 
   66 struct adb_kbd_softc {
   67         keyboard_t sc_kbd;
   68 
   69         device_t sc_dev;
   70         struct mtx sc_mutex;
   71         struct cv  sc_cv;
   72 
   73         int sc_mode;
   74         int sc_state;
   75 
   76         int have_led_control;
   77 
   78         uint8_t buffer[8];
   79 #ifdef AKBD_EMULATE_ATKBD
   80         uint8_t at_buffered_char[2];
   81 #endif
   82         volatile int buffers;
   83 
   84         struct callout sc_repeater;
   85         int sc_repeatstart;
   86         int sc_repeatcontinue;
   87         uint8_t last_press;
   88 };
   89 
   90 static device_method_t adb_kbd_methods[] = {
   91         /* Device interface */
   92         DEVMETHOD(device_probe,         adb_kbd_probe),
   93         DEVMETHOD(device_attach,        adb_kbd_attach),
   94         DEVMETHOD(device_detach,        adb_kbd_detach),
   95         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
   96         DEVMETHOD(device_suspend,       bus_generic_suspend),
   97         DEVMETHOD(device_resume,        bus_generic_resume),
   98 
   99         /* ADB interface */
  100         DEVMETHOD(adb_receive_packet,   adb_kbd_receive_packet),
  101 
  102         { 0, 0 }
  103 };
  104 
  105 static driver_t adb_kbd_driver = {
  106         "akbd",
  107         adb_kbd_methods,
  108         sizeof(struct adb_kbd_softc),
  109 };
  110 
  111 static devclass_t adb_kbd_devclass;
  112 
  113 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
  114 
  115 #ifdef AKBD_EMULATE_ATKBD
  116 
  117 #define SCAN_PRESS              0x000
  118 #define SCAN_RELEASE            0x080
  119 #define SCAN_PREFIX_E0          0x100
  120 #define SCAN_PREFIX_E1          0x200
  121 #define SCAN_PREFIX_CTL         0x400
  122 #define SCAN_PREFIX_SHIFT       0x800
  123 #define SCAN_PREFIX             (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 |      \
  124                                 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
  125 
  126 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34, 
  127         44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13, 
  128         10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43, 
  129         51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98, 
  130         100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0, 
  131         0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61, 
  132         66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103, 
  133         62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
  134 
  135 static int
  136 keycode2scancode(int keycode, int shift, int up)
  137 {
  138         static const int scan[] = {
  139                 /* KP enter, right ctrl, KP divide */
  140                 0x1c , 0x1d , 0x35 ,
  141                 /* print screen */
  142                 0x37 | SCAN_PREFIX_SHIFT,
  143                 /* right alt, home, up, page up, left, right, end */
  144                 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
  145                 /* down, page down, insert, delete */
  146                 0x50, 0x51, 0x52, 0x53,
  147                 /* pause/break (see also below) */
  148                 0x46,
  149                 /*
  150                  * MS: left window, right window, menu
  151                  * also Sun: left meta, right meta, compose
  152                  */
  153                 0x5b, 0x5c, 0x5d,
  154                 /* Sun type 6 USB */
  155                 /* help, stop, again, props, undo, front, copy */
  156                 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
  157                 /* open, paste, find, cut, audiomute, audiolower, audioraise */
  158                 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
  159                 /* power */
  160                 0x20
  161         };
  162         int scancode;
  163 
  164         scancode = keycode;
  165         if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
  166         scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
  167         /* pause/break */
  168         if ((keycode == 104) && !(shift & CTLS))
  169                 scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
  170         if (shift & SHIFTS)
  171                 scancode &= ~SCAN_PREFIX_SHIFT;
  172         return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
  173 }
  174 #endif
  175 
  176 /* keyboard driver declaration */
  177 static int              akbd_configure(int flags);
  178 static kbd_probe_t      akbd_probe;
  179 static kbd_init_t       akbd_init;
  180 static kbd_term_t       akbd_term;
  181 static kbd_intr_t       akbd_interrupt;
  182 static kbd_test_if_t    akbd_test_if;
  183 static kbd_enable_t     akbd_enable;
  184 static kbd_disable_t    akbd_disable;
  185 static kbd_read_t       akbd_read;
  186 static kbd_check_t      akbd_check;
  187 static kbd_read_char_t  akbd_read_char;
  188 static kbd_check_char_t akbd_check_char;
  189 static kbd_ioctl_t      akbd_ioctl;
  190 static kbd_lock_t       akbd_lock;
  191 static kbd_clear_state_t akbd_clear_state;
  192 static kbd_get_state_t  akbd_get_state;
  193 static kbd_set_state_t  akbd_set_state;
  194 static kbd_poll_mode_t  akbd_poll;
  195 
  196 keyboard_switch_t akbdsw = {
  197         .probe =        akbd_probe,
  198         .init =         akbd_init,
  199         .term =         akbd_term,
  200         .intr =         akbd_interrupt,
  201         .test_if =      akbd_test_if,
  202         .enable =       akbd_enable,
  203         .disable =      akbd_disable,
  204         .read =         akbd_read,
  205         .check =        akbd_check,
  206         .read_char =    akbd_read_char,
  207         .check_char =   akbd_check_char,
  208         .ioctl =        akbd_ioctl,
  209         .lock =         akbd_lock,
  210         .clear_state =  akbd_clear_state,
  211         .get_state =    akbd_get_state,
  212         .set_state =    akbd_set_state,
  213         .poll =         akbd_poll,
  214 };
  215 
  216 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
  217 
  218 static int 
  219 adb_kbd_probe(device_t dev) 
  220 {
  221         uint8_t type;
  222 
  223         type = adb_get_device_type(dev);
  224 
  225         if (type != ADB_DEVICE_KEYBOARD)
  226                 return (ENXIO);
  227 
  228         switch(adb_get_device_handler(dev)) {
  229         case 1:
  230                 device_set_desc(dev,"Apple Standard Keyboard");
  231                 break;
  232         case 2:
  233                 device_set_desc(dev,"Apple Extended Keyboard");
  234                 break;
  235         case 4:
  236                 device_set_desc(dev,"Apple ISO Keyboard");
  237                 break;
  238         case 5:
  239                 device_set_desc(dev,"Apple Extended ISO Keyboard");
  240                 break;
  241         case 8:
  242                 device_set_desc(dev,"Apple Keyboard II");
  243                 break;
  244         case 9:
  245                 device_set_desc(dev,"Apple ISO Keyboard II");
  246                 break;
  247         case 12:
  248                 device_set_desc(dev,"PowerBook Keyboard");
  249                 break;
  250         case 13:
  251                 device_set_desc(dev,"PowerBook ISO Keyboard");
  252                 break;
  253         case 24:
  254                 device_set_desc(dev,"PowerBook Extended Keyboard");
  255                 break;
  256         case 27:
  257                 device_set_desc(dev,"Apple Design Keyboard");
  258                 break;
  259         case 195:
  260                 device_set_desc(dev,"PowerBook G3 Keyboard");
  261                 break;
  262         case 196:
  263                 device_set_desc(dev,"iBook Keyboard");
  264                 break;
  265         default:
  266                 device_set_desc(dev,"ADB Keyboard");
  267                 break;
  268         }
  269 
  270         return (0);
  271 }
  272 
  273 static int
  274 ms_to_ticks(int ms)
  275 {
  276         if (hz > 1000)
  277                 return ms*(hz/1000);
  278 
  279         return ms/(1000/hz);
  280 }
  281         
  282 static int 
  283 adb_kbd_attach(device_t dev) 
  284 {
  285         struct adb_kbd_softc *sc;
  286         keyboard_switch_t *sw;
  287         uint32_t fkeys;
  288         phandle_t handle;
  289 
  290         sw = kbd_get_switch(KBD_DRIVER_NAME);
  291         if (sw == NULL) {
  292                 return ENXIO;
  293         }
  294 
  295         sc = device_get_softc(dev);
  296         sc->sc_dev = dev;
  297         sc->sc_mode = K_RAW;
  298         sc->sc_state = 0;
  299         sc->have_led_control = 0;
  300         sc->buffers = 0;
  301 
  302         /* Try stepping forward to the extended keyboard protocol */
  303         adb_set_device_handler(dev,3);
  304 
  305         mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
  306         cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
  307         callout_init(&sc->sc_repeater, 0);
  308 
  309 #ifdef AKBD_EMULATE_ATKBD
  310         kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
  311         kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
  312             sizeof(fkey_tab) / sizeof(fkey_tab[0]));
  313 #else
  314         #error ADB raw mode not implemented
  315 #endif
  316 
  317         KBD_FOUND_DEVICE(&sc->sc_kbd);
  318         KBD_PROBE_DONE(&sc->sc_kbd);
  319         KBD_INIT_DONE(&sc->sc_kbd);
  320         KBD_CONFIG_DONE(&sc->sc_kbd);
  321 
  322         (*sw->enable)(&sc->sc_kbd);
  323 
  324         kbd_register(&sc->sc_kbd);
  325 
  326 #ifdef KBD_INSTALL_CDEV
  327         if (kbd_attach(&sc->sc_kbd)) {
  328                 adb_kbd_detach(dev);
  329                 return ENXIO;
  330         }
  331 #endif
  332 
  333         /* Check if we can read out the LED state from 
  334            this keyboard by reading the key state register */
  335         if (adb_read_register(dev, 2, NULL) == 2)
  336                 sc->have_led_control = 1;
  337 
  338         adb_set_autopoll(dev,1);
  339 
  340         handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
  341         if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
  342             &fkeys, sizeof(fkeys)) != -1) {
  343                 static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
  344                     "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
  345                 struct sysctl_ctx_list *ctx;
  346                 struct sysctl_oid *tree;
  347                 int i;
  348 
  349                 if (bootverbose)
  350                         device_printf(dev, "Keyboard has embedded Fn keys\n");
  351 
  352                 for (i = 0; i < 12; i++) {
  353                         uint32_t keyval;
  354                         char buf[3];
  355                         if (OF_getprop(handle, key_names[i], &keyval,
  356                             sizeof(keyval)) < 0)
  357                                 continue;
  358                         buf[0] = 1;
  359                         buf[1] = i+1;
  360                         buf[2] = keyval;
  361                         adb_write_register(dev, 0, 3, buf);
  362                 }
  363                 adb_write_register(dev, 1, 2, &(uint16_t){0});
  364 
  365                 ctx = device_get_sysctl_ctx(dev);
  366                 tree = device_get_sysctl_tree(dev);
  367 
  368                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
  369                     "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
  370                     0, adb_fn_keys, "I",
  371                     "Set the Fn keys to be their F-key type as default");
  372         }
  373 
  374         return (0);
  375 }
  376 
  377 static int 
  378 adb_kbd_detach(device_t dev) 
  379 {
  380         struct adb_kbd_softc *sc;
  381         keyboard_t *kbd;
  382 
  383         sc = device_get_softc(dev);
  384 
  385         adb_set_autopoll(dev,0);
  386         callout_stop(&sc->sc_repeater);
  387 
  388         mtx_lock(&sc->sc_mutex);
  389 
  390         kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
  391                   device_get_unit(dev)));
  392 
  393         kbdd_disable(kbd);
  394 
  395 #ifdef KBD_INSTALL_CDEV
  396         kbd_detach(kbd);
  397 #endif
  398 
  399         kbdd_term(kbd);
  400 
  401         mtx_unlock(&sc->sc_mutex);
  402 
  403         mtx_destroy(&sc->sc_mutex);
  404         cv_destroy(&sc->sc_cv);
  405 
  406         return (0);
  407 }
  408 
  409 static u_int 
  410 adb_kbd_receive_packet(device_t dev, u_char status, 
  411     u_char command, u_char reg, int len, u_char *data)
  412 {
  413         struct adb_kbd_softc *sc;
  414 
  415         sc = device_get_softc(dev);
  416 
  417         if (command != ADB_COMMAND_TALK)
  418                 return 0;
  419 
  420         if (reg != 0 || len != 2)
  421                 return (0);
  422 
  423         mtx_lock(&sc->sc_mutex);
  424                 /* 0x7f is always the power button */
  425                 if (data[0] == 0x7f) {
  426                         devctl_notify("PMU", "Button", "pressed", NULL);
  427                         mtx_unlock(&sc->sc_mutex);
  428                         return (0);
  429                 } else if (data[0] == 0xff) {
  430                         mtx_unlock(&sc->sc_mutex);
  431                         return (0);     /* Ignore power button release. */
  432                 }
  433                 if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
  434                         /* Fake the down/up cycle for caps lock */
  435                         sc->buffer[sc->buffers++] = data[0] & 0x7f;
  436                         sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
  437                 } else {
  438                         sc->buffer[sc->buffers++] = data[0];
  439                 }
  440                 if (sc->buffer[sc->buffers-1] < 0xff)
  441                         sc->last_press = sc->buffer[sc->buffers-1];
  442 
  443                 if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
  444                         /* Fake the down/up cycle for caps lock */
  445                         sc->buffer[sc->buffers++] = data[1] & 0x7f;
  446                         sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
  447                 } else {
  448                         sc->buffer[sc->buffers++] = data[1];
  449                 }
  450 
  451                 if (sc->buffer[sc->buffers-1] < 0xff)
  452                         sc->last_press = sc->buffer[sc->buffers-1];
  453 
  454                 /* Stop any existing key repeating */
  455                 callout_stop(&sc->sc_repeater);
  456 
  457                 /* Schedule a repeat callback on keydown */
  458                 if (!(sc->last_press & (1 << 7))) {
  459                         callout_reset(&sc->sc_repeater, 
  460                             ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
  461                 }
  462         mtx_unlock(&sc->sc_mutex);
  463 
  464         cv_broadcast(&sc->sc_cv);
  465 
  466         if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
  467                 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
  468                          KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
  469         }
  470 
  471         return (0);
  472 }
  473 
  474 static void
  475 akbd_repeat(void *xsc) {
  476         struct adb_kbd_softc *sc = xsc;
  477         int notify_kbd = 0;
  478 
  479         /* Fake an up/down key repeat so long as we have the
  480            free buffers */
  481         mtx_lock(&sc->sc_mutex);
  482                 if (sc->buffers < 7) {
  483                         sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
  484                         sc->buffer[sc->buffers++] = sc->last_press;
  485 
  486                         notify_kbd = 1;
  487                 }
  488         mtx_unlock(&sc->sc_mutex);
  489 
  490         if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) 
  491             && KBD_IS_BUSY(&sc->sc_kbd)) {
  492                 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
  493                     KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
  494         }
  495 
  496         /* Reschedule the callout */
  497         callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
  498             akbd_repeat, sc);
  499 }
  500         
  501 static int 
  502 akbd_configure(int flags) 
  503 {
  504         return 0;
  505 }
  506 
  507 static int 
  508 akbd_probe(int unit, void *arg, int flags) 
  509 {
  510         return 0;
  511 }
  512 
  513 static int 
  514 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 
  515 {
  516         return 0;
  517 }
  518 
  519 static int 
  520 akbd_term(keyboard_t *kbd) 
  521 {
  522         return 0;
  523 }
  524 
  525 static int 
  526 akbd_interrupt(keyboard_t *kbd, void *arg) 
  527 {
  528         return 0;
  529 }
  530 
  531 static int 
  532 akbd_test_if(keyboard_t *kbd) 
  533 {
  534         return 0;
  535 }
  536 
  537 static int 
  538 akbd_enable(keyboard_t *kbd) 
  539 {
  540         KBD_ACTIVATE(kbd);
  541         return (0);
  542 }
  543 
  544 static int 
  545 akbd_disable(keyboard_t *kbd) 
  546 {
  547         struct adb_kbd_softc *sc;
  548         sc = (struct adb_kbd_softc *)(kbd);
  549 
  550         callout_stop(&sc->sc_repeater);
  551         KBD_DEACTIVATE(kbd);
  552         return (0);
  553 }
  554 
  555 static int 
  556 akbd_read(keyboard_t *kbd, int wait) 
  557 {
  558         return (0);
  559 }
  560 
  561 static int 
  562 akbd_check(keyboard_t *kbd) 
  563 {
  564         struct adb_kbd_softc *sc;
  565 
  566         if (!KBD_IS_ACTIVE(kbd))
  567                 return (FALSE);
  568 
  569         sc = (struct adb_kbd_softc *)(kbd);
  570 
  571         mtx_lock(&sc->sc_mutex);
  572 #ifdef AKBD_EMULATE_ATKBD
  573                 if (sc->at_buffered_char[0]) {
  574                         mtx_unlock(&sc->sc_mutex);
  575                         return (TRUE);
  576                 }
  577 #endif
  578 
  579                 if (sc->buffers > 0) {
  580                         mtx_unlock(&sc->sc_mutex);
  581                         return (TRUE); 
  582                 }
  583         mtx_unlock(&sc->sc_mutex);
  584 
  585         return (FALSE);
  586 }
  587 
  588 static u_int 
  589 akbd_read_char(keyboard_t *kbd, int wait) 
  590 {
  591         struct adb_kbd_softc *sc;
  592         uint16_t key;
  593         uint8_t adb_code;
  594         int i;
  595 
  596         sc = (struct adb_kbd_softc *)(kbd);
  597 
  598         mtx_lock(&sc->sc_mutex);
  599 
  600 #if defined(AKBD_EMULATE_ATKBD)
  601         if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
  602                 key = sc->at_buffered_char[0];
  603                 if (key & SCAN_PREFIX) {
  604                         sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
  605                         key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
  606                 } else {
  607                         sc->at_buffered_char[0] = sc->at_buffered_char[1];
  608                         sc->at_buffered_char[1] = 0;
  609                 }
  610 
  611                 mtx_unlock(&sc->sc_mutex);
  612 
  613                 return (key);
  614         }
  615 #endif
  616 
  617         if (!sc->buffers && wait)
  618                 cv_wait(&sc->sc_cv,&sc->sc_mutex);
  619 
  620         if (!sc->buffers) {
  621                 mtx_unlock(&sc->sc_mutex);
  622                 return (NOKEY);
  623         }
  624 
  625         adb_code = sc->buffer[0];
  626 
  627         for (i = 1; i < sc->buffers; i++)
  628                 sc->buffer[i-1] = sc->buffer[i];
  629 
  630         sc->buffers--;
  631 
  632         #ifdef AKBD_EMULATE_ATKBD
  633                 key = adb_to_at_scancode_map[adb_code & 0x7f];
  634                 if (sc->sc_mode == K_CODE) {
  635                         /* Add the key-release bit */
  636                         key |= adb_code & 0x80;
  637                 } else if (sc->sc_mode == K_RAW) {
  638                         /*
  639                          * In the raw case, we have to emulate the gross
  640                          * variable-length AT keyboard thing. Since this code
  641                          * is copied from sunkbd, which is the same code
  642                          * as ukbd, it might be nice to have this centralized.
  643                          */
  644 
  645                         key = keycode2scancode(key, 
  646                             0, adb_code & 0x80);
  647 
  648                         if (key & SCAN_PREFIX) {
  649                                 if (key & SCAN_PREFIX_CTL) {
  650                                         sc->at_buffered_char[0] =
  651                                             0x1d | (key & SCAN_RELEASE);
  652                                         sc->at_buffered_char[1] =
  653                                             key & ~SCAN_PREFIX;
  654                                 } else if (key & SCAN_PREFIX_SHIFT) {
  655                                         sc->at_buffered_char[0] =
  656                                             0x2a | (key & SCAN_RELEASE);
  657                                         sc->at_buffered_char[1] =
  658                                             key & ~SCAN_PREFIX_SHIFT;
  659                                 } else {
  660                                         sc->at_buffered_char[0] =
  661                                             key & ~SCAN_PREFIX;
  662                                         sc->at_buffered_char[1] = 0;
  663                                 }
  664         
  665                                 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
  666                         }
  667                 }
  668         #else
  669                 key = adb_code;
  670         #endif
  671 
  672         mtx_unlock(&sc->sc_mutex);
  673 
  674         return (key);
  675 }
  676 
  677 static int 
  678 akbd_check_char(keyboard_t *kbd) 
  679 {
  680         if (!KBD_IS_ACTIVE(kbd))
  681                 return (FALSE);
  682 
  683         return (akbd_check(kbd));
  684 }
  685 
  686 static int
  687 set_typematic(keyboard_t *kbd, int code)
  688 {
  689         /* These numbers are in microseconds, so convert to ticks */
  690 
  691         static int delays[] = { 250, 500, 750, 1000 };
  692         static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
  693                                 68,  76,  84,  92, 100, 110, 118, 126,
  694                                 136, 152, 168, 184, 200, 220, 236, 252,
  695                                 272, 304, 336, 368, 400, 440, 472, 504 };
  696                 
  697         if (code & ~0x7f)
  698                 return EINVAL;
  699         kbd->kb_delay1 = delays[(code >> 5) & 3];
  700         kbd->kb_delay2 = rates[code & 0x1f];
  701         return 0;
  702 }
  703 
  704 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
  705 {
  706         struct adb_kbd_softc *sc;
  707         uint16_t r2;
  708         int error;
  709 
  710         sc = (struct adb_kbd_softc *)(kbd);
  711         error = 0;
  712 
  713         switch (cmd) {
  714         case KDGKBMODE:
  715                 *(int *)data = sc->sc_mode;
  716                 break;
  717         case KDSKBMODE:
  718                 switch (*(int *)data) {
  719                 case K_XLATE:
  720                         if (sc->sc_mode != K_XLATE) {
  721                                 /* make lock key state and LED state match */
  722                                 sc->sc_state &= ~LOCK_MASK;
  723                                 sc->sc_state |= KBD_LED_VAL(kbd);
  724                         }
  725                         /* FALLTHROUGH */
  726                 case K_RAW:
  727                 case K_CODE:
  728                         if (sc->sc_mode != *(int *)data) 
  729                                 sc->sc_mode = *(int *)data;
  730                         break;
  731                 default:
  732                         error = EINVAL;
  733                         break;
  734                 }
  735 
  736                 break;
  737 
  738         case KDGETLED:
  739                 *(int *)data = KBD_LED_VAL(kbd);
  740                 break;
  741 
  742         case KDSKBSTATE:
  743                 if (*(int *)data & ~LOCK_MASK) {
  744                         error = EINVAL;
  745                         break;
  746                 }
  747                 sc->sc_state &= ~LOCK_MASK;
  748                 sc->sc_state |= *(int *)data;
  749 
  750                 /* FALLTHROUGH */
  751 
  752         case KDSETLED:
  753                 KBD_LED_VAL(kbd) = *(int *)data;
  754         
  755                 if (!sc->have_led_control)
  756                         break;
  757 
  758                 r2 = (~0 & 0x04) | 3;
  759 
  760                 if (*(int *)data & NLKED)
  761                         r2 &= ~1;
  762                 if (*(int *)data & CLKED)
  763                         r2 &= ~2;
  764                 if (*(int *)data & SLKED)
  765                         r2 &= ~4;
  766 
  767                 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
  768                         sizeof(uint16_t),(u_char *)&r2);
  769                 
  770                 break;
  771 
  772         case KDGKBSTATE:
  773                 *(int *)data = sc->sc_state & LOCK_MASK;
  774                 break;
  775 
  776         case KDSETREPEAT:
  777                 if (!KBD_HAS_DEVICE(kbd))
  778                         return 0;
  779                 if (((int *)data)[1] < 0)
  780                         return EINVAL;
  781                 if (((int *)data)[0] < 0)
  782                         return EINVAL;
  783                 else if (((int *)data)[0] == 0)  /* fastest possible value */
  784                         kbd->kb_delay1 = 200;
  785                 else
  786                         kbd->kb_delay1 = ((int *)data)[0];
  787                 kbd->kb_delay2 = ((int *)data)[1];
  788 
  789                 break;
  790 
  791         case KDSETRAD:
  792                 error = set_typematic(kbd, *(int *)data);
  793                 break;
  794 
  795         case PIO_KEYMAP:
  796         case OPIO_KEYMAP:
  797         case PIO_KEYMAPENT:
  798         case PIO_DEADKEYMAP:
  799         default:
  800                 return (genkbd_commonioctl(kbd, cmd, data));
  801         }
  802 
  803         return (error);
  804 }
  805 
  806 static int akbd_lock(keyboard_t *kbd, int lock)
  807 {
  808         return (0);
  809 }
  810 
  811 static void akbd_clear_state(keyboard_t *kbd)
  812 {
  813         struct adb_kbd_softc *sc;
  814 
  815         sc = (struct adb_kbd_softc *)(kbd);
  816 
  817         mtx_lock(&sc->sc_mutex);
  818 
  819         sc->buffers = 0;
  820         callout_stop(&sc->sc_repeater);
  821 
  822 #if defined(AKBD_EMULATE_ATKBD) 
  823         sc->at_buffered_char[0] = 0;
  824         sc->at_buffered_char[1] = 0;
  825 #endif
  826         mtx_unlock(&sc->sc_mutex);
  827 }
  828 
  829 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
  830 {
  831         return (0);
  832 }
  833 
  834 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
  835 {
  836         return (0);
  837 }
  838 
  839 static int akbd_poll(keyboard_t *kbd, int on) 
  840 {
  841         return (0);
  842 }
  843 
  844 static int
  845 akbd_modevent(module_t mod, int type, void *data)
  846 {
  847         switch (type) {
  848         case MOD_LOAD:
  849                 kbd_add_driver(&akbd_kbd_driver);
  850                 break;
  851 
  852         case MOD_UNLOAD:
  853                 kbd_delete_driver(&akbd_kbd_driver);
  854                 break;
  855 
  856         default:
  857                 return (EOPNOTSUPP);
  858         }
  859 
  860         return (0);
  861 }
  862 
  863 static int
  864 adb_fn_keys(SYSCTL_HANDLER_ARGS)
  865 {
  866         struct adb_kbd_softc *sc = arg1;
  867         int error;
  868         uint16_t is_fn_enabled;
  869         unsigned int is_fn_enabled_sysctl;
  870 
  871         adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
  872         is_fn_enabled &= 1;
  873         is_fn_enabled_sysctl = is_fn_enabled;
  874         error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
  875 
  876         if (error || !req->newptr)
  877                 return (error);
  878 
  879         is_fn_enabled = is_fn_enabled_sysctl;
  880         if (is_fn_enabled != 1 && is_fn_enabled != 0)
  881                 return (EINVAL);
  882 
  883         adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
  884         return (0);
  885 }
  886 
  887 DEV_MODULE(akbd, akbd_modevent, NULL);
  888 

Cache object: e42219be220936aba29582e235f9feda


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.