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