root/dev/sun/sunkbd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sunkbd_bell
  2. sunkbd_bellstop
  3. sunkbd_decode
  4. sunkbd_enable
  5. sunkbd_getleds
  6. sunkbd_ioctl
  7. sunkbd_raw
  8. sunkbd_setclick
  9. sunkbd_setleds

    1 /*      $OpenBSD: sunkbd.c,v 1.21 2005/11/11 16:44:51 miod Exp $        */
    2 
    3 /*
    4  * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
    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
   18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26  * POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * Effort sponsored in part by the Defense Advanced Research Projects
   29  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   30  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
   31  *
   32  */
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/device.h>
   37 #include <sys/kernel.h>
   38 #include <sys/timeout.h>
   39 
   40 #include <dev/wscons/wsconsio.h>
   41 #include <dev/wscons/wskbdvar.h>
   42 
   43 #include <dev/sun/sunkbdreg.h>
   44 #include <dev/sun/sunkbdvar.h>
   45 
   46 #ifdef __sparc64__
   47 #define NTCTRL 0
   48 #else
   49 #include "tctrl.h"
   50 #endif
   51 
   52 #if NTCTRL > 0
   53 #include <sparc/dev/tctrlvar.h>         /* XXX for tadpole_bell() */
   54 #endif
   55 
   56 void    sunkbd_bell(struct sunkbd_softc *, u_int, u_int, u_int);
   57 int     sunkbd_enable(void *, int);
   58 int     sunkbd_getleds(struct sunkbd_softc *);
   59 int     sunkbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
   60 void    sunkbd_setleds(void *, int);
   61 
   62 struct wskbd_accessops sunkbd_accessops = {
   63         sunkbd_enable,
   64         sunkbd_setleds,
   65         sunkbd_ioctl
   66 };
   67 
   68 void
   69 sunkbd_bell(struct sunkbd_softc *sc, u_int period, u_int pitch, u_int volume)
   70 {
   71         int ticks, s;
   72         u_int8_t c = SKBD_CMD_BELLON;
   73 
   74 #if NTCTRL > 0
   75         if (tadpole_bell(period / 10, pitch, volume) != 0)
   76                 return;
   77 #endif
   78 
   79         s = spltty();
   80         if (sc->sc_bellactive) {
   81                 if (sc->sc_belltimeout == 0)
   82                         timeout_del(&sc->sc_bellto);
   83         }
   84         if (pitch == 0 || period == 0) {
   85                 sunkbd_bellstop(sc);
   86                 splx(s);
   87                 return;
   88         }
   89         if (sc->sc_bellactive == 0) {
   90                 ticks = (period * hz) / 1000;
   91                 if (ticks <= 0)
   92                         ticks = 1;
   93 
   94                 sc->sc_bellactive = 1;
   95                 sc->sc_belltimeout = 1;
   96                 (*sc->sc_sendcmd)(sc, &c, 1);
   97                 timeout_add(&sc->sc_bellto, ticks);
   98         }
   99         splx(s);
  100 }
  101 
  102 void
  103 sunkbd_bellstop(void *v)
  104 {
  105         struct sunkbd_softc *sc = v;
  106         int s;
  107         u_int8_t c;
  108 
  109         s = spltty();
  110         sc->sc_belltimeout = 0;
  111         c = SKBD_CMD_BELLOFF;
  112         (*sc->sc_sendcmd)(v, &c, 1);
  113         sc->sc_bellactive = 0;
  114         splx(s);
  115 }
  116 
  117 void
  118 sunkbd_decode(u_int8_t c, u_int *type, int *value)
  119 {
  120         switch (c) {
  121         case SKBD_RSP_IDLE:
  122                 *type = WSCONS_EVENT_ALL_KEYS_UP;
  123                 *value = 0;
  124                 break;
  125         default:
  126                 *type = (c & 0x80) ?
  127                     WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
  128                 *value = c & 0x7f;
  129                 break;
  130         }
  131 }
  132 
  133 int
  134 sunkbd_enable(void *v, int on)
  135 {
  136         return (0);
  137 }
  138 
  139 int
  140 sunkbd_getleds(struct sunkbd_softc *sc)
  141 {
  142         return (sc->sc_leds);
  143 }
  144 
  145 int
  146 sunkbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
  147 {
  148         struct sunkbd_softc *sc = v;
  149         int *d_int = (int *)data;
  150         struct wskbd_bell_data *d_bell = (struct wskbd_bell_data *)data;
  151 
  152         switch (cmd) {
  153         case WSKBDIO_GTYPE:
  154                 if (ISTYPE5(sc->sc_layout)) {
  155                         *d_int = WSKBD_TYPE_SUN5;
  156                 } else {
  157                         *d_int = WSKBD_TYPE_SUN;
  158                 }
  159                 return (0);
  160         case WSKBDIO_SETLEDS:
  161                 sunkbd_setleds(sc, *d_int);
  162                 return (0);
  163         case WSKBDIO_GETLEDS:
  164                 *d_int = sunkbd_getleds(sc);
  165                 return (0);
  166         case WSKBDIO_COMPLEXBELL:
  167                 sunkbd_bell(sc, d_bell->period, d_bell->pitch, d_bell->volume);
  168                 return (0);
  169         }
  170 
  171         return (-1);
  172 }
  173 
  174 void
  175 sunkbd_raw(struct sunkbd_softc *sc, u_int8_t c)
  176 {
  177         int claimed = 0;
  178 
  179         if (sc->sc_kbdstate == SKBD_STATE_LAYOUT) {
  180                 sc->sc_kbdstate = SKBD_STATE_GETKEY;
  181                 sc->sc_layout = c;
  182                 return;
  183         }
  184 
  185         switch (c) {
  186         case SKBD_RSP_RESET:
  187                 sc->sc_kbdstate = SKBD_STATE_RESET;
  188                 claimed = 1;
  189                 break;
  190         case SKBD_RSP_LAYOUT:
  191                 sc->sc_kbdstate = SKBD_STATE_LAYOUT;
  192                 claimed = 1;
  193                 break;
  194         case SKBD_RSP_IDLE:
  195                 sc->sc_kbdstate = SKBD_STATE_GETKEY;
  196                 claimed = 1;
  197         }
  198 
  199         if (claimed)
  200                 return;
  201 
  202         switch (sc->sc_kbdstate) {
  203         case SKBD_STATE_RESET:
  204                 sc->sc_kbdstate = SKBD_STATE_GETKEY;
  205                 if (c < KB_SUN2 || c > KB_SUN4)
  206                         printf("%s: reset: invalid keyboard type 0x%02x\n",
  207                             sc->sc_dev.dv_xname, c);
  208                 else
  209                         sc->sc_id = c;
  210                 break;
  211         case SKBD_STATE_GETKEY:
  212                 break;
  213         }
  214 }
  215 
  216 int
  217 sunkbd_setclick(struct sunkbd_softc *sc, int click)
  218 {
  219         u_int8_t c;
  220 
  221         /* Type 2 keyboards do not support keyclick */
  222         if (sc->sc_id == KB_SUN2)
  223                 return (ENXIO);
  224 
  225         c = click ? SKBD_CMD_CLICKON : SKBD_CMD_CLICKOFF;
  226         (*sc->sc_sendcmd)(sc, &c, 1);
  227         return (0);
  228 }
  229 
  230 void
  231 sunkbd_setleds(void *v, int wled)
  232 {
  233         struct sunkbd_softc *sc = v;
  234         u_int8_t sled = 0;
  235         u_int8_t cmd[2];
  236 
  237         sc->sc_leds = wled;
  238 
  239         if (wled & WSKBD_LED_CAPS)
  240                 sled |= SKBD_LED_CAPSLOCK;
  241         if (wled & WSKBD_LED_NUM)
  242                 sled |= SKBD_LED_NUMLOCK;
  243         if (wled & WSKBD_LED_SCROLL)
  244                 sled |= SKBD_LED_SCROLLLOCK;
  245         if (wled & WSKBD_LED_COMPOSE)
  246                 sled |= SKBD_LED_COMPOSE;
  247 
  248         cmd[0] = SKBD_CMD_SETLED;
  249         cmd[1] = sled;
  250         (*sc->sc_sendcmd)(sc, cmd, sizeof(cmd));
  251 }

/* [<][>][^][v][top][bottom][index][help] */