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

1.2     ! nbrk        1: /*     $Id: jmcu.c,v 1.1.1.1 2008/03/04 16:09:01 nbrk Exp $    */
1.1       nbrk        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:        wskbd_cnattach(&jmcukbd_consops, sc, &jmcukbd_keymapdata);
                    108:
                    109:        wda.console = 1;
                    110:        wda.keymap = &jmcukbd_keymapdata;
                    111:        wda.accessops = NULL; //jmcukbd_accessops;
                    112:        wda.accesscookie = sc;
                    113:
                    114:        config_found(self, &wda, wskbddevprint);
                    115:
                    116:        return;
                    117: }
                    118:
                    119: int
                    120: jmcu_kbdintr(void *arg)
                    121: {
                    122:        struct jmcu_softc *sc = arg;
                    123:        printf("%s: jmcu_kbdintr\n", sc->sc_dev.dv_xname);
                    124:
                    125:        return(0);
                    126: }
                    127:
                    128: int
                    129: jmcu_touchintr(void *arg)
                    130: {
                    131:        struct jmcu_softc *sc = arg;
                    132:        printf("%s: jmcu_touchintr\n", sc->sc_dev.dv_xname);
                    133:
                    134:        return(0);
                    135: }
                    136:
                    137: void
                    138: jmcukbd_cngetc(void *v, u_int *type, int *data)
                    139: {
                    140:        struct jmcu_softc *sc = v;
                    141:        uint8_t ourdata;
                    142:
                    143:        printf("jmcukbd_cngetc:\n");
                    144:
                    145:        if (sc->sc_kbdeventsnum == 0)
                    146:                jmcukbd_getcodes(sc, 1);        /* note that we've passed blocking flag */
                    147:
                    148:        jmcukbd_dequeue(sc, &ourdata);
                    149:
                    150:        *data = ourdata & 0x7f;
                    151:        *type = ourdata & 0x80 ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
                    152: }
                    153:
                    154: void
                    155: jmcukbd_getcodes(struct jmcu_softc *sc, int block)
                    156: {
                    157:        int     nkeys;
                    158:        uint8_t keycode;
                    159:
                    160:        /* wake up the MCU */
                    161:        sa11x0_gpio_clear_bit(25);
                    162:
                    163:        spi_acquire(sc->sc_spisc);
                    164:
                    165:        do {
                    166:                /* ask mcu about how many keypress events are there; should get TXDUMMY here */
                    167:                if (spi_shift_1(sc->sc_spisc, JMCU_CMD_GETKEYCODES) != JMCU_CMD_TXDUMMY)
                    168:                printf("%s: WARNING, no txdummy received\n", sc->sc_dev.dv_xname);
                    169:
                    170:                nkeys = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
                    171:        } while(nkeys == 0 && block);
                    172:
                    173:        while (nkeys) {
                    174:                keycode = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
                    175:                jmcukbd_enqueue(sc, keycode);
                    176:
                    177:                nkeys--;
                    178:        }
                    179:        spi_release(sc->sc_spisc);
                    180:
                    181:        /* park off the MCU */
                    182:        sa11x0_gpio_set_bit(25);
                    183: }
                    184:
                    185: void
                    186: jmcukbd_enqueue(struct jmcu_softc *sc, uint8_t keycode)
                    187: {
                    188:        if (sc->sc_kbdeventsnum >= JMCU_KBD_NEVENTS) {
                    189:                printf("%s: WARNING, event queue is full; keycode 0x%x will be discarded\n", sc->sc_dev.dv_xname, keycode);
                    190:                return;
                    191:        }
                    192:
                    193:        sc->sc_kbdeventsbuf[sc->sc_kbdeventsnum] = keycode;
                    194:        sc->sc_kbdeventsnum++;
                    195: }
                    196:
                    197: void
                    198: jmcukbd_dequeue(struct jmcu_softc *sc, uint8_t *keycodep)
                    199: {
                    200:        if (sc->sc_kbdeventsnum < 1) {
                    201:                printf("%s: WARNING, event queue is empty\n", sc->sc_dev.dv_xname);
                    202:                return;
                    203:        }
                    204:
                    205:        sc->sc_kbdeventsnum--;
                    206:        *keycodep = sc->sc_kbdeventsbuf[sc->sc_kbdeventsnum];
                    207: }
                    208:
                    209: void
                    210: jmcubatt_status(struct jmcu_softc *sc)
                    211: {
                    212:        uint16_t        mainbatt;
                    213:        uint16_t        backbatt;
                    214:        uint8_t fraction;
                    215:
                    216:        /* wake up the MCU */
                    217:        sa11x0_gpio_clear_bit(25);
                    218:
                    219:        spi_acquire(sc->sc_spisc);
                    220:        spi_shift_1(sc->sc_spisc, JMCU_CMD_GETBATTERYDATA);
                    221:        mainbatt = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
                    222:        backbatt = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
                    223:        fraction = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
                    224:        spi_release(sc->sc_spisc);
                    225:
                    226:        /* park off the MCU */
                    227:        sa11x0_gpio_set_bit(25);
                    228:
                    229:        /* fraction[0:1] is mainbatt[8:9]; fraction[2:3] is backbatt[8:9] */
                    230:        mainbatt |= (uint16_t)((fraction & 0x03) << 8);
                    231:        backbatt |= (uint16_t)((fraction & 0xc0) << 6);
                    232:
                    233:        printf("%s: battery status: main %d, backup %d\n", sc->sc_dev.dv_xname, mainbatt, backbatt);
                    234: }
                    235:

CVSweb