Home | History | Annotate | Line # | Download | only in dev
      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 (at) 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