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