Annotation of sys/arch/zaurus/dev/zaurus_remote.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: zaurus_remote.c,v 1.1 2005/11/17 05:26:31 uwe Exp $ */
2:
3: /*
4: * Copyright (c) 2005 Uwe Stuehler <uwe@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/param.h>
20: #include <sys/device.h>
21: #include <sys/kernel.h>
22: #include <sys/limits.h>
23: #include <sys/timeout.h>
24: #include <sys/systm.h>
25:
26: #include <dev/wscons/wsconsio.h>
27: #include <dev/wscons/wskbdraw.h>
28: #include <dev/wscons/wskbdvar.h>
29: #include <dev/wscons/wsksymdef.h>
30: #include <dev/wscons/wsksymvar.h>
31:
32: #include <machine/intr.h>
33: #include <machine/zaurus_var.h>
34:
35: #include <arm/xscale/pxa2x0reg.h>
36: #include <arm/xscale/pxa2x0_gpio.h>
37:
38: #include <zaurus/dev/zaurus_scoopvar.h>
39: #include <zaurus/dev/zaurus_sspvar.h>
40:
41: #define RESCAN_INTERVAL (hz/100)
42:
43: #define KEY_RELEASE 0 /* button release */
44: #define KEY_VOL_DOWN 1
45: #define KEY_MUTE 2
46: #define KEY_REWIND 3
47: #define KEY_VOL_UP 4
48: #define KEY_FORWARD 5
49: #define KEY_PLAY 6
50: #define KEY_STOP 7
51: #define KEY_EARPHONE 8
52:
53: #ifdef DEBUG
54: static const char *zrc_keyname[] = {
55: "(release)", "volume down", "mute", "rewind", "volume up",
56: "forward", "play", "stop", "(earphone)"
57: };
58: #endif
59:
60: struct zrc_akey {
61: int min; /* minimum ADC value or INT_MIN */
62: int key; /* remote control key number */
63: };
64:
65: /* Values match the resistors in the CE-RH2 remote control. */
66: static const struct zrc_akey zrc_akeytab_c3000[] = {
67: { 238, KEY_RELEASE },
68: { 202, KEY_VOL_DOWN },
69: { 168, KEY_MUTE },
70: { 135, KEY_REWIND },
71: { 105, KEY_VOL_UP },
72: { 74, KEY_FORWARD },
73: { 42, KEY_PLAY },
74: { 12, KEY_STOP },
75: { INT_MIN, KEY_EARPHONE }
76: };
77:
78: static const struct zrc_akey *zrc_akeytab = zrc_akeytab_c3000;
79:
80: struct zrc_softc {
81: struct device sc_dev;
82: struct timeout sc_to;
83: void *sc_ih;
84: int sc_key; /* being scanned */
85: int sc_scans; /* rescan counter */
86: int sc_noise; /* discard if too noisy? */
87: int sc_keydown; /* currently pressed key */
88: struct device *sc_wskbddev;
89: #ifdef WSDISPLAY_COMPAT_RAWKBD
90: int sc_rawkbd;
91: #endif
92: };
93:
94: int zrc_match(struct device *, void *, void *);
95: void zrc_attach(struct device *, struct device *, void *);
96:
97: int zrc_intr(void *);
98: void zrc_timeout(void *);
99: int zrc_scan(void);
100: void zrc_input(struct zrc_softc *, int, int);
101:
102: struct cfattach zrc_ca = {
103: sizeof(struct zrc_softc), zrc_match, zrc_attach
104: };
105:
106: struct cfdriver zrc_cd = {
107: NULL, "zrc", DV_DULL
108: };
109:
110: int zrc_enable(void *, int);
111: void zrc_set_leds(void *, int);
112: int zrc_ioctl(void *, u_long, caddr_t, int, struct proc *);
113:
114: struct wskbd_accessops zrc_accessops = {
115: zrc_enable,
116: zrc_set_leds,
117: zrc_ioctl,
118: };
119:
120: #define KC(n) KS_KEYCODE(n)
121:
122: /* XXX what keys should be generated in translated mode? */
123: static const keysym_t zrc_keydesc[] = {
124: KC(KEY_VOL_DOWN), KS_minus,
125: KC(KEY_MUTE), KS_m,
126: KC(KEY_REWIND), KS_b,
127: KC(KEY_VOL_UP), KS_plus,
128: KC(KEY_FORWARD), KS_f,
129: KC(KEY_PLAY), KS_p,
130: KC(KEY_STOP), KS_s,
131: };
132:
133: #ifdef WSDISPLAY_COMPAT_RAWKBD
134: #define RAWKEY_AudioRewind 0xa0
135: #define RAWKEY_AudioForward 0xa1
136: #define RAWKEY_AudioPlay 0xa2
137: #define RAWKEY_AudioStop 0xa3
138: static const keysym_t zrc_xt_keymap[] = {
139: /* KC(KEY_RELEASE), */ RAWKEY_Null,
140: /* KC(KEY_VOL_DOWN), */ RAWKEY_AudioLower,
141: /* KC(KEY_MUTE), */ RAWKEY_AudioMute,
142: /* KC(KEY_REWIND), */ RAWKEY_AudioRewind,
143: /* KC(KEY_VOL_UP), */ RAWKEY_AudioRaise,
144: /* KC(KEY_FORWARD), */ RAWKEY_AudioForward,
145: /* KC(KEY_PLAY), */ RAWKEY_AudioPlay,
146: /* KC(KEY_STOP), */ RAWKEY_AudioStop,
147: };
148: #endif
149:
150: static const struct wscons_keydesc zrc_keydesctab[] = {
151: {KB_US, 0, sizeof(zrc_keydesc)/sizeof(keysym_t), zrc_keydesc},
152: {0, 0, 0, 0}
153: };
154:
155: struct wskbd_mapdata zrc_keymapdata = {
156: zrc_keydesctab, KB_US
157: };
158:
159:
160: int
161: zrc_match(struct device *parent, void *match, void *aux)
162: {
163: return (ZAURUS_ISC3000);
164: }
165:
166: void
167: zrc_attach(struct device *parent, struct device *self, void *aux)
168: {
169: struct zrc_softc *sc = (struct zrc_softc *)self;
170: struct wskbddev_attach_args a;
171:
172: /* Configure remote control interrupt handling. */
173: timeout_set(&sc->sc_to, zrc_timeout, sc);
174: pxa2x0_gpio_set_function(C3000_RC_IRQ_PIN, GPIO_IN);
175: sc->sc_ih = pxa2x0_gpio_intr_establish(C3000_RC_IRQ_PIN,
176: IST_EDGE_BOTH, IPL_BIO, zrc_intr, sc, "zrc");
177:
178: /* Enable the pullup while waiting for an interrupt. */
179: scoop_akin_pullup(1);
180:
181: sc->sc_keydown = KEY_RELEASE;
182:
183: printf(": CE-RH2 remote control\n");
184:
185: a.console = 0;
186: a.keymap = &zrc_keymapdata;
187: a.accessops = &zrc_accessops;
188: a.accesscookie = sc;
189:
190: sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
191: }
192:
193: int
194: zrc_intr(void *v)
195: {
196: struct zrc_softc *sc = v;
197:
198: /* just return if remote control isn't present */
199:
200: pxa2x0_gpio_intr_mask(sc->sc_ih);
201: scoop_akin_pullup(0);
202: sc->sc_key = zrc_scan();
203: sc->sc_scans = 0;
204: sc->sc_noise = 0;
205: timeout_add(&sc->sc_to, RESCAN_INTERVAL);
206: return (1);
207: }
208:
209: void
210: zrc_timeout(void *v)
211: {
212: struct zrc_softc *sc = v;
213: int key;
214:
215: key = zrc_scan();
216: switch (sc->sc_scans) {
217: case 0:
218: case 1:
219: case 2:
220: /* wait for a stable read */
221: if (sc->sc_key == key)
222: sc->sc_scans++;
223: else {
224: sc->sc_key = key;
225: sc->sc_scans = 0;
226: sc->sc_noise++;
227: }
228: timeout_add(&sc->sc_to, RESCAN_INTERVAL);
229: break;
230: case 3:
231: /* generate key press event */
232: if (sc->sc_key != key) {
233: key = sc->sc_key;
234: sc->sc_noise++;
235: }
236: sc->sc_scans++;
237: switch (key) {
238: case KEY_EARPHONE:
239: case KEY_RELEASE:
240: sc->sc_scans = 6;
241: break;
242: default:
243: #ifdef DEBUG
244: printf("%s pressed (%d noise)\n", zrc_keyname[key],
245: sc->sc_noise);
246: #endif
247: sc->sc_keydown = key;
248: sc->sc_noise = 0;
249: zrc_input(sc, key, 1);
250: break;
251: }
252: timeout_add(&sc->sc_to, RESCAN_INTERVAL);
253: break;
254: case 4:
255: case 5:
256: /* wait for key release, permit noise */
257: if (sc->sc_key == key) {
258: if (sc->sc_scans == 5)
259: sc->sc_noise++;
260: sc->sc_scans = 4;
261: } else
262: sc->sc_scans++;
263: timeout_add(&sc->sc_to, RESCAN_INTERVAL);
264: break;
265: case 6:
266: /* generate key release event */
267: if (sc->sc_keydown != KEY_RELEASE) {
268: zrc_input(sc, sc->sc_keydown, 0);
269: #ifdef DEBUG
270: printf("%s released (%d noise)\n",
271: zrc_keyname[sc->sc_keydown], sc->sc_noise);
272: #endif
273: sc->sc_keydown = KEY_RELEASE;
274: }
275: /* FALLTHROUGH */
276: default:
277: /* unmask interrupt again */
278: timeout_del(&sc->sc_to);
279: sc->sc_scans = 7;
280: scoop_akin_pullup(1);
281: pxa2x0_gpio_intr_unmask(sc->sc_ih);
282: }
283: }
284:
285: int
286: zrc_scan(void)
287: {
288: int val;
289: int i;
290:
291: /* XXX MAX1111 command word - also appears in zaurus_apm.c */
292: #define MAXCTRL_PD0 (1<<0)
293: #define MAXCTRL_PD1 (1<<1)
294: #define MAXCTRL_SGL (1<<2)
295: #define MAXCTRL_UNI (1<<3)
296: #define MAXCTRL_SEL_SHIFT 4
297: #define MAXCTRL_STR (1<<7)
298:
299: #define C3000_ADCCH_ZRC 0
300: val = zssp_read_max1111(MAXCTRL_PD0 | MAXCTRL_PD1 | MAXCTRL_SGL |
301: MAXCTRL_UNI | (C3000_ADCCH_ZRC << MAXCTRL_SEL_SHIFT) |
302: MAXCTRL_STR);
303: for (i = 0; zrc_akeytab[i].min != INT_MIN; i++)
304: if (val >= zrc_akeytab[i].min)
305: break;
306: return (zrc_akeytab[i].key);
307: }
308:
309: void
310: zrc_input(struct zrc_softc *sc, int key, int down)
311: {
312: u_int type = down ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
313: int s;
314:
315: s = spltty();
316:
317: #ifdef WSDISPLAY_COMPAT_RAWKBD
318: if (sc->sc_rawkbd) {
319: int c;
320: u_char cbuf[2];
321: int ncbuf = 0;
322:
323: c = zrc_xt_keymap[key];
324: if (c & 0x80)
325: cbuf[ncbuf++] = 0xe0;
326: cbuf[ncbuf] = c & 0x7f;
327:
328: if (!down)
329: cbuf[ncbuf] |= 0x80;
330: ncbuf++;
331:
332: wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf);
333: } else
334: #endif
335: wskbd_input(sc->sc_wskbddev, type, key);
336:
337: splx(s);
338: }
339:
340: int
341: zrc_enable(void *v, int on)
342: {
343: return (0);
344: }
345:
346: void
347: zrc_set_leds(void *v, int on)
348: {
349: }
350:
351: int
352: zrc_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
353: {
354: #ifdef WSDISPLAY_COMPAT_RAWKBD
355: struct zrc_softc *sc = v;
356: #endif
357:
358: switch (cmd) {
359: case WSKBDIO_GTYPE:
360: *(int *)data = WSKBD_TYPE_ZAURUS;
361: return (0);
362: case WSKBDIO_SETLEDS:
363: return (0);
364: case WSKBDIO_GETLEDS:
365: *(int *)data = 0;
366: return (0);
367: #ifdef WSDISPLAY_COMPAT_RAWKBD
368: case WSKBDIO_SETMODE:
369: sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
370: return (0);
371: #endif
372: }
373: return (-1);
374: }
CVSweb