[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

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