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

Annotation of sys/arch/jornada/dev/jmcu.c, Revision 1.1

1.1     ! nbrk        1: /*     $Id$    */
        !             2: #include <sys/param.h>
        !             3: #include <sys/systm.h>
        !             4: #include <sys/device.h>
        !             5: #include <sys/proc.h>
        !             6: #include <sys/conf.h>
        !             7: #include <sys/endian.h>
        !             8:
        !             9: #include <machine/intr.h>
        !            10: #include <machine/bus.h>
        !            11:
        !            12: #include <dev/wscons/wsconsio.h>
        !            13: #include <dev/wscons/wskbdvar.h>
        !            14: #include <dev/wscons/wsksymdef.h>
        !            15: #include <dev/wscons/wsksymvar.h>
        !            16:
        !            17: #include <dev/spivar.h>
        !            18:
        !            19: #include <jornada/dev/jmcu_cmd.h>
        !            20:
        !            21: #include <arm/sa11x0/sa11x0_var.h>
        !            22: #include <arm/sa11x0/sa11x0_reg.h>
        !            23: #include <arm/sa11x0/sa11x0_gpiovar.h>
        !            24:
        !            25: #include <jornada/dev/jmcu_kbdmap.h>
        !            26:
        !            27: #define JMCU_KBD_GPIOINTR      0
        !            28: #define JMCU_TS_GPIOINTR       15
        !            29:
        !            30: #define JMCU_KBD_NEVENTS       8
        !            31:
        !            32: struct jmcu_softc {
        !            33:        struct device   sc_dev;
        !            34:
        !            35:        struct spi_bus  *sc_bus;
        !            36:        void    *sc_spisc;
        !            37:
        !            38:        uint8_t sc_kbdeventsbuf[JMCU_KBD_NEVENTS];
        !            39:        uint8_t sc_kbdeventsnum;
        !            40: };
        !            41:
        !            42: struct jmcu_softc *jmcu_sc;
        !            43: struct wskbd_mapdata jmcukbd_keymapdata = {
        !            44:         jmcukbd_keydesctab,
        !            45:         KB_US,
        !            46: };
        !            47:
        !            48: /*
        !            49:  * Prototypes.
        !            50:  */
        !            51: int    jmcu_match(struct device *parent, void *cf, void *aux);
        !            52: void   jmcu_attach(struct device *parent, struct device *self, void *aux);
        !            53: int    jmcu_kbdintr(void *arg);
        !            54: int    jmcu_touchintr(void *arg);
        !            55: void   jmcukbd_cngetc(void *v, u_int *type, int *data);
        !            56: void   jmcukbd_enqueue(struct jmcu_softc *sc, uint8_t keycode);
        !            57: void   jmcukbd_dequeue(struct jmcu_softc *sc, uint8_t *keycodep);
        !            58: void   jmcukbd_getcodes(struct jmcu_softc *sc, int block);
        !            59: void   jmcubatt_status(struct jmcu_softc *sc);
        !            60:
        !            61: /*
        !            62:  * Autoconf glue.
        !            63:  */
        !            64: struct cfattach        jmcu_ca = {
        !            65:        sizeof(struct jmcu_softc), jmcu_match, jmcu_attach, NULL, NULL
        !            66: };
        !            67:
        !            68: struct cfdriver        jmcu_cd = {
        !            69:        NULL,
        !            70:        "jmcu",
        !            71:        DV_DULL
        !            72: };
        !            73:
        !            74: /*
        !            75:  * Console ops.
        !            76:  */
        !            77: struct wskbd_consops jmcukbd_consops = {
        !            78:        jmcukbd_cngetc,
        !            79:        NULL, /* pollc */
        !            80:        NULL /* bell */
        !            81: };
        !            82:
        !            83:
        !            84: int
        !            85: jmcu_match(struct device *parent, void *cf, void *aux)
        !            86: {
        !            87:        return (1);
        !            88: }
        !            89:
        !            90: void
        !            91: jmcu_attach(struct device *parent, struct device *self, void *aux)
        !            92: {
        !            93:        struct jmcu_softc *sc = (struct jmcu_softc *)self;
        !            94:        struct spibus_attach_args *sba = aux;
        !            95:        struct wskbddev_attach_args     wda;
        !            96:
        !            97:        sc->sc_bus = sba->sba_bus;
        !            98:        sc->sc_spisc = sba->sba_spisc;
        !            99:
        !           100:        printf(": Jornada MCU\n");
        !           101:
        !           102:        jmcu_sc = sc;
        !           103:
        !           104:        /* XXX */
        !           105:        jmcubatt_status(sc);
        !           106:
        !           107:        sa11x0_gpio_intr_establish(JMCU_KBD_GPIOINTR, IST_EDGE_FALLING, IPL_TTY, jmcu_kbdintr, sc, "jmcukbd");
        !           108:        sa11x0_gpio_intr_establish(JMCU_TS_GPIOINTR, IST_EDGE_FALLING, IPL_TTY, jmcu_touchintr, sc, "jmcutouch");
        !           109:
        !           110:        wskbd_cnattach(&jmcukbd_consops, sc, &jmcukbd_keymapdata);
        !           111:
        !           112:        wda.console = 1;
        !           113:        wda.keymap = &jmcukbd_keymapdata;
        !           114:        wda.accessops = NULL; //jmcukbd_accessops;
        !           115:        wda.accesscookie = sc;
        !           116:
        !           117:        config_found(self, &wda, wskbddevprint);
        !           118:
        !           119:        return;
        !           120: }
        !           121:
        !           122: int
        !           123: jmcu_kbdintr(void *arg)
        !           124: {
        !           125:        struct jmcu_softc *sc = arg;
        !           126:        printf("%s: jmcu_kbdintr\n", sc->sc_dev.dv_xname);
        !           127:
        !           128:        return(0);
        !           129: }
        !           130:
        !           131: int
        !           132: jmcu_touchintr(void *arg)
        !           133: {
        !           134:        struct jmcu_softc *sc = arg;
        !           135:        printf("%s: jmcu_touchintr\n", sc->sc_dev.dv_xname);
        !           136:
        !           137:        return(0);
        !           138: }
        !           139:
        !           140: void
        !           141: jmcukbd_cngetc(void *v, u_int *type, int *data)
        !           142: {
        !           143:        struct jmcu_softc *sc = v;
        !           144:        uint8_t ourdata;
        !           145:
        !           146:        printf("jmcukbd_cngetc:\n");
        !           147:
        !           148:        if (sc->sc_kbdeventsnum == 0)
        !           149:                jmcukbd_getcodes(sc, 1);        /* note that we've passed blocking flag */
        !           150:
        !           151:        jmcukbd_dequeue(sc, &ourdata);
        !           152:
        !           153:        *data = ourdata & 0x7f;
        !           154:        *type = ourdata & 0x80 ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
        !           155: }
        !           156:
        !           157: void
        !           158: jmcukbd_getcodes(struct jmcu_softc *sc, int block)
        !           159: {
        !           160:        int     nkeys;
        !           161:        uint8_t keycode;
        !           162:
        !           163:        /* wake up the MCU */
        !           164:        sa11x0_gpio_clear_bit(25);
        !           165:
        !           166:        spi_acquire(sc->sc_spisc);
        !           167:
        !           168:        do {
        !           169:                /* ask mcu about how many keypress events are there; should get TXDUMMY here */
        !           170:                if (spi_shift_1(sc->sc_spisc, JMCU_CMD_GETKEYCODES) != JMCU_CMD_TXDUMMY)
        !           171:                printf("%s: WARNING, no txdummy received\n", sc->sc_dev.dv_xname);
        !           172:
        !           173:                nkeys = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
        !           174:        } while(nkeys == 0 && block);
        !           175:
        !           176:        while (nkeys) {
        !           177:                keycode = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
        !           178:                jmcukbd_enqueue(sc, keycode);
        !           179:
        !           180:                nkeys--;
        !           181:        }
        !           182:        spi_release(sc->sc_spisc);
        !           183:
        !           184:        /* park off the MCU */
        !           185:        sa11x0_gpio_set_bit(25);
        !           186: }
        !           187:
        !           188: void
        !           189: jmcukbd_enqueue(struct jmcu_softc *sc, uint8_t keycode)
        !           190: {
        !           191:        if (sc->sc_kbdeventsnum >= JMCU_KBD_NEVENTS) {
        !           192:                printf("%s: WARNING, event queue is full; keycode 0x%x will be discarded\n", sc->sc_dev.dv_xname, keycode);
        !           193:                return;
        !           194:        }
        !           195:
        !           196:        sc->sc_kbdeventsbuf[sc->sc_kbdeventsnum] = keycode;
        !           197:        sc->sc_kbdeventsnum++;
        !           198: }
        !           199:
        !           200: void
        !           201: jmcukbd_dequeue(struct jmcu_softc *sc, uint8_t *keycodep)
        !           202: {
        !           203:        if (sc->sc_kbdeventsnum < 1) {
        !           204:                printf("%s: WARNING, event queue is empty\n", sc->sc_dev.dv_xname);
        !           205:                return;
        !           206:        }
        !           207:
        !           208:        sc->sc_kbdeventsnum--;
        !           209:        *keycodep = sc->sc_kbdeventsbuf[sc->sc_kbdeventsnum];
        !           210: }
        !           211:
        !           212: void
        !           213: jmcubatt_status(struct jmcu_softc *sc)
        !           214: {
        !           215:        uint16_t        mainbatt;
        !           216:        uint16_t        backbatt;
        !           217:        uint8_t fraction;
        !           218:
        !           219:        /* wake up the MCU */
        !           220:        sa11x0_gpio_clear_bit(25);
        !           221:
        !           222:        spi_acquire(sc->sc_spisc);
        !           223:        spi_shift_1(sc->sc_spisc, JMCU_CMD_GETBATTERYDATA);
        !           224:        mainbatt = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
        !           225:        backbatt = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
        !           226:        fraction = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
        !           227:        spi_release(sc->sc_spisc);
        !           228:
        !           229:        /* park off the MCU */
        !           230:        sa11x0_gpio_set_bit(25);
        !           231:
        !           232:        /* fraction[0:1] is mainbatt[8:9]; fraction[2:3] is backbatt[8:9] */
        !           233:        mainbatt |= (uint16_t)((fraction & 0x03) << 8);
        !           234:        backbatt |= (uint16_t)((fraction & 0xc0) << 6);
        !           235:
        !           236:        printf("%s: battery status: main %d, backup %d\n", sc->sc_dev.dv_xname, mainbatt, backbatt);
        !           237: }
        !           238:

CVSweb