[BACK]Return to zaurus_kbd.c CVS log [TXT][DIR] Up to [local] / sys / arch / zaurus / dev

Annotation of sys/arch/zaurus/dev/zaurus_kbd.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: zaurus_kbd.c,v 1.28 2005/12/21 20:36:03 deraadt Exp $ */
        !             2: /*
        !             3:  * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17:
        !            18: #include <sys/param.h>
        !            19: #include <sys/systm.h>
        !            20: #include <sys/device.h>
        !            21: #include <sys/malloc.h>
        !            22: #include <sys/timeout.h>
        !            23: #include <sys/kernel.h>
        !            24: #include <sys/proc.h>
        !            25: #include <sys/signalvar.h>
        !            26:
        !            27: #include <arm/xscale/pxa2x0reg.h>
        !            28: #include <arm/xscale/pxa2x0_gpio.h>
        !            29:
        !            30: #include <dev/wscons/wsconsio.h>
        !            31: #include <dev/wscons/wskbdvar.h>
        !            32: #include <dev/wscons/wsksymdef.h>
        !            33: #include <dev/wscons/wsksymvar.h>
        !            34:
        !            35: #include <zaurus/dev/zaurus_kbdmap.h>
        !            36:
        !            37: #include "apm.h"
        !            38:
        !            39: const int
        !            40: gpio_sense_pins_c3000[] = {
        !            41:        12,
        !            42:        17,
        !            43:        91,
        !            44:        34,
        !            45:        36,
        !            46:        38,
        !            47:        39,
        !            48:        -1
        !            49: };
        !            50:
        !            51: const int
        !            52: gpio_strobe_pins_c3000[] = {
        !            53:        88,
        !            54:        23,
        !            55:        24,
        !            56:        25,
        !            57:        26,
        !            58:        27,
        !            59:        52,
        !            60:        103,
        !            61:        107,
        !            62:        -1,
        !            63:        108,
        !            64:        114
        !            65: };
        !            66:
        !            67: const int stuck_keys[] = {
        !            68:        7,
        !            69:        15,
        !            70:        23,
        !            71:        31
        !            72: };
        !            73:
        !            74:
        !            75: #define REP_DELAY1 400
        !            76: #define REP_DELAYN 100
        !            77:
        !            78: struct zkbd_softc {
        !            79:        struct device sc_dev;
        !            80:
        !            81:        const int *sc_sense_array;
        !            82:        const int *sc_strobe_array;
        !            83:        int sc_nsense;
        !            84:        int sc_nstrobe;
        !            85:
        !            86:        short sc_onkey_pin;
        !            87:        short sc_sync_pin;
        !            88:        short sc_swa_pin;
        !            89:        short sc_swb_pin;
        !            90:        char *sc_okeystate;
        !            91:        char *sc_keystate;
        !            92:        char sc_hinge;          /* 0=open, 1=nonsense, 2=backwards, 3=closed */
        !            93:        char sc_maxkbdcol;
        !            94:
        !            95:        struct timeout sc_roll_to;
        !            96:
        !            97:        /* console stuff */
        !            98:        int sc_polling;
        !            99:        int sc_pollUD;
        !           100:        int sc_pollkey;
        !           101:
        !           102:        /* wskbd bits */
        !           103:        struct device   *sc_wskbddev;
        !           104:        int sc_rawkbd;
        !           105: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           106:        const char *sc_xt_keymap;
        !           107:        struct timeout sc_rawrepeat_ch;
        !           108: #define MAXKEYS 20
        !           109:        char sc_rep[MAXKEYS];
        !           110:        int sc_nrep;
        !           111: #endif
        !           112:        void *sc_powerhook;
        !           113: };
        !           114:
        !           115: struct zkbd_softc *zkbd_dev; /* XXX */
        !           116:
        !           117: int zkbd_match(struct device *, void *, void *);
        !           118: void zkbd_attach(struct device *, struct device *, void *);
        !           119:
        !           120: int zkbd_irq(void *v);
        !           121: void zkbd_poll(void *v);
        !           122: int zkbd_on(void *v);
        !           123: int zkbd_sync(void *v);
        !           124: int zkbd_hinge(void *v);
        !           125: void zkbd_power(int why, void *arg);
        !           126:
        !           127: int zkbd_modstate;
        !           128:
        !           129: struct cfattach zkbd_ca = {
        !           130:        sizeof(struct zkbd_softc), zkbd_match, zkbd_attach
        !           131: };
        !           132:
        !           133: struct cfdriver zkbd_cd = {
        !           134:        NULL, "zkbd", DV_DULL
        !           135: };
        !           136:
        !           137: int zkbd_enable(void *, int);
        !           138: void zkbd_set_leds(void *, int);
        !           139: int zkbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           140: void zkbd_rawrepeat(void *v);
        !           141:
        !           142: struct wskbd_accessops zkbd_accessops = {
        !           143:        zkbd_enable,
        !           144:        zkbd_set_leds,
        !           145:        zkbd_ioctl,
        !           146: };
        !           147:
        !           148: void zkbd_cngetc(void *, u_int *, int *);
        !           149: void zkbd_cnpollc(void *, int);
        !           150:
        !           151: struct wskbd_consops zkbd_consops = {
        !           152:         zkbd_cngetc,
        !           153:         zkbd_cnpollc,
        !           154: };
        !           155:
        !           156: struct wskbd_mapdata zkbd_keymapdata = {
        !           157:         zkbd_keydesctab,
        !           158:         KB_US,
        !           159: };
        !           160:
        !           161:
        !           162:
        !           163: int
        !           164: zkbd_match(struct device *parent, void *cf, void *aux)
        !           165: {
        !           166:        return 1;
        !           167: }
        !           168:
        !           169:
        !           170: void
        !           171: zkbd_attach(struct device *parent, struct device *self, void *aux)
        !           172: {
        !           173:        struct zkbd_softc *sc = (struct zkbd_softc *)self;
        !           174:        struct wskbddev_attach_args a;
        !           175:        int pin, i;
        !           176:        extern int glass_console;
        !           177:
        !           178:        zkbd_dev = sc;
        !           179:        sc->sc_polling = 0;
        !           180: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           181:        sc->sc_rawkbd = 0;
        !           182: #endif
        !           183:        /* Determine which system we are - XXX */
        !           184:
        !           185:        sc->sc_powerhook = powerhook_establish(zkbd_power, sc);
        !           186:        if (sc->sc_powerhook == NULL) {
        !           187:                printf(": unable to establish powerhook\n");
        !           188:                return;
        !           189:        }
        !           190:
        !           191:        if (1 /* C3000 */) {
        !           192:                sc->sc_sense_array = gpio_sense_pins_c3000;
        !           193:                sc->sc_strobe_array = gpio_strobe_pins_c3000;
        !           194:                sc->sc_nsense = sizeof(gpio_sense_pins_c3000)/sizeof(int);
        !           195:                sc->sc_nstrobe = sizeof(gpio_strobe_pins_c3000)/sizeof(int);
        !           196:                sc->sc_maxkbdcol = 10;
        !           197:                sc->sc_onkey_pin = 95;
        !           198:                sc->sc_sync_pin = 16;
        !           199:                sc->sc_swa_pin = 97;
        !           200:                sc->sc_swb_pin = 96;
        !           201: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           202:                sc->sc_xt_keymap = xt_keymap;
        !           203: #endif
        !           204:        } /* XXX */
        !           205:
        !           206:        sc->sc_okeystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
        !           207:            M_DEVBUF, M_NOWAIT);
        !           208:        bzero(sc->sc_okeystate, (sc->sc_nsense * sc->sc_nstrobe));
        !           209:
        !           210:        sc->sc_keystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
        !           211:            M_DEVBUF, M_NOWAIT);
        !           212:        bzero(sc->sc_keystate, (sc->sc_nsense * sc->sc_nstrobe));
        !           213:
        !           214:        /* set all the strobe bits */
        !           215:        for (i = 0; i < sc->sc_nstrobe; i++) {
        !           216:                pin = sc->sc_strobe_array[i];
        !           217:                if (pin == -1) {
        !           218:                        continue;
        !           219:                }
        !           220:                pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT);
        !           221:        }
        !           222:        /* set all the sense bits */
        !           223:        for (i = 0; i < sc->sc_nsense; i++) {
        !           224:                pin = sc->sc_sense_array[i];
        !           225:                if (pin == -1) {
        !           226:                        continue;
        !           227:                }
        !           228:                pxa2x0_gpio_set_function(pin, GPIO_IN);
        !           229:                pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH, IPL_TTY,
        !           230:                    zkbd_irq, sc, sc->sc_dev.dv_xname);
        !           231:        }
        !           232:        pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH, IPL_TTY,
        !           233:            zkbd_on, sc, sc->sc_dev.dv_xname);
        !           234:        pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING, IPL_TTY,
        !           235:            zkbd_sync, sc, sc->sc_dev.dv_xname);
        !           236:        pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH, IPL_TTY,
        !           237:            zkbd_hinge, sc, sc->sc_dev.dv_xname);
        !           238:        pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH, IPL_TTY,
        !           239:            zkbd_hinge, sc, sc->sc_dev.dv_xname);
        !           240:
        !           241:        if (glass_console) {
        !           242:                wskbd_cnattach(&zkbd_consops, sc, &zkbd_keymapdata);
        !           243:                a.console = 1;
        !           244:        } else {
        !           245:                a.console = 0;
        !           246:        }
        !           247:
        !           248:        a.keymap = &zkbd_keymapdata;
        !           249:        a.accessops = &zkbd_accessops;
        !           250:        a.accesscookie = sc;
        !           251:
        !           252:        printf("\n");
        !           253:
        !           254:        zkbd_hinge(sc);         /* to initialize sc_hinge */
        !           255:
        !           256:        sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
        !           257:
        !           258:        timeout_set(&(sc->sc_roll_to), zkbd_poll, sc);
        !           259: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           260:        timeout_set(&sc->sc_rawrepeat_ch, zkbd_rawrepeat, sc);
        !           261: #endif
        !           262:
        !           263: }
        !           264:
        !           265: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           266: void
        !           267: zkbd_rawrepeat(void *v)
        !           268: {
        !           269:        struct zkbd_softc *sc = v;
        !           270:        int s;
        !           271:
        !           272:        s = spltty();
        !           273:        wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
        !           274:        splx(s);
        !           275:        timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
        !           276: }
        !           277: #endif
        !           278:
        !           279: /* XXX only deal with keys that can be pressed when display is open? */
        !           280: /* XXX are some not in the array? */
        !           281: /* handle keypress interrupt */
        !           282: int
        !           283: zkbd_irq(void *v)
        !           284: {
        !           285:        zkbd_poll(v);
        !           286:
        !           287:        return 1;
        !           288: }
        !           289:
        !           290: void
        !           291: zkbd_poll(void *v)
        !           292: {
        !           293:        struct zkbd_softc *sc = v;
        !           294:        int i, j, col, pin, type, keysdown = 0, s;
        !           295:        int stuck;
        !           296:        int keystate;
        !           297: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           298:        int npress = 0, ncbuf = 0, c;
        !           299:        char cbuf[MAXKEYS *2];
        !           300: #endif
        !           301:
        !           302:        s = spltty();
        !           303:
        !           304:        /* discharge all */
        !           305:        for (i = 0; i < sc->sc_nstrobe; i++) {
        !           306:                pin = sc->sc_strobe_array[i];
        !           307:                if (pin != -1) {
        !           308:                        pxa2x0_gpio_clear_bit(pin);
        !           309:                        pxa2x0_gpio_set_dir(pin, GPIO_IN);
        !           310:                }
        !           311:        }
        !           312:
        !           313:        delay (10);
        !           314:        for(col = 0; col < sc->sc_nstrobe; col++) {
        !           315:                if (sc->sc_strobe_array[i] == -1)
        !           316:                        continue;
        !           317:
        !           318:                pin = sc->sc_strobe_array[col];
        !           319:
        !           320:                /* activate_col */
        !           321:                pxa2x0_gpio_set_bit(pin);
        !           322:                pxa2x0_gpio_set_dir(pin, GPIO_OUT);
        !           323:
        !           324:                /* wait activate delay */
        !           325:                delay(10);
        !           326:
        !           327:                /* read row */
        !           328:                for (i = 0; i < sc->sc_nsense; i++) {
        !           329:                        int bit;
        !           330:
        !           331:                        if (sc->sc_sense_array[i] == -1)
        !           332:                                continue;
        !           333:
        !           334:                        bit = pxa2x0_gpio_get_bit(sc->sc_sense_array[i]);
        !           335:                        if (bit && sc->sc_hinge && col < sc->sc_maxkbdcol)
        !           336:                                continue;
        !           337:                        sc->sc_keystate[i + (col * sc->sc_nsense)] = bit;
        !           338:                }
        !           339:
        !           340:                /* reset_col */
        !           341:                pxa2x0_gpio_set_dir(pin, GPIO_IN);
        !           342:                /* wait discharge delay */
        !           343:                delay(10);
        !           344:        }
        !           345:        /* charge all */
        !           346:        for (i = 0; i < sc->sc_nstrobe; i++) {
        !           347:                pin = sc->sc_strobe_array[i];
        !           348:                if (pin != -1) {
        !           349:                        pxa2x0_gpio_set_bit(pin);
        !           350:                        pxa2x0_gpio_set_dir(pin, GPIO_OUT);
        !           351:                }
        !           352:        }
        !           353:
        !           354:        /* force the irqs to clear as we have just played with them. */
        !           355:        for (i = 0; i < sc->sc_nsense; i++)
        !           356:                if (sc->sc_sense_array[i] != -1)
        !           357:                        pxa2x0_gpio_clear_intr(sc->sc_sense_array[i]);
        !           358:
        !           359:        /* process after resetting interrupt */
        !           360:
        !           361:        zkbd_modstate = (
        !           362:                (sc->sc_keystate[84] ? (1 << 0) : 0) | /* shift */
        !           363:                (sc->sc_keystate[93] ? (1 << 1) : 0) | /* Fn */
        !           364:                (sc->sc_keystate[14] ? (1 << 2) : 0)); /* 'alt' */
        !           365:
        !           366:        for (i = 0; i < (sc->sc_nsense * sc->sc_nstrobe); i++) {
        !           367:                stuck = 0;
        !           368:                /* extend  xt_keymap to do this faster. */
        !           369:                /* ignore 'stuck' keys' */
        !           370:                for (j = 0; j < sizeof(stuck_keys)/sizeof(stuck_keys[0]); j++) {
        !           371:                        if (stuck_keys[j] == i) {
        !           372:                                stuck = 1 ;
        !           373:                                break;
        !           374:                        }
        !           375:                }
        !           376:                if (stuck)
        !           377:                        continue;
        !           378:                keystate = sc->sc_keystate[i];
        !           379:
        !           380:                keysdown |= keystate; /* if any keys held */
        !           381:
        !           382: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           383:                if (sc->sc_polling == 0 && sc->sc_rawkbd) {
        !           384:                        if ((keystate) || (sc->sc_okeystate[i] != keystate)) {
        !           385:                                c = sc->sc_xt_keymap[i];
        !           386:                                if (c & 0x80) {
        !           387:                                        cbuf[ncbuf++] = 0xe0;
        !           388:                                }
        !           389:                                cbuf[ncbuf] = c & 0x7f;
        !           390:
        !           391:                                if (keystate) {
        !           392:                                        if (c & 0x80) {
        !           393:                                                sc->sc_rep[npress++] = 0xe0;
        !           394:                                        }
        !           395:                                        sc->sc_rep[npress++] = c & 0x7f;
        !           396:                                } else {
        !           397:                                        cbuf[ncbuf] |= 0x80;
        !           398:                                }
        !           399:                                ncbuf++;
        !           400:                                sc->sc_okeystate[i] = keystate;
        !           401:                        }
        !           402:                }
        !           403: #endif
        !           404:
        !           405:                if ((!sc->sc_rawkbd) && (sc->sc_okeystate[i] != keystate)) {
        !           406:
        !           407:                        type = keystate ? WSCONS_EVENT_KEY_DOWN :
        !           408:                            WSCONS_EVENT_KEY_UP;
        !           409:
        !           410:                        if (sc->sc_polling) {
        !           411:                                sc->sc_pollkey = i;
        !           412:                                sc->sc_pollUD = type;
        !           413:                        } else {
        !           414:                                wskbd_input(sc->sc_wskbddev, type, i);
        !           415:                        }
        !           416:
        !           417:                        sc->sc_okeystate[i] = keystate;
        !           418:                }
        !           419:        }
        !           420:
        !           421: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           422:        if (sc->sc_polling == 0 && sc->sc_rawkbd) {
        !           423:                wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf);
        !           424:                sc->sc_nrep = npress;
        !           425:                if (npress != 0)
        !           426:                        timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
        !           427:                else
        !           428:                        timeout_del(&sc->sc_rawrepeat_ch);
        !           429:        }
        !           430: #endif
        !           431:        if (keysdown)
        !           432:                timeout_add(&(sc->sc_roll_to), hz * REP_DELAYN / 1000 / 2);
        !           433:        else
        !           434:                timeout_del(&(sc->sc_roll_to)); /* always cancel? */
        !           435:
        !           436:        splx(s);
        !           437: }
        !           438:
        !           439: #if NAPM > 0
        !           440: extern int kbd_reset;
        !           441: extern int apm_suspends;
        !           442: static int zkbdondown;                         /* on key is pressed */
        !           443: static struct timeval zkbdontv = { 0, 0 };     /* last on key event */
        !           444: const  struct timeval zkbdhalttv = { 3, 0 };   /*  3s for safe shutdown */
        !           445: const  struct timeval zkbdsleeptv = { 0, 250000 };     /* .25s for suspend */
        !           446: extern int lid_suspend;
        !           447: #endif
        !           448:
        !           449: int
        !           450: zkbd_on(void *v)
        !           451: {
        !           452: #if NAPM > 0
        !           453:        struct zkbd_softc *sc = v;
        !           454:        int down = pxa2x0_gpio_get_bit(sc->sc_onkey_pin) ? 1 : 0;
        !           455:
        !           456:        /*
        !           457:         * Change run mode depending on how long the key is held down.
        !           458:         * Ignore the key if it gets pressed while the lid is closed.
        !           459:         *
        !           460:         * Keys can bounce and we have to work around missed interrupts.
        !           461:         * Only the second edge is detected upon exit from sleep mode.
        !           462:         */
        !           463:        if (down) {
        !           464:                if (sc->sc_hinge == 3) {
        !           465:                        zkbdondown = 0;
        !           466:                } else {
        !           467:                        microuptime(&zkbdontv);
        !           468:                        zkbdondown = 1;
        !           469:                }
        !           470:        } else if (zkbdondown) {
        !           471:                if (ratecheck(&zkbdontv, &zkbdhalttv)) {
        !           472:                        if (kbd_reset == 1) {
        !           473:                                kbd_reset = 0;
        !           474:                                psignal(initproc, SIGUSR1);
        !           475:                        }
        !           476:                } else if (ratecheck(&zkbdontv, &zkbdsleeptv)) {
        !           477:                        apm_suspends++;
        !           478:                }
        !           479:                zkbdondown = 0;
        !           480:        }
        !           481: #endif
        !           482:        return 1;
        !           483: }
        !           484:
        !           485: int
        !           486: zkbd_sync(void *v)
        !           487: {
        !           488:        return 1;
        !           489: }
        !           490:
        !           491: int
        !           492: zkbd_hinge(void *v)
        !           493: {
        !           494:        struct zkbd_softc *sc = v;
        !           495:        int a = pxa2x0_gpio_get_bit(sc->sc_swa_pin) ? 1 : 0;
        !           496:        int b = pxa2x0_gpio_get_bit(sc->sc_swb_pin) ? 2 : 0;
        !           497:        extern void lcd_blank(int);
        !           498:
        !           499:        sc->sc_hinge = a | b;
        !           500:
        !           501:        if (sc->sc_hinge == 3) {
        !           502: #if NAPM > 0
        !           503:                if (lid_suspend)
        !           504:                        apm_suspends++;
        !           505: #endif
        !           506:                lcd_blank(1);
        !           507:        } else
        !           508:                lcd_blank(0);
        !           509:
        !           510:
        !           511:        return 1;
        !           512: }
        !           513:
        !           514: int
        !           515: zkbd_enable(void *v, int on)
        !           516: {
        !           517:         return 0;
        !           518: }
        !           519:
        !           520: void
        !           521: zkbd_set_leds(void *v, int on)
        !           522: {
        !           523: }
        !           524:
        !           525: int
        !           526: zkbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           527: {
        !           528: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           529:        struct zkbd_softc *sc = v;
        !           530: #endif
        !           531:
        !           532:        switch (cmd) {
        !           533:
        !           534:        case WSKBDIO_GTYPE:
        !           535:                *(int *)data = WSKBD_TYPE_ZAURUS;
        !           536:                return 0;
        !           537:        case WSKBDIO_SETLEDS:
        !           538:                return 0;
        !           539:        case WSKBDIO_GETLEDS:
        !           540:                *(int *)data = 0;
        !           541:                return 0;
        !           542: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           543:        case WSKBDIO_SETMODE:
        !           544:                sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
        !           545:                timeout_del(&sc->sc_rawrepeat_ch);
        !           546:                return (0);
        !           547: #endif
        !           548:
        !           549:        }
        !           550:        /* kbdioctl(...); */
        !           551:
        !           552:        return -1;
        !           553: }
        !           554:
        !           555: /* implement polling for zaurus_kbd */
        !           556: void
        !           557: zkbd_cngetc(void *v, u_int *type, int *data)
        !           558: {
        !           559:        struct zkbd_softc *sc = zkbd_dev;
        !           560:        sc->sc_pollkey = -1;
        !           561:        sc->sc_pollUD = -1;
        !           562:        sc->sc_polling = 1;
        !           563:        while (sc->sc_pollkey == -1) {
        !           564:                zkbd_poll(zkbd_dev);
        !           565:                DELAY(10000);   /* XXX */
        !           566:        }
        !           567:        sc->sc_polling = 0;
        !           568:        *data = sc->sc_pollkey;
        !           569:        *type = sc->sc_pollUD;
        !           570: }
        !           571:
        !           572: void
        !           573: zkbd_cnpollc(void *v, int on)
        !           574: {
        !           575: }
        !           576:
        !           577: void
        !           578: zkbd_power(int why, void *arg)
        !           579: {
        !           580:        zkbd_hinge(arg);
        !           581: }

CVSweb