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