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

Cache object: 3dc8b76b4e8e7fe036150327aced61ad


[ 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.