1 1.11 thorpej /* $NetBSD: wzero3_tp.c,v 1.11 2023/12/20 14:50:02 thorpej Exp $ */ 2 1.1 nonaka 3 1.7 nonaka /*- 4 1.7 nonaka * Copyright (C) 2010 NONAKA Kimihiro <nonaka (at) netbsd.org> 5 1.1 nonaka * All rights reserved. 6 1.1 nonaka * 7 1.1 nonaka * Redistribution and use in source and binary forms, with or without 8 1.1 nonaka * modification, are permitted provided that the following conditions 9 1.1 nonaka * are met: 10 1.1 nonaka * 1. Redistributions of source code must retain the above copyright 11 1.1 nonaka * notice, this list of conditions and the following disclaimer. 12 1.1 nonaka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 nonaka * notice, this list of conditions and the following disclaimer in the 14 1.1 nonaka * documentation and/or other materials provided with the distribution. 15 1.1 nonaka * 16 1.7 nonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.7 nonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.7 nonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.7 nonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.7 nonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.7 nonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.7 nonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.7 nonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.7 nonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.7 nonaka * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 nonaka */ 27 1.1 nonaka 28 1.1 nonaka #include <sys/cdefs.h> 29 1.11 thorpej __KERNEL_RCSID(0, "$NetBSD: wzero3_tp.c,v 1.11 2023/12/20 14:50:02 thorpej Exp $"); 30 1.1 nonaka 31 1.1 nonaka #include <sys/types.h> 32 1.1 nonaka #include <sys/param.h> 33 1.1 nonaka #include <sys/systm.h> 34 1.1 nonaka #include <sys/device.h> 35 1.1 nonaka #include <sys/kernel.h> 36 1.1 nonaka #include <sys/callout.h> 37 1.1 nonaka 38 1.1 nonaka #include <machine/bootinfo.h> 39 1.1 nonaka #include <machine/platid.h> 40 1.1 nonaka #include <machine/platid_mask.h> 41 1.1 nonaka 42 1.1 nonaka #include <dev/wscons/wsconsio.h> 43 1.1 nonaka #include <dev/wscons/wsmousevar.h> 44 1.1 nonaka #include <dev/wscons/wsdisplayvar.h> 45 1.1 nonaka 46 1.1 nonaka #include <dev/hpc/hpcfbio.h> 47 1.1 nonaka #include <dev/hpc/hpctpanelvar.h> 48 1.1 nonaka 49 1.1 nonaka #include <arm/xscale/pxa2x0cpu.h> 50 1.1 nonaka #include <arm/xscale/pxa2x0reg.h> 51 1.1 nonaka #include <arm/xscale/pxa2x0var.h> 52 1.1 nonaka #include <arm/xscale/xscalereg.h> 53 1.1 nonaka #include <arm/xscale/pxa2x0_lcd.h> 54 1.1 nonaka #include <arm/xscale/pxa2x0_gpio.h> 55 1.1 nonaka 56 1.1 nonaka #include <hpcarm/dev/wzero3_reg.h> 57 1.1 nonaka #include <hpcarm/dev/wzero3_sspvar.h> 58 1.1 nonaka 59 1.1 nonaka #ifdef WZERO3TP_DEBUG 60 1.1 nonaka #define DPRINTF(s) printf s 61 1.1 nonaka #else 62 1.1 nonaka #define DPRINTF(s) 63 1.1 nonaka #endif 64 1.1 nonaka 65 1.2 nonaka #define POLL_TIMEOUT_RATE0 ((hz * 150) / 1000) 66 1.2 nonaka #define POLL_TIMEOUT_RATE1 ((hz + 99) / 100) /* XXX every tick */ 67 1.1 nonaka 68 1.1 nonaka /* Settable via sysctl. */ 69 1.1 nonaka int wzero3tp_rawmode; 70 1.1 nonaka 71 1.2 nonaka static const struct wsmouse_calibcoords ws003sh_default_calib = { 72 1.2 nonaka 0, 0, 479, 639, /* minx, miny, maxx, maxy */ 73 1.2 nonaka 5, /* samplelen */ 74 1.2 nonaka { 75 1.2 nonaka { 2028, 2004, 240, 320 }, /* rawx, rawy, x, y */ 76 1.2 nonaka { 3312, 705, 48, 64 }, 77 1.2 nonaka { 3316, 3371, 48, 576 }, 78 1.2 nonaka { 739, 3392, 432, 576 }, 79 1.2 nonaka { 749, 673, 432, 64 }, 80 1.2 nonaka } 81 1.2 nonaka }; 82 1.2 nonaka 83 1.1 nonaka static const struct wsmouse_calibcoords ws007sh_default_calib = { 84 1.1 nonaka 0, 0, 479, 639, /* minx, miny, maxx, maxy */ 85 1.1 nonaka 5, /* samplelen */ 86 1.1 nonaka { 87 1.1 nonaka { 2050, 2024, 240, 320 }, /* rawx, rawy, x, y */ 88 1.1 nonaka { 578, 3471, 48, 64 }, 89 1.1 nonaka { 578, 582, 48, 576 }, 90 1.1 nonaka { 3432, 582, 432, 576 }, 91 1.1 nonaka { 3432, 3471, 432, 64 }, 92 1.1 nonaka } 93 1.1 nonaka }; 94 1.1 nonaka 95 1.4 nonaka static const struct wsmouse_calibcoords ws011sh_default_calib = { 96 1.4 nonaka 0, 0, 479, 799, /* minx, miny, maxx, maxy */ 97 1.4 nonaka 5, /* samplelen */ 98 1.4 nonaka { 99 1.4 nonaka { 2126, 2048, 240, 400 }, /* rawx, rawy, x, y */ 100 1.4 nonaka { 527, 3464, 48, 80 }, 101 1.4 nonaka { 3628, 3376, 48, 720 }, 102 1.4 nonaka { 3351, 595, 432, 720 }, 103 1.4 nonaka { 554, 562, 432, 80 }, 104 1.4 nonaka } 105 1.4 nonaka }; 106 1.4 nonaka 107 1.1 nonaka struct wzero3tp_pos { 108 1.1 nonaka int x; 109 1.1 nonaka int y; 110 1.1 nonaka int z; /* touch pressure */ 111 1.1 nonaka }; 112 1.1 nonaka 113 1.1 nonaka struct wzero3tp_model; 114 1.1 nonaka struct wzero3tp_softc { 115 1.1 nonaka device_t sc_dev; 116 1.1 nonaka const struct wzero3tp_model *sc_model; 117 1.1 nonaka void *sc_gh; 118 1.1 nonaka struct callout sc_tp_poll; 119 1.1 nonaka int sc_enabled; 120 1.1 nonaka int sc_buttons; /* button emulation ? */ 121 1.8 chs device_t sc_wsmousedev; 122 1.1 nonaka struct wzero3tp_pos sc_oldpos; 123 1.1 nonaka struct tpcalib_softc sc_tpcalib; 124 1.1 nonaka }; 125 1.1 nonaka 126 1.2 nonaka static void nulldrv_init(void); 127 1.2 nonaka static int nulldrv_readpos(struct wzero3tp_pos *); 128 1.2 nonaka static void nulldrv_suspend(void); 129 1.2 nonaka static void nulldrv_resume(void); 130 1.2 nonaka 131 1.2 nonaka static void ws007sh_wait_for_hsync(void); 132 1.2 nonaka 133 1.2 nonaka void max1233_init(void); 134 1.2 nonaka int max1233_readpos(struct wzero3tp_pos *); 135 1.2 nonaka void max1233_suspend(void); 136 1.2 nonaka void max1233_resume(void); 137 1.2 nonaka 138 1.2 nonaka void ads7846_init(void); 139 1.2 nonaka int ads7846_readpos(struct wzero3tp_pos *); 140 1.2 nonaka void ads7846_suspend(void); 141 1.2 nonaka void ads7846_resume(void); 142 1.2 nonaka extern void (*ads7846_wait_for_hsync)(void); 143 1.2 nonaka 144 1.4 nonaka void ak4184_init(void); 145 1.4 nonaka int ak4184_readpos(struct wzero3tp_pos *); 146 1.4 nonaka void ak4184_suspend(void); 147 1.4 nonaka void ak4184_resume(void); 148 1.4 nonaka 149 1.1 nonaka static int wzero3tp_match(device_t, cfdata_t, void *); 150 1.1 nonaka static void wzero3tp_attach(device_t, device_t, void *); 151 1.1 nonaka 152 1.1 nonaka CFATTACH_DECL_NEW(wzero3tp, sizeof(struct wzero3tp_softc), 153 1.1 nonaka wzero3tp_match, wzero3tp_attach, NULL, NULL); 154 1.1 nonaka 155 1.1 nonaka static int wzero3tp_enable(void *); 156 1.1 nonaka static void wzero3tp_disable(void *); 157 1.1 nonaka static bool wzero3tp_suspend(device_t dv, const pmf_qual_t *); 158 1.1 nonaka static bool wzero3tp_resume(device_t dv, const pmf_qual_t *); 159 1.1 nonaka static void wzero3tp_poll(void *); 160 1.1 nonaka static int wzero3tp_irq(void *); 161 1.1 nonaka static int wzero3tp_ioctl(void *, u_long, void *, int, struct lwp *); 162 1.1 nonaka 163 1.1 nonaka static const struct wsmouse_accessops wzero3tp_accessops = { 164 1.1 nonaka wzero3tp_enable, 165 1.1 nonaka wzero3tp_ioctl, 166 1.1 nonaka wzero3tp_disable 167 1.1 nonaka }; 168 1.1 nonaka 169 1.1 nonaka struct wzero3tp_model { 170 1.1 nonaka platid_mask_t *platid; 171 1.1 nonaka const char *name; 172 1.1 nonaka int intr_pin; 173 1.1 nonaka const struct wsmouse_calibcoords *calib; 174 1.2 nonaka void (*wait_for_hsync)(void); 175 1.2 nonaka struct chip { 176 1.2 nonaka void (*init)(void); 177 1.2 nonaka int (*readpos)(struct wzero3tp_pos *); 178 1.2 nonaka void (*suspend)(void); 179 1.2 nonaka void (*resume)(void); 180 1.2 nonaka } chip; 181 1.1 nonaka } wzero3tp_table[] = { 182 1.1 nonaka /* WS003SH */ 183 1.1 nonaka { 184 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS003SH, 185 1.1 nonaka "WS003SH", 186 1.2 nonaka GPIO_WS003SH_TOUCH_PANEL, 187 1.2 nonaka &ws003sh_default_calib, 188 1.1 nonaka NULL, 189 1.2 nonaka { max1233_init, max1233_readpos, 190 1.2 nonaka max1233_suspend, max1233_resume, }, 191 1.1 nonaka }, 192 1.1 nonaka /* WS004SH */ 193 1.1 nonaka { 194 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS004SH, 195 1.1 nonaka "WS004SH", 196 1.2 nonaka GPIO_WS003SH_TOUCH_PANEL, 197 1.2 nonaka &ws003sh_default_calib, 198 1.1 nonaka NULL, 199 1.2 nonaka { max1233_init, max1233_readpos, 200 1.2 nonaka max1233_suspend, max1233_resume, }, 201 1.1 nonaka }, 202 1.1 nonaka /* WS007SH */ 203 1.1 nonaka { 204 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS007SH, 205 1.1 nonaka "WS007SH", 206 1.1 nonaka GPIO_WS007SH_TOUCH_PANEL, 207 1.1 nonaka &ws007sh_default_calib, 208 1.2 nonaka ws007sh_wait_for_hsync, 209 1.2 nonaka { ads7846_init, ads7846_readpos, 210 1.2 nonaka ads7846_suspend, ads7846_resume, }, 211 1.1 nonaka }, 212 1.1 nonaka /* WS011SH */ 213 1.1 nonaka { 214 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS011SH, 215 1.1 nonaka "WS011SH", 216 1.1 nonaka GPIO_WS011SH_TOUCH_PANEL, 217 1.4 nonaka &ws011sh_default_calib, 218 1.1 nonaka NULL, 219 1.4 nonaka { ak4184_init, ak4184_readpos, 220 1.4 nonaka ak4184_suspend, ak4184_resume, }, 221 1.1 nonaka }, 222 1.2 nonaka #if 0 223 1.1 nonaka /* WS0020H */ 224 1.1 nonaka { 225 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS020SH, 226 1.1 nonaka "WS020SH", 227 1.1 nonaka -1, 228 1.1 nonaka NULL, 229 1.2 nonaka NULL, 230 1.2 nonaka { nulldrv_init, nulldrv_readpos, 231 1.2 nonaka nulldrv_suspend, nulldrv_resume, }, 232 1.1 nonaka }, 233 1.1 nonaka #endif 234 1.1 nonaka { 235 1.2 nonaka NULL, NULL, -1, NULL, NULL, 236 1.2 nonaka { nulldrv_init, nulldrv_readpos, 237 1.2 nonaka nulldrv_suspend, nulldrv_resume, }, 238 1.1 nonaka }, 239 1.1 nonaka }; 240 1.1 nonaka 241 1.1 nonaka static const struct wzero3tp_model * 242 1.1 nonaka wzero3tp_lookup(void) 243 1.1 nonaka { 244 1.1 nonaka const struct wzero3tp_model *model; 245 1.1 nonaka 246 1.1 nonaka for (model = wzero3tp_table; model->platid != NULL; model++) { 247 1.1 nonaka if (platid_match(&platid, model->platid)) { 248 1.1 nonaka return model; 249 1.1 nonaka } 250 1.1 nonaka } 251 1.1 nonaka return NULL; 252 1.1 nonaka } 253 1.1 nonaka 254 1.1 nonaka static int 255 1.1 nonaka wzero3tp_match(device_t parent, cfdata_t cf, void *aux) 256 1.1 nonaka { 257 1.1 nonaka 258 1.1 nonaka if (strcmp(cf->cf_name, "wzero3tp") != 0) 259 1.1 nonaka return 0; 260 1.1 nonaka if (wzero3tp_lookup() == NULL) 261 1.1 nonaka return 0; 262 1.1 nonaka return 1; 263 1.1 nonaka } 264 1.1 nonaka 265 1.1 nonaka static void 266 1.1 nonaka wzero3tp_attach(device_t parent, device_t self, void *aux) 267 1.1 nonaka { 268 1.1 nonaka struct wzero3tp_softc *sc = device_private(self); 269 1.1 nonaka struct wsmousedev_attach_args a; 270 1.1 nonaka 271 1.1 nonaka sc->sc_dev = self; 272 1.1 nonaka 273 1.2 nonaka aprint_normal(": touch panel\n"); 274 1.2 nonaka aprint_naive("\n"); 275 1.2 nonaka 276 1.1 nonaka sc->sc_model = wzero3tp_lookup(); 277 1.2 nonaka if (sc->sc_model == NULL) { 278 1.2 nonaka aprint_error_dev(self, "unknown model\n"); 279 1.1 nonaka return; 280 1.2 nonaka } 281 1.1 nonaka 282 1.1 nonaka callout_init(&sc->sc_tp_poll, 0); 283 1.1 nonaka callout_setfunc(&sc->sc_tp_poll, wzero3tp_poll, sc); 284 1.1 nonaka 285 1.2 nonaka if (sc->sc_model->wait_for_hsync) 286 1.2 nonaka ads7846_wait_for_hsync = sc->sc_model->wait_for_hsync; 287 1.2 nonaka 288 1.2 nonaka (*sc->sc_model->chip.init)(); 289 1.2 nonaka 290 1.1 nonaka a.accessops = &wzero3tp_accessops; 291 1.1 nonaka a.accesscookie = sc; 292 1.1 nonaka 293 1.10 thorpej sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint, CFARGS_NONE); 294 1.1 nonaka 295 1.1 nonaka /* Initialize calibration, set default parameters. */ 296 1.1 nonaka tpcalib_init(&sc->sc_tpcalib); 297 1.2 nonaka if (sc->sc_model->calib) { 298 1.2 nonaka tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS, 299 1.2 nonaka __UNCONST(sc->sc_model->calib), 0, 0); 300 1.2 nonaka } 301 1.1 nonaka } 302 1.1 nonaka 303 1.1 nonaka static int 304 1.1 nonaka wzero3tp_enable(void *v) 305 1.1 nonaka { 306 1.1 nonaka struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v; 307 1.1 nonaka 308 1.2 nonaka DPRINTF(("%s: %s\n", device_xname(sc->sc_dev), __func__)); 309 1.1 nonaka 310 1.1 nonaka if (sc->sc_enabled) { 311 1.1 nonaka DPRINTF(("%s: already enabled\n", device_xname(sc->sc_dev))); 312 1.1 nonaka return EBUSY; 313 1.1 nonaka } 314 1.1 nonaka 315 1.1 nonaka callout_stop(&sc->sc_tp_poll); 316 1.1 nonaka 317 1.1 nonaka if (!pmf_device_register(sc->sc_dev, wzero3tp_suspend, wzero3tp_resume)) 318 1.1 nonaka aprint_error_dev(sc->sc_dev, 319 1.1 nonaka "couldn't establish power handler\n"); 320 1.1 nonaka 321 1.2 nonaka pxa2x0_gpio_set_function(sc->sc_model->intr_pin, GPIO_IN); 322 1.1 nonaka 323 1.2 nonaka /* XXX */ 324 1.2 nonaka if (sc->sc_gh == NULL) { 325 1.2 nonaka sc->sc_gh = pxa2x0_gpio_intr_establish( 326 1.2 nonaka sc->sc_model->intr_pin, IST_EDGE_FALLING, IPL_TTY, 327 1.2 nonaka wzero3tp_irq, sc); 328 1.2 nonaka } else { 329 1.2 nonaka pxa2x0_gpio_intr_unmask(sc->sc_gh); 330 1.1 nonaka } 331 1.1 nonaka 332 1.1 nonaka /* enable interrupts */ 333 1.1 nonaka sc->sc_enabled = 1; 334 1.1 nonaka sc->sc_buttons = 0; 335 1.1 nonaka 336 1.1 nonaka return 0; 337 1.1 nonaka } 338 1.1 nonaka 339 1.1 nonaka static void 340 1.1 nonaka wzero3tp_disable(void *v) 341 1.1 nonaka { 342 1.1 nonaka struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v; 343 1.1 nonaka 344 1.2 nonaka DPRINTF(("%s: %s\n", device_xname(sc->sc_dev), __func__)); 345 1.1 nonaka 346 1.1 nonaka callout_stop(&sc->sc_tp_poll); 347 1.1 nonaka 348 1.1 nonaka pmf_device_deregister(sc->sc_dev); 349 1.1 nonaka 350 1.2 nonaka pxa2x0_gpio_intr_mask(sc->sc_gh); 351 1.1 nonaka 352 1.1 nonaka /* disable interrupts */ 353 1.1 nonaka sc->sc_enabled = 0; 354 1.1 nonaka } 355 1.1 nonaka 356 1.1 nonaka static bool 357 1.1 nonaka wzero3tp_suspend(device_t dv, const pmf_qual_t *qual) 358 1.1 nonaka { 359 1.1 nonaka struct wzero3tp_softc *sc = device_private(dv); 360 1.1 nonaka 361 1.2 nonaka DPRINTF(("%s: %s\n", device_xname(sc->sc_dev), __func__)); 362 1.1 nonaka 363 1.1 nonaka sc->sc_enabled = 0; 364 1.2 nonaka pxa2x0_gpio_intr_mask(sc->sc_gh); 365 1.1 nonaka 366 1.1 nonaka callout_stop(&sc->sc_tp_poll); 367 1.1 nonaka 368 1.2 nonaka (*sc->sc_model->chip.suspend)(); 369 1.1 nonaka 370 1.2 nonaka pxa2x0_gpio_set_function(sc->sc_model->intr_pin, GPIO_OUT|GPIO_SET); 371 1.1 nonaka 372 1.1 nonaka return true; 373 1.1 nonaka } 374 1.1 nonaka 375 1.1 nonaka static bool 376 1.1 nonaka wzero3tp_resume(device_t dv, const pmf_qual_t *qual) 377 1.1 nonaka { 378 1.1 nonaka struct wzero3tp_softc *sc = device_private(dv); 379 1.1 nonaka 380 1.2 nonaka DPRINTF(("%s: %s\n", device_xname(sc->sc_dev), __func__)); 381 1.1 nonaka 382 1.2 nonaka pxa2x0_gpio_set_function(sc->sc_model->intr_pin, GPIO_IN); 383 1.2 nonaka pxa2x0_gpio_intr_mask(sc->sc_gh); 384 1.1 nonaka 385 1.2 nonaka (*sc->sc_model->chip.resume)(); 386 1.1 nonaka 387 1.2 nonaka pxa2x0_gpio_intr_unmask(sc->sc_gh); 388 1.1 nonaka sc->sc_enabled = 1; 389 1.1 nonaka 390 1.1 nonaka return true; 391 1.1 nonaka } 392 1.1 nonaka 393 1.1 nonaka static void 394 1.1 nonaka wzero3tp_poll(void *v) 395 1.1 nonaka { 396 1.1 nonaka int s; 397 1.1 nonaka 398 1.1 nonaka s = spltty(); 399 1.1 nonaka (void)wzero3tp_irq(v); 400 1.1 nonaka splx(s); 401 1.1 nonaka } 402 1.1 nonaka 403 1.1 nonaka static int 404 1.1 nonaka wzero3tp_irq(void *v) 405 1.1 nonaka { 406 1.1 nonaka struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v; 407 1.1 nonaka struct wzero3tp_pos tp = { 0, 0, 0 }; 408 1.1 nonaka int pindown; 409 1.1 nonaka int down; 410 1.1 nonaka int x, y; 411 1.1 nonaka int s; 412 1.1 nonaka 413 1.1 nonaka if (!sc->sc_enabled) 414 1.1 nonaka return 0; 415 1.1 nonaka 416 1.1 nonaka s = splhigh(); 417 1.1 nonaka 418 1.2 nonaka pindown = pxa2x0_gpio_get_bit(sc->sc_model->intr_pin) ? 0 : 1; 419 1.1 nonaka DPRINTF(("%s: pindown = %d\n", device_xname(sc->sc_dev), pindown)); 420 1.1 nonaka if (pindown) { 421 1.1 nonaka pxa2x0_gpio_intr_mask(sc->sc_gh); 422 1.1 nonaka callout_schedule(&sc->sc_tp_poll, POLL_TIMEOUT_RATE1); 423 1.1 nonaka } 424 1.1 nonaka 425 1.2 nonaka down = (*sc->sc_model->chip.readpos)(&tp); 426 1.1 nonaka DPRINTF(("%s: x = %d, y = %d, z = %d, down = %d\n", 427 1.1 nonaka device_xname(sc->sc_dev), tp.x, tp.y, tp.z, down)); 428 1.1 nonaka 429 1.1 nonaka if (!pindown) { 430 1.1 nonaka pxa2x0_gpio_intr_unmask(sc->sc_gh); 431 1.1 nonaka callout_schedule(&sc->sc_tp_poll, POLL_TIMEOUT_RATE0); 432 1.1 nonaka } 433 1.2 nonaka pxa2x0_gpio_clear_intr(sc->sc_model->intr_pin); 434 1.1 nonaka 435 1.1 nonaka splx(s); 436 1.1 nonaka 437 1.1 nonaka if (down) { 438 1.1 nonaka if (!wzero3tp_rawmode) { 439 1.1 nonaka tpcalib_trans(&sc->sc_tpcalib, tp.x, tp.y, &x, &y); 440 1.1 nonaka DPRINTF(("%s: x = %d, y = %d\n", 441 1.1 nonaka device_xname(sc->sc_dev), x, y)); 442 1.1 nonaka tp.x = x; 443 1.1 nonaka tp.y = y; 444 1.1 nonaka } 445 1.1 nonaka } 446 1.1 nonaka 447 1.1 nonaka if (!down) { 448 1.1 nonaka /* x/y values are not reliable when pen is up */ 449 1.1 nonaka tp = sc->sc_oldpos; 450 1.1 nonaka } 451 1.1 nonaka 452 1.1 nonaka if (down || sc->sc_buttons != down) { 453 1.1 nonaka wsmouse_input(sc->sc_wsmousedev, down, tp.x, tp.y, 0, 0, 454 1.1 nonaka WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y); 455 1.1 nonaka sc->sc_buttons = down; 456 1.1 nonaka sc->sc_oldpos = tp; 457 1.1 nonaka } 458 1.1 nonaka 459 1.1 nonaka return 1; 460 1.1 nonaka } 461 1.1 nonaka 462 1.1 nonaka static int 463 1.1 nonaka wzero3tp_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) 464 1.1 nonaka { 465 1.1 nonaka struct wzero3tp_softc *sc = (struct wzero3tp_softc *)v; 466 1.1 nonaka struct wsmouse_id *id; 467 1.1 nonaka 468 1.1 nonaka switch (cmd) { 469 1.1 nonaka case WSMOUSEIO_GTYPE: 470 1.1 nonaka *(u_int *)data = WSMOUSE_TYPE_TPANEL; 471 1.1 nonaka return 0; 472 1.1 nonaka 473 1.1 nonaka case WSMOUSEIO_GETID: 474 1.1 nonaka /* 475 1.1 nonaka * return unique ID string, 476 1.1 nonaka * "<vendor> <model> <serial number>" 477 1.1 nonaka */ 478 1.1 nonaka id = (struct wsmouse_id *)data; 479 1.1 nonaka if (id->type != WSMOUSE_ID_TYPE_UIDSTR) 480 1.1 nonaka return EINVAL; 481 1.1 nonaka snprintf(id->data, WSMOUSE_ID_MAXLEN, "Sharp %s SN000000", 482 1.1 nonaka sc->sc_model->name); 483 1.1 nonaka id->length = strlen(id->data); 484 1.1 nonaka return 0; 485 1.1 nonaka 486 1.1 nonaka case WSMOUSEIO_SCALIBCOORDS: 487 1.1 nonaka case WSMOUSEIO_GCALIBCOORDS: 488 1.1 nonaka return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, l); 489 1.1 nonaka } 490 1.1 nonaka 491 1.1 nonaka return EPASSTHROUGH; 492 1.1 nonaka } 493 1.2 nonaka 494 1.2 nonaka /*---------------------------------------------------------------------------- 495 1.2 nonaka * null driver 496 1.2 nonaka */ 497 1.2 nonaka static void 498 1.2 nonaka nulldrv_init(void) 499 1.2 nonaka { 500 1.2 nonaka 501 1.2 nonaka /* Nothing to do */ 502 1.2 nonaka } 503 1.2 nonaka 504 1.2 nonaka static int 505 1.2 nonaka nulldrv_readpos(struct wzero3tp_pos *pos) 506 1.2 nonaka { 507 1.2 nonaka 508 1.2 nonaka pos->x = 0; 509 1.2 nonaka pos->y = 0; 510 1.2 nonaka pos->z = 0; 511 1.2 nonaka 512 1.2 nonaka return 0; 513 1.2 nonaka } 514 1.2 nonaka 515 1.2 nonaka static void 516 1.2 nonaka nulldrv_suspend(void) 517 1.2 nonaka { 518 1.2 nonaka 519 1.2 nonaka /* Nothing to do */ 520 1.2 nonaka } 521 1.2 nonaka 522 1.2 nonaka static void 523 1.2 nonaka nulldrv_resume(void) 524 1.2 nonaka { 525 1.2 nonaka 526 1.2 nonaka /* Nothing to do */ 527 1.2 nonaka } 528 1.2 nonaka 529 1.2 nonaka /*---------------------------------------------------------------------------- 530 1.2 nonaka * model specific functions 531 1.2 nonaka */ 532 1.2 nonaka static void 533 1.2 nonaka ws007sh_wait_for_hsync(void) 534 1.2 nonaka { 535 1.2 nonaka 536 1.2 nonaka while (pxa2x0_gpio_get_bit(GPIO_WS007SH_HSYNC) == 0) 537 1.2 nonaka continue; 538 1.2 nonaka while (pxa2x0_gpio_get_bit(GPIO_WS007SH_HSYNC) != 0) 539 1.2 nonaka continue; 540 1.2 nonaka } 541 1.2 nonaka 542 1.2 nonaka /*---------------------------------------------------------------------------- 543 1.2 nonaka * MAX1233 touch screen controller for WS003SH/WS004SH 544 1.2 nonaka */ 545 1.2 nonaka #define MAXCTRL_ADDR_SH 0 /* Address bit[5:0] */ 546 1.2 nonaka #define MAXCTRL_PAGE_SH 6 /* Page bit (0:Data/1:Control) */ 547 1.2 nonaka #define MAXCTRL_RW_SH 15 /* R/W bit (0:Write/1:Read) */ 548 1.2 nonaka 549 1.2 nonaka /* VREF=2.5V, sets interrupt initiated touch-screen scans 550 1.6 tsutsui * 3.5us/sample, 16 data ave., 12 bit, settling time: 100us */ 551 1.6 tsutsui #define MAX1233_ADCCTRL 0x8be3 552 1.2 nonaka 553 1.2 nonaka void 554 1.2 nonaka max1233_init(void) 555 1.2 nonaka { 556 1.2 nonaka 557 1.2 nonaka /* Enable automatic low power mode. */ 558 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 559 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH), 560 1.2 nonaka 0x0001); 561 1.2 nonaka /* Wait for touch */ 562 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 563 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH), 564 1.2 nonaka MAX1233_ADCCTRL); 565 1.6 tsutsui /* DAC on */ 566 1.6 tsutsui (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 567 1.6 tsutsui (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (2<<MAXCTRL_ADDR_SH), 568 1.6 tsutsui 0x0000); 569 1.2 nonaka } 570 1.2 nonaka 571 1.2 nonaka void 572 1.2 nonaka max1233_suspend(void) 573 1.2 nonaka { 574 1.2 nonaka 575 1.2 nonaka /* power down. */ 576 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 577 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH), 578 1.2 nonaka 0xc000); 579 1.2 nonaka /* DAC off */ 580 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 581 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (2<<MAXCTRL_ADDR_SH), 582 1.2 nonaka 0x8000); 583 1.2 nonaka } 584 1.2 nonaka 585 1.2 nonaka void 586 1.2 nonaka max1233_resume(void) 587 1.2 nonaka { 588 1.2 nonaka 589 1.2 nonaka /* Enable automatic low power mode. */ 590 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 591 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH), 592 1.2 nonaka 0x0001); 593 1.2 nonaka /* Wait for touch */ 594 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 595 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH), 596 1.2 nonaka MAX1233_ADCCTRL); 597 1.2 nonaka /* DAC on */ 598 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 599 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (2<<MAXCTRL_ADDR_SH), 600 1.2 nonaka 0x0000); 601 1.2 nonaka } 602 1.2 nonaka 603 1.2 nonaka int 604 1.2 nonaka max1233_readpos(struct wzero3tp_pos *pos) 605 1.2 nonaka { 606 1.6 tsutsui uint32_t x, y, z1 = 0, z2 = 0, rt; 607 1.2 nonaka uint32_t status; 608 1.2 nonaka int down; 609 1.2 nonaka 610 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 611 1.2 nonaka (0<<MAXCTRL_RW_SH) | (1<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH), 612 1.3 nonaka 0x0bf3); 613 1.6 tsutsui DELAY(300); 614 1.2 nonaka 615 1.2 nonaka while ((status = (wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 616 1.2 nonaka (1<<MAXCTRL_RW_SH) 617 1.2 nonaka | (1<<MAXCTRL_PAGE_SH) 618 1.2 nonaka | (0<<MAXCTRL_ADDR_SH), 0) & 0x4000)) != 0x4000) { 619 1.2 nonaka DPRINTF(("%s: status=%#x\n", __func__, status)); 620 1.6 tsutsui DELAY(10); 621 1.2 nonaka } 622 1.2 nonaka DPRINTF(("%s: status=%#x\n", __func__, status)); 623 1.2 nonaka 624 1.6 tsutsui x = wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 625 1.2 nonaka (1<<MAXCTRL_RW_SH) | (0<<MAXCTRL_PAGE_SH) | (0<<MAXCTRL_ADDR_SH),0); 626 1.6 tsutsui DPRINTF(("%s: x=%d\n", __func__, x)); 627 1.6 tsutsui y = wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 628 1.2 nonaka (1<<MAXCTRL_RW_SH) | (0<<MAXCTRL_PAGE_SH) | (1<<MAXCTRL_ADDR_SH),0); 629 1.6 tsutsui DPRINTF(("%s: y=%d\n", __func__, y)); 630 1.2 nonaka z1 = wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 631 1.2 nonaka (1<<MAXCTRL_RW_SH) | (0<<MAXCTRL_PAGE_SH) | (2<<MAXCTRL_ADDR_SH),0); 632 1.2 nonaka DPRINTF(("%s: z1=%d\n", __func__, z1)); 633 1.2 nonaka z2 = wzero3ssp_ic_send(WZERO3_SSP_IC_MAX1233, 634 1.2 nonaka (1<<MAXCTRL_RW_SH) | (0<<MAXCTRL_PAGE_SH) | (3<<MAXCTRL_ADDR_SH),0); 635 1.2 nonaka DPRINTF(("%s: z2=%d\n", __func__, z2)); 636 1.2 nonaka 637 1.6 tsutsui if (z1 >= 10) { 638 1.4 nonaka rt = 400 /* XXX: X plate ohms */; 639 1.6 tsutsui rt *= x; 640 1.2 nonaka rt *= (z2 / z1) - 1; 641 1.2 nonaka rt >>= 12; 642 1.2 nonaka } else 643 1.2 nonaka rt = 0; 644 1.2 nonaka DPRINTF(("%s: rt=%d\n", __func__, rt)); 645 1.2 nonaka 646 1.6 tsutsui down = (rt != 0); 647 1.6 tsutsui if (down) { 648 1.6 tsutsui pos->x = x; 649 1.6 tsutsui pos->y = y; 650 1.6 tsutsui } 651 1.2 nonaka pos->z = down; 652 1.2 nonaka 653 1.2 nonaka return down; 654 1.2 nonaka } 655 1.2 nonaka 656 1.2 nonaka /*---------------------------------------------------------------------------- 657 1.2 nonaka * ADS7846/TSC2046 touch screen controller for WS007SH 658 1.2 nonaka */ 659 1.4 nonaka #define ADSCTRL_PD0_SH 0 /* PD0 bit */ 660 1.4 nonaka #define ADSCTRL_PD1_SH 1 /* PD1 bit */ 661 1.4 nonaka #define ADSCTRL_DFR_SH 2 /* SER/DFR bit */ 662 1.4 nonaka #define ADSCTRL_MOD_SH 3 /* Mode bit */ 663 1.4 nonaka #define ADSCTRL_ADR_SH 4 /* Address setting */ 664 1.4 nonaka #define ADSCTRL_STS_SH 7 /* Start bit */ 665 1.2 nonaka 666 1.2 nonaka static uint32_t ads7846_sync(int, int, uint32_t); 667 1.2 nonaka 668 1.2 nonaka void 669 1.2 nonaka ads7846_init(void) 670 1.2 nonaka { 671 1.2 nonaka 672 1.2 nonaka /* Enable automatic low power mode. */ 673 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, 674 1.2 nonaka (4<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH), 0); 675 1.2 nonaka } 676 1.2 nonaka 677 1.2 nonaka void 678 1.2 nonaka ads7846_suspend(void) 679 1.2 nonaka { 680 1.2 nonaka 681 1.2 nonaka /* Turn off reference voltage but leave ADC on. */ 682 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, 683 1.2 nonaka (1<<ADSCTRL_PD1_SH) | (1<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH), 0); 684 1.2 nonaka } 685 1.2 nonaka 686 1.2 nonaka void 687 1.2 nonaka ads7846_resume(void) 688 1.2 nonaka { 689 1.2 nonaka 690 1.2 nonaka /* Enable automatic low power mode. */ 691 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, 692 1.2 nonaka (4<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH), 0); 693 1.2 nonaka } 694 1.2 nonaka 695 1.2 nonaka int 696 1.2 nonaka ads7846_readpos(struct wzero3tp_pos *pos) 697 1.2 nonaka { 698 1.2 nonaka int cmd, cmd0; 699 1.2 nonaka int z0, z1; 700 1.2 nonaka int down; 701 1.2 nonaka 702 1.2 nonaka cmd0 = (1<<ADSCTRL_STS_SH) | (1<<ADSCTRL_PD0_SH) | (1<<ADSCTRL_PD1_SH); 703 1.2 nonaka 704 1.2 nonaka /* check that pen is down */ 705 1.2 nonaka cmd = cmd0 | (3<<ADSCTRL_ADR_SH); 706 1.2 nonaka z0 = wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, cmd, 0); 707 1.2 nonaka DPRINTF(("%s: first z0 = %d\n", __func__, z0)); 708 1.2 nonaka 709 1.2 nonaka down = (z0 >= 10); 710 1.2 nonaka if (!down) 711 1.2 nonaka goto out; 712 1.2 nonaka 713 1.2 nonaka /* Y (discard) */ 714 1.2 nonaka cmd = cmd0 | (1<<ADSCTRL_ADR_SH); 715 1.2 nonaka (void)ads7846_sync(0, 1, cmd); 716 1.2 nonaka 717 1.2 nonaka /* Y */ 718 1.2 nonaka cmd = cmd0 | (1<<ADSCTRL_ADR_SH); 719 1.2 nonaka (void)ads7846_sync(1, 1, cmd); 720 1.2 nonaka 721 1.2 nonaka /* X */ 722 1.2 nonaka cmd = cmd0 | (5<<ADSCTRL_ADR_SH); 723 1.2 nonaka pos->y = ads7846_sync(1, 1, cmd); 724 1.2 nonaka DPRINTF(("%s: y = %d\n", __func__, pos->y)); 725 1.2 nonaka 726 1.2 nonaka /* Z0 */ 727 1.2 nonaka cmd = cmd0 | (3<<ADSCTRL_ADR_SH); 728 1.2 nonaka pos->x = ads7846_sync(1, 1, cmd); 729 1.2 nonaka DPRINTF(("%s: x = %d\n", __func__, pos->x)); 730 1.2 nonaka 731 1.2 nonaka /* Z1 */ 732 1.2 nonaka cmd = cmd0 | (4<<ADSCTRL_ADR_SH); 733 1.2 nonaka z0 = ads7846_sync(1, 1, cmd); 734 1.2 nonaka z1 = ads7846_sync(1, 0, cmd); 735 1.2 nonaka DPRINTF(("%s: z0 = %d, z1 = %d\n", __func__, z0, z1)); 736 1.2 nonaka 737 1.2 nonaka /* check that pen is still down */ 738 1.2 nonaka if (z0 == 0 || (pos->x * (z1 - z0) / z0) >= 15000) 739 1.2 nonaka down = 0; 740 1.2 nonaka pos->z = down; 741 1.2 nonaka 742 1.2 nonaka out: 743 1.2 nonaka /* Enable automatic low power mode. */ 744 1.2 nonaka cmd = (1<<ADSCTRL_ADR_SH) | (1<<ADSCTRL_STS_SH); 745 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, cmd, 0); 746 1.2 nonaka 747 1.2 nonaka return down; 748 1.2 nonaka } 749 1.2 nonaka 750 1.2 nonaka void (*ads7846_wait_for_hsync)(void); 751 1.2 nonaka 752 1.2 nonaka /* 753 1.2 nonaka * Communicate synchronously with the ADS784x touch screen controller. 754 1.2 nonaka */ 755 1.2 nonaka static uint32_t 756 1.2 nonaka ads7846_sync(int dorecv, int dosend, uint32_t cmd) 757 1.2 nonaka { 758 1.2 nonaka uint32_t rv = 0; 759 1.2 nonaka 760 1.2 nonaka if (ads7846_wait_for_hsync) 761 1.2 nonaka (*ads7846_wait_for_hsync)(); 762 1.2 nonaka 763 1.2 nonaka if (dorecv) 764 1.2 nonaka rv = wzero3ssp_ic_stop(WZERO3_SSP_IC_ADS7846); 765 1.2 nonaka 766 1.2 nonaka if (dosend) { 767 1.2 nonaka /* send dummy command; discard SSDR */ 768 1.2 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_ADS7846, cmd, 0); 769 1.2 nonaka 770 1.2 nonaka /* wait for refresh */ 771 1.2 nonaka if (ads7846_wait_for_hsync) 772 1.2 nonaka (*ads7846_wait_for_hsync)(); 773 1.2 nonaka 774 1.2 nonaka /* send the actual command; keep ADS784x enabled */ 775 1.2 nonaka wzero3ssp_ic_start(WZERO3_SSP_IC_ADS7846, cmd); 776 1.2 nonaka } 777 1.2 nonaka 778 1.2 nonaka return rv; 779 1.2 nonaka } 780 1.4 nonaka 781 1.4 nonaka /*---------------------------------------------------------------------------- 782 1.4 nonaka * AK4184 touch screen controller for WS011SH 783 1.4 nonaka */ 784 1.4 nonaka #define AKMCTRL_PD_SH 12 /* Power down bit */ 785 1.4 nonaka #define AKMCTRL_ADR_SH 13 /* Address setting bits */ 786 1.4 nonaka #define AKMCTRL_STS_SH 15 /* Start bit */ 787 1.4 nonaka 788 1.4 nonaka static uint32_t ak4184_sync(int, int, uint32_t); 789 1.4 nonaka 790 1.4 nonaka void 791 1.4 nonaka ak4184_init(void) 792 1.4 nonaka { 793 1.4 nonaka 794 1.4 nonaka /* Enable automatic low power mode. */ 795 1.5 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184_TP, 796 1.4 nonaka (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (0<<AKMCTRL_PD_SH), 0); 797 1.4 nonaka } 798 1.4 nonaka 799 1.4 nonaka int 800 1.4 nonaka ak4184_readpos(struct wzero3tp_pos *pos) 801 1.4 nonaka { 802 1.4 nonaka u_int rt; 803 1.4 nonaka int z1, z2; 804 1.4 nonaka 805 1.4 nonaka /* X (discard) */ 806 1.4 nonaka (void)ak4184_sync(0, 1, 807 1.4 nonaka (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH)); 808 1.4 nonaka 809 1.4 nonaka /* X */ 810 1.4 nonaka (void)ak4184_sync(1, 1, 811 1.4 nonaka (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH)); 812 1.4 nonaka 813 1.4 nonaka /* Y */ 814 1.4 nonaka pos->x = ak4184_sync(1, 1, 815 1.4 nonaka (1<<AKMCTRL_STS_SH) | (1<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH)); 816 1.4 nonaka DPRINTF(("%s: x=%d\n", __func__, pos->x)); 817 1.4 nonaka pos->y = ak4184_sync(1, 1, 818 1.4 nonaka (1<<AKMCTRL_STS_SH) | (2<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH)); 819 1.4 nonaka DPRINTF(("%s: y=%d\n", __func__, pos->y)); 820 1.4 nonaka z1 = ak4184_sync(1, 1, 821 1.4 nonaka (1<<AKMCTRL_STS_SH) | (3<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH)); 822 1.4 nonaka DPRINTF(("%s: z1=%d\n", __func__, z1)); 823 1.4 nonaka z2 = ak4184_sync(1, 0, 824 1.4 nonaka (1<<AKMCTRL_STS_SH) | (3<<AKMCTRL_ADR_SH) | (1<<AKMCTRL_PD_SH)); 825 1.4 nonaka DPRINTF(("%s: z2=%d\n", __func__, z2)); 826 1.4 nonaka 827 1.4 nonaka if (z1 >= 10) { 828 1.4 nonaka rt = 400 /* XXX: X plate ohms */; 829 1.4 nonaka rt *= pos->x; 830 1.4 nonaka rt *= (z2 / z1) - 1; 831 1.4 nonaka rt >>= 12; 832 1.4 nonaka } else 833 1.4 nonaka rt = 0; 834 1.4 nonaka DPRINTF(("%s: rt=%d\n", __func__, rt)); 835 1.4 nonaka 836 1.4 nonaka /* check that pen is still down */ 837 1.4 nonaka if (z1 == 0 || rt == 0) 838 1.4 nonaka pos->z = 0; 839 1.4 nonaka else 840 1.4 nonaka pos->z = 1; 841 1.4 nonaka 842 1.4 nonaka /* Enable automatic low power mode. */ 843 1.5 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184_TP, 844 1.4 nonaka (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (0<<AKMCTRL_PD_SH), 0); 845 1.4 nonaka 846 1.4 nonaka return pos->z; 847 1.4 nonaka } 848 1.4 nonaka 849 1.4 nonaka void 850 1.4 nonaka ak4184_suspend(void) 851 1.4 nonaka { 852 1.4 nonaka 853 1.4 nonaka /* Nothing to do */ 854 1.4 nonaka } 855 1.4 nonaka 856 1.4 nonaka void 857 1.4 nonaka ak4184_resume(void) 858 1.4 nonaka { 859 1.4 nonaka 860 1.4 nonaka /* Enable automatic low power mode. */ 861 1.5 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184_TP, 862 1.4 nonaka (1<<AKMCTRL_STS_SH) | (0<<AKMCTRL_ADR_SH) | (0<<AKMCTRL_PD_SH), 0); 863 1.4 nonaka } 864 1.4 nonaka 865 1.4 nonaka static uint32_t 866 1.4 nonaka ak4184_sync(int dorecv, int dosend, uint32_t cmd) 867 1.4 nonaka { 868 1.4 nonaka uint32_t rv = 0; 869 1.4 nonaka 870 1.4 nonaka if (dorecv) 871 1.5 nonaka rv = wzero3ssp_ic_stop(WZERO3_SSP_IC_AK4184_TP); 872 1.4 nonaka 873 1.4 nonaka if (dosend) { 874 1.4 nonaka /* send dummy command; discard SSDR */ 875 1.5 nonaka (void)wzero3ssp_ic_send(WZERO3_SSP_IC_AK4184_TP, cmd, 0); 876 1.4 nonaka 877 1.4 nonaka /* send the actual command; keep AK4184 enabled */ 878 1.5 nonaka wzero3ssp_ic_start(WZERO3_SSP_IC_AK4184_TP, cmd); 879 1.4 nonaka } 880 1.4 nonaka 881 1.4 nonaka return rv; 882 1.4 nonaka } 883