xref: /netbsd/sys/arch/hpcarm/dev/wzero3_ssp.c (revision 0a5ccc74)
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 *
wzero3ssp_lookup(void)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
wzero3ssp_match(device_t parent,cfdata_t cf,void * aux)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
wzero3ssp_attach(device_t parent,device_t self,void * aux)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
wzero3ssp_init(struct wzero3ssp_softc * sc)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
wzero3ssp_resume(device_t dv,const pmf_qual_t * qual)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
wzero3ssp_ic_start(int ic,uint32_t cmd)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
wzero3ssp_ic_stop(int ic)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
wzero3ssp_ic_send(int ic,uint32_t data,uint32_t data2)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
wzero3ssp_read_ads7846(struct wzero3ssp_softc * sc,uint32_t cmd)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
wzero3ssp_read_max1233(struct wzero3ssp_softc * sc,uint32_t cmd,uint32_t data)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
wzero3ssp_read_ak4184_tp(struct wzero3ssp_softc * sc,uint32_t cmd)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
wzero3ssp_read_ak4184_keypad(struct wzero3ssp_softc * sc,uint32_t cmd,uint32_t data)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