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