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