zssp.c revision 1.13.62.1 1 1.13.62.1 thorpej /* $NetBSD: zssp.c,v 1.13.62.1 2021/03/20 19:33:39 thorpej Exp $ */
2 1.1 ober /* $OpenBSD: zaurus_ssp.c,v 1.6 2005/04/08 21:58:49 uwe Exp $ */
3 1.1 ober
4 1.1 ober /*
5 1.1 ober * Copyright (c) 2005 Uwe Stuehler <uwe (at) bsdx.de>
6 1.1 ober *
7 1.1 ober * Permission to use, copy, modify, and distribute this software for any
8 1.1 ober * purpose with or without fee is hereby granted, provided that the above
9 1.1 ober * copyright notice and this permission notice appear in all copies.
10 1.1 ober *
11 1.1 ober * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 1.1 ober * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 1.1 ober * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 1.1 ober * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 1.1 ober * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 1.1 ober * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 1.1 ober * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 1.1 ober */
19 1.1 ober
20 1.1 ober #include <sys/cdefs.h>
21 1.13.62.1 thorpej __KERNEL_RCSID(0, "$NetBSD: zssp.c,v 1.13.62.1 2021/03/20 19:33:39 thorpej Exp $");
22 1.1 ober
23 1.1 ober #include <sys/param.h>
24 1.1 ober #include <sys/systm.h>
25 1.1 ober #include <sys/device.h>
26 1.11 dyoung #include <sys/bus.h>
27 1.1 ober
28 1.1 ober #include <arm/xscale/pxa2x0reg.h>
29 1.1 ober #include <arm/xscale/pxa2x0var.h>
30 1.1 ober #include <arm/xscale/pxa2x0_gpio.h>
31 1.1 ober
32 1.1 ober #include <zaurus/dev/zsspvar.h>
33 1.1 ober #include <zaurus/zaurus/zaurus_var.h>
34 1.1 ober
35 1.1 ober #define GPIO_ADS7846_CS_C3000 14 /* SSP SFRM */
36 1.1 ober #define GPIO_MAX1111_CS_C3000 20
37 1.1 ober #define GPIO_TG_CS_C3000 53
38 1.13 tsutsui #define GPIO_ADS7846_CS_C860 24 /* SSP SFRM */
39 1.13 tsutsui #define GPIO_MAX1111_CS_C860 20
40 1.13 tsutsui #define GPIO_TG_CS_C860 19
41 1.1 ober
42 1.2 nonaka #define SSCR0_ADS7846_C3000 0x06ab /* 12bit/Microwire/div by 7 */
43 1.2 nonaka #define SSCR0_MAX1111 0x0387
44 1.1 ober #define SSCR0_LZ9JG18 0x01ab
45 1.13 tsutsui #define SSCR0_ADS7846_C860 0x00ab /* 12bit/Microwire/div by 7 */
46 1.13 tsutsui
47 1.13 tsutsui struct zssp_ads7846 {
48 1.13 tsutsui u_int gpio;
49 1.13 tsutsui uint32_t sscr0;
50 1.13 tsutsui };
51 1.13 tsutsui struct zssp_max1111 {
52 1.13 tsutsui u_int gpio;
53 1.13 tsutsui uint32_t sscr0;
54 1.13 tsutsui };
55 1.13 tsutsui struct zssp_lz9jg18 {
56 1.13 tsutsui u_int gpio;
57 1.13 tsutsui uint32_t sscr0;
58 1.13 tsutsui int sclk_pin;
59 1.13 tsutsui int sfrm_pin;
60 1.13 tsutsui int txd_pin;
61 1.13 tsutsui int rxd_pin;
62 1.13 tsutsui };
63 1.1 ober
64 1.1 ober struct zssp_softc {
65 1.4 nonaka device_t sc_dev;
66 1.1 ober bus_space_tag_t sc_iot;
67 1.1 ober bus_space_handle_t sc_ioh;
68 1.13 tsutsui bus_addr_t sc_ssp;
69 1.13 tsutsui struct zssp_ads7846 ads7846;
70 1.13 tsutsui struct zssp_max1111 max1111;
71 1.13 tsutsui struct zssp_lz9jg18 lz9jg18;
72 1.1 ober };
73 1.1 ober
74 1.4 nonaka static int zssp_match(device_t, cfdata_t, void *);
75 1.4 nonaka static void zssp_attach(device_t, device_t, void *);
76 1.12 tsutsui static int zssp_search(device_t, cfdata_t, const int *, void *);
77 1.12 tsutsui static int zssp_print(void *, const char *);
78 1.2 nonaka
79 1.4 nonaka CFATTACH_DECL_NEW(zssp, sizeof(struct zssp_softc),
80 1.2 nonaka zssp_match, zssp_attach, NULL, NULL);
81 1.2 nonaka
82 1.1 ober static void zssp_init(void);
83 1.9 dyoung static bool zssp_resume(device_t dv, const pmf_qual_t *);
84 1.1 ober
85 1.2 nonaka static struct zssp_softc *zssp_sc;
86 1.1 ober
87 1.1 ober static int
88 1.4 nonaka zssp_match(device_t parent, cfdata_t cf, void *aux)
89 1.1 ober {
90 1.1 ober
91 1.2 nonaka if (zssp_sc != NULL)
92 1.2 nonaka return 0;
93 1.1 ober return 1;
94 1.1 ober }
95 1.1 ober
96 1.1 ober static void
97 1.4 nonaka zssp_attach(device_t parent, device_t self, void *aux)
98 1.1 ober {
99 1.4 nonaka struct zssp_softc *sc = device_private(self);
100 1.4 nonaka
101 1.4 nonaka sc->sc_dev = self;
102 1.4 nonaka zssp_sc = sc;
103 1.4 nonaka
104 1.4 nonaka aprint_normal("\n");
105 1.4 nonaka aprint_naive("\n");
106 1.1 ober
107 1.1 ober sc->sc_iot = &pxa2x0_bs_tag;
108 1.13 tsutsui if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
109 1.13 tsutsui sc->sc_ssp = PXA2X0_SSP1_BASE;
110 1.13 tsutsui sc->ads7846.gpio = GPIO_ADS7846_CS_C3000;
111 1.13 tsutsui sc->ads7846.sscr0 = SSCR0_ADS7846_C3000;
112 1.13 tsutsui sc->max1111.gpio = GPIO_MAX1111_CS_C3000;
113 1.13 tsutsui sc->max1111.sscr0 = SSCR0_MAX1111;
114 1.13 tsutsui sc->lz9jg18.gpio = GPIO_TG_CS_C3000;
115 1.13 tsutsui sc->lz9jg18.sscr0 = SSCR0_LZ9JG18;
116 1.13 tsutsui sc->lz9jg18.sclk_pin = 19;
117 1.13 tsutsui sc->lz9jg18.sfrm_pin = 14;
118 1.13 tsutsui sc->lz9jg18.txd_pin = 87;
119 1.13 tsutsui sc->lz9jg18.rxd_pin = 86;
120 1.13 tsutsui } else {
121 1.13 tsutsui sc->sc_ssp = PXA2X0_SSP_BASE;
122 1.13 tsutsui sc->ads7846.gpio = GPIO_ADS7846_CS_C860;
123 1.13 tsutsui sc->ads7846.sscr0 = SSCR0_ADS7846_C860;
124 1.13 tsutsui sc->max1111.gpio = GPIO_MAX1111_CS_C860;
125 1.13 tsutsui sc->max1111.sscr0 = SSCR0_MAX1111;
126 1.13 tsutsui sc->lz9jg18.gpio = GPIO_TG_CS_C860;
127 1.13 tsutsui sc->lz9jg18.sscr0 = SSCR0_LZ9JG18;
128 1.13 tsutsui sc->lz9jg18.sclk_pin = 23;
129 1.13 tsutsui sc->lz9jg18.sfrm_pin = 24;
130 1.13 tsutsui sc->lz9jg18.txd_pin = 25;
131 1.13 tsutsui sc->lz9jg18.rxd_pin = 26;
132 1.13 tsutsui }
133 1.13 tsutsui
134 1.13 tsutsui if (bus_space_map(sc->sc_iot, sc->sc_ssp, PXA2X0_SSP_SIZE,
135 1.1 ober 0, &sc->sc_ioh)) {
136 1.4 nonaka aprint_error_dev(sc->sc_dev, "can't map bus space\n");
137 1.1 ober return;
138 1.1 ober }
139 1.1 ober
140 1.6 nonaka if (!pmf_device_register(sc->sc_dev, NULL, zssp_resume))
141 1.6 nonaka aprint_error_dev(sc->sc_dev,
142 1.6 nonaka "couldn't establish power handler\n");
143 1.1 ober
144 1.1 ober zssp_init();
145 1.12 tsutsui
146 1.12 tsutsui /* Attach all devices */
147 1.13.62.1 thorpej config_search(self, sc,
148 1.13.62.1 thorpej CFARG_SUBMATCH, zssp_search,
149 1.13.62.1 thorpej CFARG_IATTR, "zssp",
150 1.13.62.1 thorpej CFARG_EOL);
151 1.12 tsutsui }
152 1.12 tsutsui
153 1.12 tsutsui static int
154 1.12 tsutsui zssp_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
155 1.12 tsutsui {
156 1.12 tsutsui struct zssp_attach_args aa;
157 1.12 tsutsui
158 1.12 tsutsui aa.zaa_name = cf->cf_name;
159 1.12 tsutsui
160 1.12 tsutsui if (config_match(parent, cf, &aa))
161 1.12 tsutsui config_attach(parent, cf, &aa, zssp_print);
162 1.12 tsutsui
163 1.12 tsutsui return 0;
164 1.12 tsutsui }
165 1.12 tsutsui
166 1.12 tsutsui static int
167 1.12 tsutsui zssp_print(void *aux, const char *name)
168 1.12 tsutsui {
169 1.12 tsutsui
170 1.12 tsutsui return UNCONF;
171 1.1 ober }
172 1.1 ober
173 1.1 ober /*
174 1.1 ober * Initialize the dedicated SSP unit and disable all chip selects.
175 1.1 ober * This function is called with interrupts disabled.
176 1.1 ober */
177 1.1 ober static void
178 1.1 ober zssp_init(void)
179 1.1 ober {
180 1.1 ober struct zssp_softc *sc;
181 1.1 ober
182 1.12 tsutsui if (__predict_false(zssp_sc == NULL)) {
183 1.12 tsutsui aprint_error("%s: not configured.\n", __func__);
184 1.12 tsutsui return;
185 1.12 tsutsui }
186 1.2 nonaka sc = zssp_sc;
187 1.1 ober
188 1.1 ober pxa2x0_clkman_config(CKEN_SSP, 1);
189 1.1 ober
190 1.13 tsutsui bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, sc->lz9jg18.sscr0);
191 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);
192 1.1 ober
193 1.13 tsutsui pxa2x0_gpio_set_function(sc->ads7846.gpio, GPIO_OUT|GPIO_SET);
194 1.13 tsutsui pxa2x0_gpio_set_function(sc->max1111.gpio, GPIO_OUT|GPIO_SET);
195 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.gpio, GPIO_OUT|GPIO_SET);
196 1.1 ober }
197 1.1 ober
198 1.6 nonaka static bool
199 1.9 dyoung zssp_resume(device_t dv, const pmf_qual_t *qual)
200 1.1 ober {
201 1.1 ober int s;
202 1.1 ober
203 1.6 nonaka s = splhigh();
204 1.6 nonaka zssp_init();
205 1.6 nonaka splx(s);
206 1.6 nonaka
207 1.6 nonaka return true;
208 1.1 ober }
209 1.1 ober
210 1.1 ober /*
211 1.1 ober * Transmit a single data word to one of the ICs, keep the chip selected
212 1.1 ober * afterwards, and don't wait for data to be returned in SSDR. Interrupts
213 1.1 ober * must be held off until zssp_ic_stop() gets called.
214 1.1 ober */
215 1.1 ober void
216 1.1 ober zssp_ic_start(int ic, uint32_t data)
217 1.1 ober {
218 1.1 ober struct zssp_softc *sc;
219 1.1 ober
220 1.12 tsutsui if (__predict_false(zssp_sc == NULL)) {
221 1.12 tsutsui aprint_error("%s: not configured.\n", __func__);
222 1.12 tsutsui return;
223 1.12 tsutsui }
224 1.2 nonaka sc = zssp_sc;
225 1.1 ober
226 1.1 ober /* disable other ICs */
227 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
228 1.1 ober if (ic != ZSSP_IC_ADS7846)
229 1.13 tsutsui pxa2x0_gpio_set_bit(sc->ads7846.gpio);
230 1.1 ober if (ic != ZSSP_IC_LZ9JG18)
231 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.gpio);
232 1.1 ober if (ic != ZSSP_IC_MAX1111)
233 1.13 tsutsui pxa2x0_gpio_set_bit(sc->max1111.gpio);
234 1.1 ober
235 1.1 ober /* activate the chosen one */
236 1.1 ober switch (ic) {
237 1.1 ober case ZSSP_IC_ADS7846:
238 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0,
239 1.13 tsutsui sc->ads7846.sscr0);
240 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->ads7846.gpio);
241 1.13 tsutsui delay(1); /* ADS7846 Tcss = 100ns */
242 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data);
243 1.1 ober while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
244 1.1 ober & SSSR_TNF) != SSSR_TNF)
245 1.1 ober continue; /* poll */
246 1.1 ober break;
247 1.1 ober case ZSSP_IC_LZ9JG18:
248 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->lz9jg18.gpio);
249 1.1 ober break;
250 1.1 ober case ZSSP_IC_MAX1111:
251 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->max1111.gpio);
252 1.1 ober break;
253 1.1 ober }
254 1.1 ober }
255 1.1 ober
256 1.1 ober /*
257 1.1 ober * Read the last value from SSDR and deactivate all chip-selects.
258 1.1 ober */
259 1.1 ober uint32_t
260 1.1 ober zssp_ic_stop(int ic)
261 1.1 ober {
262 1.1 ober struct zssp_softc *sc;
263 1.1 ober uint32_t rv;
264 1.1 ober
265 1.12 tsutsui if (__predict_false(zssp_sc == NULL)) {
266 1.12 tsutsui aprint_error("%s: not configured.\n", __func__);
267 1.12 tsutsui return 0;
268 1.12 tsutsui }
269 1.2 nonaka sc = zssp_sc;
270 1.1 ober
271 1.1 ober switch (ic) {
272 1.1 ober case ZSSP_IC_ADS7846:
273 1.1 ober /* read result of last command */
274 1.1 ober while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
275 1.1 ober & SSSR_RNE) != SSSR_RNE)
276 1.1 ober continue; /* poll */
277 1.1 ober rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
278 1.1 ober break;
279 1.1 ober case ZSSP_IC_LZ9JG18:
280 1.1 ober case ZSSP_IC_MAX1111:
281 1.1 ober /* last value received is irrelevant or undefined */
282 1.1 ober default:
283 1.1 ober rv = 0;
284 1.1 ober break;
285 1.1 ober }
286 1.1 ober
287 1.13 tsutsui pxa2x0_gpio_set_bit(sc->ads7846.gpio);
288 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.gpio);
289 1.13 tsutsui pxa2x0_gpio_set_bit(sc->max1111.gpio);
290 1.1 ober
291 1.1 ober return rv;
292 1.1 ober }
293 1.1 ober
294 1.1 ober /*
295 1.1 ober * Activate one of the chip-select lines, transmit one word value in
296 1.1 ober * each direction, and deactivate the chip-select again.
297 1.1 ober */
298 1.1 ober uint32_t
299 1.1 ober zssp_ic_send(int ic, uint32_t data)
300 1.1 ober {
301 1.1 ober
302 1.1 ober switch (ic) {
303 1.1 ober case ZSSP_IC_MAX1111:
304 1.1 ober return (zssp_read_max1111(data));
305 1.1 ober case ZSSP_IC_ADS7846:
306 1.1 ober return (zssp_read_ads7846(data));
307 1.1 ober case ZSSP_IC_LZ9JG18:
308 1.1 ober zssp_write_lz9jg18(data);
309 1.1 ober return 0;
310 1.1 ober default:
311 1.5 nonaka aprint_error("zssp: zssp_ic_send: invalid IC %d\n", ic);
312 1.1 ober return 0;
313 1.1 ober }
314 1.1 ober }
315 1.1 ober
316 1.1 ober int
317 1.1 ober zssp_read_max1111(uint32_t cmd)
318 1.1 ober {
319 1.1 ober struct zssp_softc *sc;
320 1.7 nonaka int data[3];
321 1.7 nonaka int voltage[3]; /* voltage[0]: dummy */
322 1.2 nonaka int i;
323 1.2 nonaka int s;
324 1.1 ober
325 1.12 tsutsui if (__predict_false(zssp_sc == NULL)) {
326 1.12 tsutsui aprint_error("%s: not configured.\n", __func__);
327 1.12 tsutsui return 0;
328 1.12 tsutsui }
329 1.2 nonaka sc = zssp_sc;
330 1.1 ober
331 1.1 ober s = splhigh();
332 1.1 ober
333 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
334 1.13 tsutsui bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, sc->max1111.sscr0);
335 1.1 ober
336 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.gpio);
337 1.13 tsutsui pxa2x0_gpio_set_bit(sc->ads7846.gpio);
338 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->max1111.gpio);
339 1.1 ober
340 1.1 ober delay(1);
341 1.1 ober
342 1.7 nonaka memset(data, 0, sizeof(data));
343 1.7 nonaka data[0] = cmd;
344 1.7 nonaka for (i = 0; i < __arraycount(data); i++) {
345 1.7 nonaka bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, data[i]);
346 1.1 ober while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
347 1.1 ober & SSSR_TNF) != SSSR_TNF)
348 1.1 ober continue; /* poll */
349 1.7 nonaka /* XXX is this delay necessary? */
350 1.1 ober delay(1);
351 1.1 ober while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
352 1.1 ober & SSSR_RNE) != SSSR_RNE)
353 1.1 ober continue; /* poll */
354 1.1 ober voltage[i] = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
355 1.1 ober SSP_SSDR);
356 1.1 ober }
357 1.1 ober
358 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.gpio);
359 1.13 tsutsui pxa2x0_gpio_set_bit(sc->ads7846.gpio);
360 1.13 tsutsui pxa2x0_gpio_set_bit(sc->max1111.gpio);
361 1.1 ober
362 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
363 1.1 ober
364 1.1 ober splx(s);
365 1.1 ober
366 1.1 ober /* XXX no idea what this means, but it's what Linux would do. */
367 1.7 nonaka if ((voltage[1] & 0xc0) != 0 || (voltage[2] & 0x3f) != 0)
368 1.7 nonaka return -1;
369 1.7 nonaka return ((voltage[1] << 2) & 0xfc) | ((voltage[2] >> 6) & 0x03);
370 1.1 ober }
371 1.1 ober
372 1.1 ober /* XXX - only does CS_ADS7846 */
373 1.1 ober uint32_t
374 1.1 ober zssp_read_ads7846(uint32_t cmd)
375 1.1 ober {
376 1.1 ober struct zssp_softc *sc;
377 1.2 nonaka uint32_t val;
378 1.1 ober int s;
379 1.1 ober
380 1.12 tsutsui if (__predict_false(zssp_sc == NULL)) {
381 1.12 tsutsui aprint_error("%s: not configured\n", __func__);
382 1.1 ober return 0;
383 1.1 ober }
384 1.2 nonaka sc = zssp_sc;
385 1.1 ober
386 1.2 nonaka s = splhigh();
387 1.1 ober
388 1.13 tsutsui bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
389 1.13 tsutsui bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, sc->ads7846.sscr0);
390 1.1 ober
391 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.gpio);
392 1.13 tsutsui pxa2x0_gpio_set_bit(sc->max1111.gpio);
393 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->ads7846.gpio);
394 1.13 tsutsui delay(1); /* ADS7846 Tcss = 100ns */
395 1.1 ober
396 1.1 ober bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
397 1.1 ober
398 1.1 ober while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
399 1.1 ober & SSSR_TNF) != SSSR_TNF)
400 1.1 ober continue; /* poll */
401 1.1 ober
402 1.1 ober delay(1);
403 1.1 ober
404 1.1 ober while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
405 1.1 ober & SSSR_RNE) != SSSR_RNE)
406 1.1 ober continue; /* poll */
407 1.1 ober
408 1.1 ober val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
409 1.1 ober
410 1.13 tsutsui pxa2x0_gpio_set_bit(sc->ads7846.gpio);
411 1.1 ober
412 1.1 ober splx(s);
413 1.1 ober
414 1.1 ober return val;
415 1.1 ober }
416 1.1 ober
417 1.1 ober void
418 1.1 ober zssp_write_lz9jg18(uint32_t data)
419 1.1 ober {
420 1.13 tsutsui struct zssp_softc *sc;
421 1.13 tsutsui int sclk_fn;
422 1.13 tsutsui int sfrm_fn;
423 1.13 tsutsui int txd_fn;
424 1.13 tsutsui int rxd_fn;
425 1.1 ober int i;
426 1.2 nonaka int s;
427 1.1 ober
428 1.13 tsutsui KASSERT(zssp_sc != NULL);
429 1.13 tsutsui sc = zssp_sc;
430 1.13 tsutsui
431 1.1 ober /* XXX this creates a DAC command from a backlight duty value. */
432 1.1 ober data = 0x40 | (data & 0x1f);
433 1.1 ober
434 1.1 ober s = splhigh();
435 1.1 ober
436 1.13 tsutsui sclk_fn = pxa2x0_gpio_get_function(sc->lz9jg18.sclk_pin);
437 1.13 tsutsui sfrm_fn = pxa2x0_gpio_get_function(sc->lz9jg18.sfrm_pin);
438 1.13 tsutsui txd_fn = pxa2x0_gpio_get_function(sc->lz9jg18.txd_pin);
439 1.13 tsutsui rxd_fn = pxa2x0_gpio_get_function(sc->lz9jg18.rxd_pin);
440 1.13 tsutsui
441 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.sfrm_pin, GPIO_OUT | GPIO_SET);
442 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.sclk_pin, GPIO_OUT | GPIO_CLR);
443 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.txd_pin, GPIO_OUT | GPIO_CLR);
444 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.rxd_pin, GPIO_IN);
445 1.13 tsutsui
446 1.13 tsutsui pxa2x0_gpio_set_bit(sc->max1111.gpio);
447 1.13 tsutsui pxa2x0_gpio_set_bit(sc->ads7846.gpio);
448 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->lz9jg18.gpio);
449 1.1 ober
450 1.1 ober delay(10);
451 1.1 ober
452 1.1 ober for (i = 0; i < 8; i++) {
453 1.1 ober if (data & 0x80)
454 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.txd_pin);
455 1.1 ober else
456 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->lz9jg18.txd_pin);
457 1.1 ober delay(10);
458 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.sclk_pin);
459 1.1 ober delay(10);
460 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->lz9jg18.sclk_pin);
461 1.1 ober delay(10);
462 1.1 ober data <<= 1;
463 1.1 ober }
464 1.1 ober
465 1.13 tsutsui pxa2x0_gpio_clear_bit(sc->lz9jg18.txd_pin);
466 1.13 tsutsui pxa2x0_gpio_set_bit(sc->lz9jg18.gpio);
467 1.1 ober
468 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.sclk_pin, sclk_fn);
469 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.sfrm_pin, sfrm_fn);
470 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.txd_pin, txd_fn);
471 1.13 tsutsui pxa2x0_gpio_set_function(sc->lz9jg18.rxd_pin, rxd_fn);
472 1.1 ober
473 1.1 ober splx(s);
474 1.1 ober }
475