1 1.5 nonaka /* $NetBSD: wzero3_ssp.c,v 1.5 2012/01/21 19:44:29 nonaka Exp $ */ 2 1.1 nonaka 3 1.5 nonaka /*- 4 1.5 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.5 nonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.5 nonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.5 nonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.5 nonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.5 nonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.5 nonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.5 nonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.5 nonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.5 nonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.5 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.5 nonaka __KERNEL_RCSID(0, "$NetBSD: wzero3_ssp.c,v 1.5 2012/01/21 19:44:29 nonaka Exp $"); 30 1.1 nonaka 31 1.1 nonaka #include <sys/param.h> 32 1.1 nonaka #include <sys/systm.h> 33 1.1 nonaka #include <sys/device.h> 34 1.1 nonaka #include <sys/mutex.h> 35 1.1 nonaka #include <sys/pmf.h> 36 1.1 nonaka #include <sys/bus.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 <arm/xscale/pxa2x0reg.h> 43 1.1 nonaka #include <arm/xscale/pxa2x0var.h> 44 1.1 nonaka #include <arm/xscale/pxa2x0_gpio.h> 45 1.1 nonaka 46 1.1 nonaka #include <hpcarm/dev/wzero3_reg.h> 47 1.1 nonaka #include <hpcarm/dev/wzero3_sspvar.h> 48 1.1 nonaka 49 1.2 nonaka #define WS003SH_SSCR0_MAX1233 0x0000048f /* 16bit/SPI/div by 5 */ 50 1.2 nonaka #define WS007SH_SSCR0_ADS7846 0x000006ab /* 12bit/Microwire/div by 7 */ 51 1.3 nonaka #define WS011SH_SSCR0_AK4184_TP 0x0010068f /* 32bit/SPI/div by 7 */ 52 1.4 nonaka #define WS011SH_SSCR0_AK4184_KEYPAD 0x0000068f /* 16bit/SPI/div by 7 */ 53 1.1 nonaka 54 1.2 nonaka struct wzero3ssp_model; 55 1.1 nonaka struct wzero3ssp_softc { 56 1.1 nonaka device_t sc_dev; 57 1.1 nonaka bus_space_tag_t sc_iot; 58 1.1 nonaka bus_space_handle_t sc_ioh; 59 1.1 nonaka kmutex_t sc_mtx; 60 1.2 nonaka const struct wzero3ssp_model *sc_model; 61 1.1 nonaka }; 62 1.1 nonaka 63 1.1 nonaka static int wzero3ssp_match(device_t, cfdata_t, void *); 64 1.1 nonaka static void wzero3ssp_attach(device_t, device_t, void *); 65 1.1 nonaka 66 1.1 nonaka CFATTACH_DECL_NEW(wzero3ssp, sizeof(struct wzero3ssp_softc), 67 1.1 nonaka wzero3ssp_match, wzero3ssp_attach, NULL, NULL); 68 1.1 nonaka 69 1.1 nonaka static void wzero3ssp_init(struct wzero3ssp_softc *); 70 1.1 nonaka static bool wzero3ssp_resume(device_t dv, const pmf_qual_t *); 71 1.2 nonaka static uint32_t wzero3ssp_read_ads7846(struct wzero3ssp_softc *, uint32_t); 72 1.2 nonaka static uint32_t wzero3ssp_read_max1233(struct wzero3ssp_softc *, uint32_t, 73 1.2 nonaka uint32_t); 74 1.4 nonaka static uint32_t wzero3ssp_read_ak4184_tp(struct wzero3ssp_softc *, uint32_t); 75 1.4 nonaka static uint16_t wzero3ssp_read_ak4184_keypad(struct wzero3ssp_softc *, uint32_t, 76 1.4 nonaka uint32_t); 77 1.1 nonaka 78 1.1 nonaka static struct wzero3ssp_softc *wzero3ssp_sc; 79 1.1 nonaka 80 1.1 nonaka static const struct wzero3ssp_model { 81 1.1 nonaka platid_mask_t *platid; 82 1.2 nonaka u_long sspaddr; 83 1.1 nonaka } wzero3ssp_table[] = { 84 1.1 nonaka /* WS003SH */ 85 1.1 nonaka { 86 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS003SH, 87 1.2 nonaka PXA2X0_SSP2_BASE, 88 1.1 nonaka }, 89 1.1 nonaka /* WS004SH */ 90 1.1 nonaka { 91 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS004SH, 92 1.2 nonaka PXA2X0_SSP2_BASE, 93 1.1 nonaka }, 94 1.1 nonaka /* WS007SH */ 95 1.1 nonaka { 96 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS007SH, 97 1.2 nonaka PXA2X0_SSP1_BASE, 98 1.1 nonaka }, 99 1.1 nonaka /* WS011SH */ 100 1.1 nonaka { 101 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS011SH, 102 1.2 nonaka PXA2X0_SSP1_BASE, 103 1.1 nonaka }, 104 1.2 nonaka #if 0 105 1.1 nonaka /* WS0020H */ 106 1.1 nonaka { 107 1.1 nonaka &platid_mask_MACH_SHARP_WZERO3_WS020SH, 108 1.2 nonaka PXA2X0_SSP1_BASE, 109 1.1 nonaka }, 110 1.1 nonaka #endif 111 1.1 nonaka { 112 1.2 nonaka NULL, 0, 113 1.1 nonaka }, 114 1.1 nonaka }; 115 1.1 nonaka 116 1.1 nonaka static const struct wzero3ssp_model * 117 1.1 nonaka wzero3ssp_lookup(void) 118 1.1 nonaka { 119 1.1 nonaka const struct wzero3ssp_model *model; 120 1.1 nonaka 121 1.1 nonaka for (model = wzero3ssp_table; model->platid != NULL; model++) { 122 1.1 nonaka if (platid_match(&platid, model->platid)) { 123 1.1 nonaka return model; 124 1.1 nonaka } 125 1.1 nonaka } 126 1.1 nonaka return NULL; 127 1.1 nonaka } 128 1.1 nonaka 129 1.1 nonaka static int 130 1.1 nonaka wzero3ssp_match(device_t parent, cfdata_t cf, void *aux) 131 1.1 nonaka { 132 1.1 nonaka 133 1.1 nonaka if (strcmp(cf->cf_name, "wzero3ssp") != 0) 134 1.1 nonaka return 0; 135 1.1 nonaka if (wzero3ssp_lookup() == NULL) 136 1.1 nonaka return 0; 137 1.1 nonaka if (wzero3ssp_sc != NULL) 138 1.1 nonaka return 0; 139 1.1 nonaka return 1; 140 1.1 nonaka } 141 1.1 nonaka 142 1.1 nonaka static void 143 1.1 nonaka wzero3ssp_attach(device_t parent, device_t self, void *aux) 144 1.1 nonaka { 145 1.1 nonaka struct wzero3ssp_softc *sc = device_private(self); 146 1.1 nonaka 147 1.1 nonaka sc->sc_dev = self; 148 1.1 nonaka wzero3ssp_sc = sc; 149 1.1 nonaka 150 1.1 nonaka aprint_normal("\n"); 151 1.1 nonaka aprint_naive("\n"); 152 1.1 nonaka 153 1.2 nonaka sc->sc_model = wzero3ssp_lookup(); 154 1.2 nonaka if (sc->sc_model == NULL) { 155 1.2 nonaka aprint_error_dev(self, "unknown model\n"); 156 1.2 nonaka return; 157 1.2 nonaka } 158 1.2 nonaka 159 1.1 nonaka mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_TTY); 160 1.1 nonaka 161 1.1 nonaka sc->sc_iot = &pxa2x0_bs_tag; 162 1.2 nonaka if (bus_space_map(sc->sc_iot, sc->sc_model->sspaddr, PXA2X0_SSP_SIZE, 0, 163 1.1 nonaka &sc->sc_ioh)) { 164 1.1 nonaka aprint_error_dev(sc->sc_dev, "can't map bus space\n"); 165 1.1 nonaka return; 166 1.1 nonaka } 167 1.1 nonaka 168 1.1 nonaka if (!pmf_device_register(sc->sc_dev, NULL, wzero3ssp_resume)) 169 1.1 nonaka aprint_error_dev(sc->sc_dev, 170 1.1 nonaka "couldn't establish power handler\n"); 171 1.1 nonaka 172 1.1 nonaka wzero3ssp_init(sc); 173 1.1 nonaka } 174 1.1 nonaka 175 1.1 nonaka /* 176 1.1 nonaka * Initialize the dedicated SSP unit and disable all chip selects. 177 1.1 nonaka * This function is called with interrupts disabled. 178 1.1 nonaka */ 179 1.1 nonaka static void 180 1.1 nonaka wzero3ssp_init(struct wzero3ssp_softc *sc) 181 1.1 nonaka { 182 1.1 nonaka 183 1.2 nonaka if (sc->sc_model->sspaddr == PXA2X0_SSP1_BASE) 184 1.2 nonaka pxa2x0_clkman_config(CKEN_SSP2, 1); 185 1.2 nonaka else if (sc->sc_model->sspaddr == PXA2X0_SSP2_BASE) 186 1.2 nonaka pxa2x0_clkman_config(CKEN_SSP3, 1); 187 1.1 nonaka 188 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 189 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0); 190 1.1 nonaka 191 1.2 nonaka /* XXX */ 192 1.2 nonaka if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH) 193 1.2 nonaka || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) { 194 1.2 nonaka pxa2x0_gpio_set_function(39/*GPIO_WS003SH_XXX*/, 195 1.2 nonaka GPIO_OUT|GPIO_SET); 196 1.2 nonaka pxa2x0_gpio_set_function(GPIO_WS003SH_MAX1233_CS, 197 1.2 nonaka GPIO_OUT|GPIO_SET); 198 1.2 nonaka } 199 1.2 nonaka if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) { 200 1.2 nonaka pxa2x0_gpio_set_function(GPIO_WS007SH_ADS7846_CS, 201 1.2 nonaka GPIO_OUT|GPIO_SET); 202 1.2 nonaka } 203 1.3 nonaka if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) { 204 1.3 nonaka pxa2x0_gpio_set_function(GPIO_WS011SH_AK4184_CS, 205 1.3 nonaka GPIO_OUT|GPIO_SET); 206 1.3 nonaka } 207 1.1 nonaka } 208 1.1 nonaka 209 1.1 nonaka static bool 210 1.1 nonaka wzero3ssp_resume(device_t dv, const pmf_qual_t *qual) 211 1.1 nonaka { 212 1.1 nonaka struct wzero3ssp_softc *sc = device_private(dv); 213 1.1 nonaka 214 1.1 nonaka mutex_enter(&sc->sc_mtx); 215 1.1 nonaka wzero3ssp_init(sc); 216 1.1 nonaka mutex_exit(&sc->sc_mtx); 217 1.1 nonaka 218 1.1 nonaka return true; 219 1.1 nonaka } 220 1.1 nonaka 221 1.1 nonaka /* 222 1.1 nonaka * Transmit a single data word to one of the ICs, keep the chip selected 223 1.1 nonaka * afterwards, and don't wait for data to be returned in SSDR. Interrupts 224 1.1 nonaka * must be held off until wzero3ssp_ic_stop() gets called. 225 1.1 nonaka */ 226 1.1 nonaka void 227 1.1 nonaka wzero3ssp_ic_start(int ic, uint32_t cmd) 228 1.1 nonaka { 229 1.1 nonaka struct wzero3ssp_softc *sc; 230 1.1 nonaka 231 1.1 nonaka KASSERT(wzero3ssp_sc != NULL); 232 1.1 nonaka sc = wzero3ssp_sc; 233 1.1 nonaka 234 1.1 nonaka mutex_enter(&sc->sc_mtx); 235 1.1 nonaka 236 1.1 nonaka /* disable other ICs */ 237 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 238 1.3 nonaka if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) { 239 1.3 nonaka if (ic != WZERO3_SSP_IC_ADS7846) 240 1.3 nonaka pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS); 241 1.3 nonaka } 242 1.3 nonaka if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) { 243 1.4 nonaka if (ic != WZERO3_SSP_IC_AK4184_TP 244 1.4 nonaka && ic != WZERO3_SSP_IC_AK4184_KEYPAD) 245 1.3 nonaka pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS); 246 1.3 nonaka } 247 1.1 nonaka 248 1.1 nonaka /* activate the chosen one */ 249 1.1 nonaka switch (ic) { 250 1.1 nonaka case WZERO3_SSP_IC_ADS7846: 251 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 252 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 253 1.1 nonaka WS007SH_SSCR0_ADS7846); 254 1.1 nonaka pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS); 255 1.1 nonaka bus_space_write_1(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd); 256 1.1 nonaka while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) 257 1.1 nonaka & SSSR_TNF) != SSSR_TNF) 258 1.1 nonaka continue; /* poll */ 259 1.1 nonaka break; 260 1.4 nonaka case WZERO3_SSP_IC_AK4184_TP: 261 1.3 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 262 1.3 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 263 1.3 nonaka WS011SH_SSCR0_AK4184_TP); 264 1.3 nonaka pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS); 265 1.3 nonaka (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 266 1.3 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) 267 1.3 nonaka & SSSR_TNF)) 268 1.3 nonaka continue; /* poll */ 269 1.3 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16); 270 1.3 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) 271 1.3 nonaka & SSSR_BUSY) 272 1.3 nonaka continue; /* poll */ 273 1.3 nonaka break; 274 1.2 nonaka case WZERO3_SSP_IC_MAX1233: 275 1.4 nonaka case WZERO3_SSP_IC_AK4184_KEYPAD: 276 1.2 nonaka case WZERO3_SSP_IC_NUM: 277 1.2 nonaka default: 278 1.2 nonaka break; 279 1.1 nonaka } 280 1.1 nonaka } 281 1.1 nonaka 282 1.1 nonaka /* 283 1.1 nonaka * Read the last value from SSDR and deactivate all chip-selects. 284 1.1 nonaka */ 285 1.1 nonaka uint32_t 286 1.1 nonaka wzero3ssp_ic_stop(int ic) 287 1.1 nonaka { 288 1.1 nonaka struct wzero3ssp_softc *sc; 289 1.1 nonaka uint32_t rv; 290 1.1 nonaka 291 1.1 nonaka KASSERT(wzero3ssp_sc != NULL); 292 1.1 nonaka sc = wzero3ssp_sc; 293 1.1 nonaka 294 1.1 nonaka switch (ic) { 295 1.1 nonaka case WZERO3_SSP_IC_ADS7846: 296 1.1 nonaka /* read result of last command */ 297 1.1 nonaka while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) 298 1.1 nonaka & SSSR_RNE) != SSSR_RNE) 299 1.1 nonaka continue; /* poll */ 300 1.1 nonaka rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 301 1.2 nonaka pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS); 302 1.1 nonaka break; 303 1.4 nonaka case WZERO3_SSP_IC_AK4184_TP: 304 1.3 nonaka /* read result of last command */ 305 1.3 nonaka while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) 306 1.3 nonaka & SSSR_RNE) != SSSR_RNE) 307 1.3 nonaka continue; /* poll */ 308 1.3 nonaka rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 309 1.3 nonaka pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS); 310 1.3 nonaka break; 311 1.2 nonaka case WZERO3_SSP_IC_MAX1233: 312 1.4 nonaka case WZERO3_SSP_IC_AK4184_KEYPAD: 313 1.2 nonaka case WZERO3_SSP_IC_NUM: 314 1.1 nonaka default: 315 1.1 nonaka rv = 0; 316 1.1 nonaka break; 317 1.1 nonaka } 318 1.1 nonaka 319 1.1 nonaka mutex_exit(&sc->sc_mtx); 320 1.1 nonaka 321 1.1 nonaka return rv; 322 1.1 nonaka } 323 1.1 nonaka 324 1.1 nonaka /* 325 1.1 nonaka * Activate one of the chip-select lines, transmit one word value in 326 1.1 nonaka * each direction, and deactivate the chip-select again. 327 1.1 nonaka */ 328 1.1 nonaka uint32_t 329 1.2 nonaka wzero3ssp_ic_send(int ic, uint32_t data, uint32_t data2) 330 1.1 nonaka { 331 1.2 nonaka struct wzero3ssp_softc *sc; 332 1.2 nonaka 333 1.2 nonaka if (wzero3ssp_sc == NULL) { 334 1.2 nonaka aprint_error("%s: not configured\n", __func__); 335 1.2 nonaka return 0; 336 1.2 nonaka } 337 1.2 nonaka sc = wzero3ssp_sc; 338 1.1 nonaka 339 1.1 nonaka switch (ic) { 340 1.1 nonaka case WZERO3_SSP_IC_ADS7846: 341 1.2 nonaka return wzero3ssp_read_ads7846(sc, data); 342 1.2 nonaka case WZERO3_SSP_IC_MAX1233: 343 1.2 nonaka return wzero3ssp_read_max1233(sc, data, data2); 344 1.4 nonaka case WZERO3_SSP_IC_AK4184_TP: 345 1.4 nonaka return wzero3ssp_read_ak4184_tp(sc, data); 346 1.4 nonaka case WZERO3_SSP_IC_AK4184_KEYPAD: 347 1.4 nonaka return wzero3ssp_read_ak4184_keypad(sc, data, data2); 348 1.2 nonaka case WZERO3_SSP_IC_NUM: 349 1.1 nonaka default: 350 1.2 nonaka aprint_error("%s: invalid IC %d\n", __func__, ic); 351 1.1 nonaka return 0; 352 1.1 nonaka } 353 1.1 nonaka } 354 1.1 nonaka 355 1.1 nonaka static uint32_t 356 1.2 nonaka wzero3ssp_read_ads7846(struct wzero3ssp_softc *sc, uint32_t cmd) 357 1.1 nonaka { 358 1.1 nonaka uint32_t rv; 359 1.1 nonaka 360 1.1 nonaka mutex_enter(&sc->sc_mtx); 361 1.1 nonaka 362 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 363 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 364 1.1 nonaka WS007SH_SSCR0_ADS7846); 365 1.1 nonaka 366 1.1 nonaka pxa2x0_gpio_clear_bit(GPIO_WS007SH_ADS7846_CS); 367 1.1 nonaka 368 1.1 nonaka /* send cmd */ 369 1.2 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF)) 370 1.2 nonaka continue; /* poll */ 371 1.1 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd); 372 1.2 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY) 373 1.1 nonaka continue; /* poll */ 374 1.2 nonaka 375 1.2 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE)) 376 1.1 nonaka continue; /* poll */ 377 1.1 nonaka rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 378 1.1 nonaka 379 1.1 nonaka pxa2x0_gpio_set_bit(GPIO_WS007SH_ADS7846_CS); 380 1.1 nonaka 381 1.1 nonaka mutex_exit(&sc->sc_mtx); 382 1.1 nonaka 383 1.1 nonaka return rv; 384 1.1 nonaka } 385 1.2 nonaka 386 1.2 nonaka static uint32_t 387 1.2 nonaka wzero3ssp_read_max1233(struct wzero3ssp_softc *sc, uint32_t cmd, uint32_t data) 388 1.2 nonaka { 389 1.2 nonaka uint32_t rv; 390 1.2 nonaka 391 1.2 nonaka mutex_enter(&sc->sc_mtx); 392 1.2 nonaka 393 1.2 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 394 1.2 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 395 1.2 nonaka WS003SH_SSCR0_MAX1233); 396 1.2 nonaka 397 1.2 nonaka pxa2x0_gpio_set_bit(39/*GPIO_WS003SH_XXX*/); 398 1.2 nonaka pxa2x0_gpio_clear_bit(GPIO_WS003SH_MAX1233_CS); 399 1.2 nonaka 400 1.2 nonaka /* send cmd */ 401 1.2 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF)) 402 1.2 nonaka continue; /* poll */ 403 1.2 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd); 404 1.2 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY) 405 1.2 nonaka continue; /* poll */ 406 1.2 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE)) 407 1.2 nonaka continue; /* poll */ 408 1.2 nonaka (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 409 1.2 nonaka 410 1.2 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF)) 411 1.2 nonaka continue; /* poll */ 412 1.2 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data); 413 1.2 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY) 414 1.2 nonaka continue; /* poll */ 415 1.2 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE)) 416 1.2 nonaka continue; /* poll */ 417 1.2 nonaka rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 418 1.2 nonaka 419 1.2 nonaka pxa2x0_gpio_set_bit(GPIO_WS003SH_MAX1233_CS); 420 1.2 nonaka 421 1.2 nonaka mutex_exit(&sc->sc_mtx); 422 1.2 nonaka 423 1.2 nonaka return rv; 424 1.2 nonaka } 425 1.3 nonaka 426 1.3 nonaka static uint32_t 427 1.4 nonaka wzero3ssp_read_ak4184_tp(struct wzero3ssp_softc *sc, uint32_t cmd) 428 1.3 nonaka { 429 1.3 nonaka uint32_t rv; 430 1.3 nonaka 431 1.3 nonaka mutex_enter(&sc->sc_mtx); 432 1.3 nonaka 433 1.3 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 434 1.3 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 435 1.3 nonaka WS011SH_SSCR0_AK4184_TP); 436 1.3 nonaka 437 1.3 nonaka pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS); 438 1.3 nonaka 439 1.4 nonaka /* clear rx fifo */ 440 1.3 nonaka (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 441 1.3 nonaka 442 1.3 nonaka /* send cmd */ 443 1.3 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF)) 444 1.3 nonaka continue; /* poll */ 445 1.3 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd << 16); 446 1.3 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY) 447 1.3 nonaka continue; /* poll */ 448 1.3 nonaka 449 1.3 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE)) 450 1.3 nonaka continue; /* poll */ 451 1.3 nonaka rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 452 1.3 nonaka 453 1.3 nonaka pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS); 454 1.3 nonaka 455 1.3 nonaka mutex_exit(&sc->sc_mtx); 456 1.3 nonaka 457 1.3 nonaka return rv; 458 1.3 nonaka } 459 1.4 nonaka 460 1.4 nonaka static uint16_t 461 1.4 nonaka wzero3ssp_read_ak4184_keypad(struct wzero3ssp_softc *sc, uint32_t cmd, 462 1.4 nonaka uint32_t data) 463 1.4 nonaka { 464 1.4 nonaka uint16_t rv; 465 1.4 nonaka 466 1.4 nonaka mutex_enter(&sc->sc_mtx); 467 1.4 nonaka 468 1.4 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0); 469 1.4 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 470 1.4 nonaka WS011SH_SSCR0_AK4184_KEYPAD); 471 1.4 nonaka 472 1.4 nonaka pxa2x0_gpio_clear_bit(GPIO_WS011SH_AK4184_CS); 473 1.4 nonaka 474 1.4 nonaka /* clear rx fifo */ 475 1.4 nonaka (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 476 1.4 nonaka 477 1.4 nonaka /* send cmd */ 478 1.4 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF)) 479 1.4 nonaka continue; /* poll */ 480 1.4 nonaka bus_space_write_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR, (uint16_t)cmd); 481 1.4 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY) 482 1.4 nonaka continue; /* poll */ 483 1.4 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE)) 484 1.4 nonaka continue; /* poll */ 485 1.4 nonaka (void) bus_space_read_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 486 1.4 nonaka 487 1.4 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_TNF)) 488 1.4 nonaka continue; /* poll */ 489 1.4 nonaka bus_space_write_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR, (uint16_t)data); 490 1.4 nonaka while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_BUSY) 491 1.4 nonaka continue; /* poll */ 492 1.4 nonaka while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR) & SSSR_RNE)) 493 1.4 nonaka continue; /* poll */ 494 1.4 nonaka rv = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SSP_SSDR); 495 1.4 nonaka 496 1.4 nonaka pxa2x0_gpio_set_bit(GPIO_WS011SH_AK4184_CS); 497 1.4 nonaka 498 1.4 nonaka mutex_exit(&sc->sc_mtx); 499 1.4 nonaka 500 1.4 nonaka return rv; 501 1.4 nonaka } 502