wzero3_ssp.c revision 1.5 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