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