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

Cache object: 031e44ba8d68b1bb0da4642bf56c3962


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