ucb1200.c revision 1.1 1 1.1 uch /* $NetBSD: ucb1200.c,v 1.1 2000/01/08 21:07:04 uch Exp $ */
2 1.1 uch
3 1.1 uch /*
4 1.1 uch * Copyright (c) 2000, by UCHIYAMA Yasushi
5 1.1 uch * All rights reserved.
6 1.1 uch *
7 1.1 uch * Redistribution and use in source and binary forms, with or without
8 1.1 uch * modification, are permitted provided that the following conditions
9 1.1 uch * are met:
10 1.1 uch * 1. Redistributions of source code must retain the above copyright
11 1.1 uch * notice, this list of conditions and the following disclaimer.
12 1.1 uch * 2. The name of the developer may NOT be used to endorse or promote products
13 1.1 uch * derived from this software without specific prior written permission.
14 1.1 uch *
15 1.1 uch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 1.1 uch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 1.1 uch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 1.1 uch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.1 uch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.1 uch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 1.1 uch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.1 uch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.1 uch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.1 uch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.1 uch * SUCH DAMAGE.
26 1.1 uch *
27 1.1 uch */
28 1.1 uch
29 1.1 uch /*
30 1.1 uch * Device driver for PHILIPS UCB1200 Advanced modem/audio analog front-end
31 1.1 uch */
32 1.1 uch #define UCB1200DEBUG
33 1.1 uch
34 1.1 uch #include "opt_tx39_debug.h"
35 1.1 uch #include "opt_use_poll.h"
36 1.1 uch
37 1.1 uch #include <sys/param.h>
38 1.1 uch #include <sys/systm.h>
39 1.1 uch #include <sys/device.h>
40 1.1 uch
41 1.1 uch #include <machine/bus.h>
42 1.1 uch #include <machine/intr.h>
43 1.1 uch #include <machine/bootinfo.h> /* bootinfo */
44 1.1 uch
45 1.1 uch #include <dev/wscons/wsconsio.h>
46 1.1 uch #include <dev/wscons/wsmousevar.h>
47 1.1 uch
48 1.1 uch #include <hpcmips/tx/tx39var.h>
49 1.1 uch #include <hpcmips/tx/tx39sibvar.h>
50 1.1 uch #include <hpcmips/tx/tx39sibreg.h>
51 1.1 uch #include <hpcmips/tx/tx39icureg.h>
52 1.1 uch
53 1.1 uch #include <hpcmips/tx/tx3912videovar.h> /* debug */
54 1.1 uch
55 1.1 uch #include <hpcmips/dev/ucb1200var.h>
56 1.1 uch #include <hpcmips/dev/ucb1200reg.h>
57 1.1 uch
58 1.1 uch #ifdef UCB1200DEBUG
59 1.1 uch int ucb1200_debug = 1;
60 1.1 uch #define DPRINTF(arg) if (ucb1200_debug) printf arg;
61 1.1 uch #define DPRINTFN(n, arg) if (ucb1200_debug > (n)) printf arg;
62 1.1 uch #else
63 1.1 uch #define DPRINTF(arg)
64 1.1 uch #endif
65 1.1 uch
66 1.1 uch int ucb1200_match __P((struct device*, struct cfdata*, void*));
67 1.1 uch void ucb1200_attach __P((struct device*, struct device*, void*));
68 1.1 uch int ucb1200_idcheck __P((bus_space_tag_t));
69 1.1 uch
70 1.1 uch void ucb1200_dump __P((struct ucb1200_softc*));
71 1.1 uch int ucb1200_sibintr __P((void*));
72 1.1 uch int ucb1200_poll __P((void*));
73 1.1 uch
74 1.1 uch int ucb1200_adc_async __P((void*));
75 1.1 uch int ucb1200_input __P((struct ucb1200_softc*));
76 1.1 uch
77 1.1 uch void ucb1200_intr_ack_sync __P((struct ucb1200_softc*));
78 1.1 uch int ucb1200_adc_sync __P((struct ucb1200_softc*, int, int*));
79 1.1 uch
80 1.1 uch int ucb_ts_enable __P((void*));
81 1.1 uch int ucb_ts_ioctl __P((void*, u_long, caddr_t, int, struct proc*));
82 1.1 uch void ucb_ts_disable __P((void*));
83 1.1 uch
84 1.1 uch /* mra is defined in mra.c */
85 1.1 uch int mra_Y_AX1_BX2_C __P((int *y, int ys, int *x1, int x1s, int *x2, int x2s,
86 1.1 uch int n, int scale, int *a, int *b, int *c));
87 1.1 uch
88 1.1 uch struct cfattach ucb_ca = {
89 1.1 uch sizeof(struct ucb1200_softc), ucb1200_match, ucb1200_attach
90 1.1 uch };
91 1.1 uch
92 1.1 uch const struct wsmouse_accessops ucb_ts_accessops = {
93 1.1 uch ucb_ts_enable,
94 1.1 uch ucb_ts_ioctl,
95 1.1 uch ucb_ts_disable,
96 1.1 uch };
97 1.1 uch
98 1.1 uch /*
99 1.1 uch * XXX currently no calibration method. this is temporary hack.
100 1.1 uch */
101 1.1 uch #include <machine/platid.h>
102 1.1 uch #define NSAMPLE 5
103 1.1 uch
104 1.1 uch struct calibration_sample *calibration_sample_lookup __P((void));
105 1.1 uch int ucb1200_tp_calibration __P((struct ucb1200_softc*));
106 1.1 uch
107 1.1 uch struct calibration_sample {
108 1.1 uch int cs_xraw, cs_yraw, cs_x, cs_y;
109 1.1 uch };
110 1.1 uch
111 1.1 uch struct calibration_sample_table {
112 1.1 uch platid_t cst_platform;
113 1.1 uch struct calibration_sample cst_sample[NSAMPLE];
114 1.1 uch } calibration_sample_table[] = {
115 1.1 uch {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_8XX}}, /* uch machine */
116 1.1 uch {{ 507, 510, 320, 120 },
117 1.1 uch { 898, 757, 40, 40 },
118 1.1 uch { 900, 255, 40, 200 },
119 1.1 uch { 109, 249, 600, 200 },
120 1.1 uch { 110, 753, 600, 40 }}},
121 1.1 uch
122 1.1 uch {{{PLATID_WILD, PLATID_MACH_COMPAQ_C_2010}}, /* uch machine */
123 1.1 uch {{ 506, 487, 320, 120 },
124 1.1 uch { 880, 250, 40, 40 },
125 1.1 uch { 880, 718, 40, 200 },
126 1.1 uch { 140, 726, 600, 200 },
127 1.1 uch { 137, 250, 600, 40 }}},
128 1.1 uch
129 1.1 uch {{{PLATID_WILD, PLATID_MACH_SHARP_MOBILON_HC4100}}, /* uch machine */
130 1.1 uch {{ 497, 501, 320, 120 },
131 1.1 uch { 752, 893, 40, 40 },
132 1.1 uch { 242, 891, 40, 200 },
133 1.1 uch { 241, 115, 600, 200 },
134 1.1 uch { 747, 101, 600, 40 }}},
135 1.1 uch
136 1.1 uch {{{PLATID_UNKNOWN, PLATID_UNKNOWN}},
137 1.1 uch {{0, 0, 0, 0},
138 1.1 uch {0, 0, 0, 0},
139 1.1 uch {0, 0, 0, 0},
140 1.1 uch {0, 0, 0, 0},
141 1.1 uch {0, 0, 0, 0}}},
142 1.1 uch };
143 1.1 uch
144 1.1 uch struct calibration_sample*
145 1.1 uch calibration_sample_lookup()
146 1.1 uch {
147 1.1 uch struct calibration_sample_table *tab;
148 1.1 uch platid_mask_t mask;
149 1.1 uch
150 1.1 uch for (tab = calibration_sample_table;
151 1.1 uch tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) {
152 1.1 uch
153 1.1 uch mask = PLATID_DEREF(&tab->cst_platform);
154 1.1 uch
155 1.1 uch if (platid_match(&platid, &mask)) {
156 1.1 uch return tab->cst_sample;
157 1.1 uch }
158 1.1 uch }
159 1.1 uch
160 1.1 uch return 0;
161 1.1 uch }
162 1.1 uch
163 1.1 uch int
164 1.1 uch ucb1200_tp_calibration(sc)
165 1.1 uch struct ucb1200_softc *sc;
166 1.1 uch {
167 1.1 uch #define SCALE (1024*1024)
168 1.1 uch struct calibration_sample *cs;
169 1.1 uch int s, n;
170 1.1 uch
171 1.1 uch tx3912video_calibration_pattern();
172 1.1 uch
173 1.1 uch sc->sc_prmxs = bootinfo->fb_width;
174 1.1 uch sc->sc_prmys = bootinfo->fb_height;
175 1.1 uch sc->sc_maxx = bootinfo->fb_width - 1;
176 1.1 uch sc->sc_maxy = bootinfo->fb_height - 1;
177 1.1 uch
178 1.1 uch if (!(cs = calibration_sample_lookup())) {
179 1.1 uch printf(": no calibration data\n");
180 1.1 uch return 1;
181 1.1 uch }
182 1.1 uch
183 1.1 uch s = sizeof(struct calibration_sample);
184 1.1 uch n = NSAMPLE;
185 1.1 uch
186 1.1 uch if (mra_Y_AX1_BX2_C(&cs->cs_x, s, &cs->cs_xraw, s, &cs->cs_yraw, s,
187 1.1 uch n, SCALE, &sc->sc_prmax, &sc->sc_prmbx,
188 1.1 uch &sc->sc_prmcx) ||
189 1.1 uch mra_Y_AX1_BX2_C(&cs->cs_y, s, &cs->cs_xraw, s, &cs->cs_yraw, s,
190 1.1 uch n, SCALE, &sc->sc_prmay,
191 1.1 uch &sc->sc_prmby, &sc->sc_prmcy)) {
192 1.1 uch printf(": MRA error");
193 1.1 uch
194 1.1 uch return 1;
195 1.1 uch } else {
196 1.1 uch DPRINTF((": Ax=%d Bx=%d Cx=%d",
197 1.1 uch sc->sc_prmax, sc->sc_prmbx, sc->sc_prmcx));
198 1.1 uch DPRINTF((" Ay=%d By=%d Cy=%d\n",
199 1.1 uch sc->sc_prmay, sc->sc_prmby, sc->sc_prmcy));
200 1.1 uch }
201 1.1 uch
202 1.1 uch return 0;
203 1.1 uch }
204 1.1 uch
205 1.1 uch int
206 1.1 uch ucb1200_match(parent, cf, aux)
207 1.1 uch struct device *parent;
208 1.1 uch struct cfdata *cf;
209 1.1 uch void *aux;
210 1.1 uch {
211 1.1 uch struct txsib_attach_args *sa = aux;
212 1.1 uch
213 1.1 uch if (sa->sa_slot != 0) /* UCB1200 must be subframe 0 */
214 1.1 uch return 0;
215 1.1 uch
216 1.1 uch return txsibsf0_reg_read(sa->sa_tc, UCB1200_ID_REG) == UCB1200_ID
217 1.1 uch ? 1 : 0;
218 1.1 uch }
219 1.1 uch
220 1.1 uch void
221 1.1 uch ucb1200_attach(parent, self, aux)
222 1.1 uch struct device *parent;
223 1.1 uch struct device *self;
224 1.1 uch void *aux;
225 1.1 uch {
226 1.1 uch struct txsib_attach_args *sa = aux;
227 1.1 uch struct ucb1200_softc *sc = (void*)self;
228 1.1 uch struct wsmousedev_attach_args wsmaa;
229 1.1 uch
230 1.1 uch sc->sc_tc = sa->sa_tc;
231 1.1 uch sc->sc_parent = parent;
232 1.1 uch
233 1.1 uch tx_intr_establish(sc->sc_tc,
234 1.1 uch MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT),
235 1.1 uch IST_EDGE, IPL_TTY, ucb1200_sibintr, sc);
236 1.1 uch
237 1.1 uch ucb1200_tp_calibration(sc);
238 1.1 uch #ifdef UCB1200DEBUG
239 1.1 uch ucb1200_dump(sc);
240 1.1 uch #endif
241 1.1 uch
242 1.1 uch wsmaa.accessops = &ucb_ts_accessops;
243 1.1 uch wsmaa.accesscookie = sc;
244 1.1 uch
245 1.1 uch printf("\n");
246 1.1 uch
247 1.1 uch /*
248 1.1 uch * attach the wsmouse
249 1.1 uch */
250 1.1 uch sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
251 1.1 uch }
252 1.1 uch
253 1.1 uch int
254 1.1 uch ucb1200_poll(arg)
255 1.1 uch void *arg;
256 1.1 uch {
257 1.1 uch struct ucb1200_softc *sc = arg;
258 1.1 uch
259 1.1 uch if (sc->sm_state != UCBADC_IDLE) {
260 1.1 uch printf("%s: %s busy\n", sc->sc_dev.dv_xname,
261 1.1 uch sc->sc_parent->dv_xname);
262 1.1 uch return POLL_CONT;
263 1.1 uch }
264 1.1 uch
265 1.1 uch if (sc->sc_polling_finish) {
266 1.1 uch sc->sc_polling_finish = 0;
267 1.1 uch return POLL_END;
268 1.1 uch }
269 1.1 uch
270 1.1 uch /* execute A-D converter */
271 1.1 uch sc->sm_state = UCBADC_ADC_INIT;
272 1.1 uch ucb1200_adc_async(sc);
273 1.1 uch
274 1.1 uch return POLL_CONT;
275 1.1 uch }
276 1.1 uch
277 1.1 uch #define REGWRITE(addr, reg, ret) ( \
278 1.1 uch sc->sm_addr = (addr), \
279 1.1 uch sc->sm_reg = (reg), \
280 1.1 uch sc->sm_returnstate = (ret),\
281 1.1 uch sc->sm_state = UCBADC_REGWRITE)
282 1.1 uch #define REGREAD(addr, ret) ( \
283 1.1 uch sc->sm_addr = (addr), \
284 1.1 uch sc->sm_returnstate = (ret), \
285 1.1 uch sc->sm_state = UCBADC_REGREAD)
286 1.1 uch
287 1.1 uch int
288 1.1 uch ucb1200_adc_async(arg)
289 1.1 uch void *arg;
290 1.1 uch {
291 1.1 uch struct ucb1200_softc *sc = arg;
292 1.1 uch tx_chipset_tag_t tc = sc->sc_tc;
293 1.1 uch txreg_t reg;
294 1.1 uch u_int16_t reg16;
295 1.1 uch
296 1.1 uch DPRINTFN(9, ("state: %d\n", sc->sm_state));
297 1.1 uch
298 1.1 uch switch (sc->sm_state) {
299 1.1 uch default:
300 1.1 uch panic("ucb1200_adc: invalid state %d", sc->sm_state);
301 1.1 uch /* NOTREACHED */
302 1.1 uch break;
303 1.1 uch
304 1.1 uch case UCBADC_IDLE:
305 1.1 uch /* nothing to do */
306 1.1 uch break;
307 1.1 uch
308 1.1 uch case UCBADC_ADC_INIT:
309 1.1 uch sc->sc_polling++;
310 1.1 uch sc->sc_stat = UCBTS_STAT_DRAG;
311 1.1 uch /* enable heart beat of this state machine */
312 1.1 uch sc->sm_ih = tx_intr_establish(
313 1.1 uch tc,
314 1.1 uch MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
315 1.1 uch IST_EDGE, IPL_TTY, ucb1200_adc_async, sc);
316 1.1 uch
317 1.1 uch sc->sm_state = UCBADC_MEASUMENT_INIT;
318 1.1 uch break;
319 1.1 uch
320 1.1 uch case UCBADC_ADC_FINI:
321 1.1 uch /* disable heart beat of this state machine */
322 1.1 uch tx_intr_disestablish(tc, sc->sm_ih);
323 1.1 uch sc->sm_state = UCBADC_IDLE;
324 1.1 uch break;
325 1.1 uch
326 1.1 uch case UCBADC_MEASUMENT_INIT:
327 1.1 uch switch (sc->sm_measurement) {
328 1.1 uch default:
329 1.1 uch panic("unknown measurement spec.");
330 1.1 uch /* NOTREACHED */
331 1.1 uch break;
332 1.1 uch case UCBADC_MEASUREMENT_X:
333 1.1 uch REGWRITE(UCB1200_TSCTRL_REG,
334 1.1 uch UCB1200_TSCTRL_XPOSITION,
335 1.1 uch UCBADC_ADC_ENABLE);
336 1.1 uch break;
337 1.1 uch case UCBADC_MEASUREMENT_Y:
338 1.1 uch REGWRITE(UCB1200_TSCTRL_REG,
339 1.1 uch UCB1200_TSCTRL_YPOSITION,
340 1.1 uch UCBADC_ADC_ENABLE);
341 1.1 uch break;
342 1.1 uch case UCBADC_MEASUREMENT_PRESSURE:
343 1.1 uch REGWRITE(UCB1200_TSCTRL_REG,
344 1.1 uch UCB1200_TSCTRL_PRESSURE,
345 1.1 uch UCBADC_ADC_ENABLE);
346 1.1 uch break;
347 1.1 uch }
348 1.1 uch break;
349 1.1 uch
350 1.1 uch case UCBADC_MEASUMENT_FINI:
351 1.1 uch switch (sc->sm_measurement) {
352 1.1 uch case UCBADC_MEASUREMENT_X:
353 1.1 uch sc->sm_measurement = UCBADC_MEASUREMENT_Y;
354 1.1 uch sc->sm_state = UCBADC_MEASUMENT_INIT;
355 1.1 uch break;
356 1.1 uch case UCBADC_MEASUREMENT_Y:
357 1.1 uch sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE;
358 1.1 uch sc->sm_state = UCBADC_MEASUMENT_INIT;
359 1.1 uch break;
360 1.1 uch case UCBADC_MEASUREMENT_PRESSURE:
361 1.1 uch sc->sm_measurement = UCBADC_MEASUREMENT_X;
362 1.1 uch /* measument complete. pass down to wsmouse_input */
363 1.1 uch sc->sm_state = UCBADC_ADC_INPUT;
364 1.1 uch break;
365 1.1 uch }
366 1.1 uch break;
367 1.1 uch
368 1.1 uch case UCBADC_ADC_ENABLE:
369 1.1 uch switch (sc->sm_measurement) {
370 1.1 uch case UCBADC_MEASUREMENT_PRESSURE:
371 1.1 uch /* FALLTHROUGH */
372 1.1 uch case UCBADC_MEASUREMENT_X:
373 1.1 uch sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
374 1.1 uch UCB1200_ADCCTRL_ENABLE,
375 1.1 uch UCB1200_ADCCTRL_INPUT_TSPX);
376 1.1 uch REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
377 1.1 uch UCBADC_ADC_START0);
378 1.1 uch break;
379 1.1 uch case UCBADC_MEASUREMENT_Y:
380 1.1 uch sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
381 1.1 uch UCB1200_ADCCTRL_ENABLE,
382 1.1 uch UCB1200_ADCCTRL_INPUT_TSPY);
383 1.1 uch REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
384 1.1 uch UCBADC_ADC_START0);
385 1.1 uch break;
386 1.1 uch }
387 1.1 uch break;
388 1.1 uch
389 1.1 uch case UCBADC_ADC_START0:
390 1.1 uch REGWRITE(UCB1200_ADCCTRL_REG,
391 1.1 uch sc->sm_tmpreg | UCB1200_ADCCTRL_START,
392 1.1 uch UCBADC_ADC_START1);
393 1.1 uch break;
394 1.1 uch
395 1.1 uch case UCBADC_ADC_START1:
396 1.1 uch REGWRITE(UCB1200_ADCCTRL_REG,
397 1.1 uch sc->sm_tmpreg,
398 1.1 uch UCBADC_ADC_DATAREAD);
399 1.1 uch sc->sm_retry = 10;
400 1.1 uch break;
401 1.1 uch
402 1.1 uch case UCBADC_ADC_DATAREAD:
403 1.1 uch REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT);
404 1.1 uch break;
405 1.1 uch
406 1.1 uch case UCBADC_ADC_DATAREAD_WAIT:
407 1.1 uch reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg);
408 1.1 uch if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) &&
409 1.1 uch --sc->sm_retry > 0) {
410 1.1 uch sc->sm_state = UCBADC_ADC_DATAREAD;
411 1.1 uch } else {
412 1.1 uch if (sc->sm_retry <= 0) {
413 1.1 uch printf("dataread failed\n");
414 1.1 uch sc->sm_state = UCBADC_ADC_FINI;
415 1.1 uch break;
416 1.1 uch }
417 1.1 uch
418 1.1 uch switch (sc->sm_measurement) {
419 1.1 uch case UCBADC_MEASUREMENT_X:
420 1.1 uch sc->sc_x = UCB1200_ADCDATA(reg16);
421 1.1 uch DPRINTFN(9, ("x=%d\n", sc->sc_x));
422 1.1 uch break;
423 1.1 uch case UCBADC_MEASUREMENT_Y:
424 1.1 uch sc->sc_y = UCB1200_ADCDATA(reg16);
425 1.1 uch DPRINTFN(9, ("y=%d\n", sc->sc_y));
426 1.1 uch break;
427 1.1 uch case UCBADC_MEASUREMENT_PRESSURE:
428 1.1 uch sc->sc_p = UCB1200_ADCDATA(reg16);
429 1.1 uch DPRINTFN(9, ("p=%d\n", sc->sc_p));
430 1.1 uch break;
431 1.1 uch }
432 1.1 uch
433 1.1 uch sc->sm_state = UCBADC_ADC_DISABLE;
434 1.1 uch }
435 1.1 uch
436 1.1 uch break;
437 1.1 uch
438 1.1 uch case UCBADC_ADC_DISABLE:
439 1.1 uch REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE);
440 1.1 uch
441 1.1 uch break;
442 1.1 uch case UCBADC_ADC_INTRMODE:
443 1.1 uch REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT,
444 1.1 uch UCBADC_MEASUMENT_FINI);
445 1.1 uch break;
446 1.1 uch
447 1.1 uch case UCBADC_ADC_INPUT:
448 1.1 uch if (ucb1200_input(sc) == 0)
449 1.1 uch sc->sm_state = UCBADC_ADC_FINI;
450 1.1 uch else
451 1.1 uch sc->sm_state = UCBADC_INTR_ACK0;
452 1.1 uch break;
453 1.1 uch
454 1.1 uch case UCBADC_INTR_ACK0:
455 1.1 uch REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1);
456 1.1 uch break;
457 1.1 uch
458 1.1 uch case UCBADC_INTR_ACK1:
459 1.1 uch REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2);
460 1.1 uch break;
461 1.1 uch
462 1.1 uch case UCBADC_INTR_ACK2:
463 1.1 uch sc->sc_polling_finish = 1;
464 1.1 uch REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI);
465 1.1 uch break;
466 1.1 uch
467 1.1 uch /*
468 1.1 uch * UCB1200 register access state
469 1.1 uch */
470 1.1 uch case UCBADC_REGREAD:
471 1.1 uch /*
472 1.1 uch * In : sc->sm_addr
473 1.1 uch * Out : sc->sm_reg (with SIBtag)
474 1.1 uch */
475 1.1 uch #define TXSIB_REGREAD_INIT 0
476 1.1 uch #define TXSIB_REGREAD_READ 1
477 1.1 uch switch (sc->sm_read_state) {
478 1.1 uch case TXSIB_REGREAD_INIT:
479 1.1 uch reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr);
480 1.1 uch tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
481 1.1 uch sc->sm_rw_retry = 3;
482 1.1 uch sc->sm_read_state = TXSIB_REGREAD_READ;
483 1.1 uch break;
484 1.1 uch case TXSIB_REGREAD_READ:
485 1.1 uch reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
486 1.1 uch if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) &&
487 1.1 uch --sc->sm_rw_retry > 0) {
488 1.1 uch printf("retry!\n");
489 1.1 uch break;
490 1.1 uch }
491 1.1 uch
492 1.1 uch if (sc->sm_rw_retry <= 0) {
493 1.1 uch printf("sf0read: command failed\n");
494 1.1 uch sc->sm_state = UCBADC_ADC_FINI;
495 1.1 uch } else {
496 1.1 uch sc->sm_reg = reg;
497 1.1 uch sc->sm_read_state = TXSIB_REGREAD_INIT;
498 1.1 uch DPRINTFN(9, ("%08x\n", reg));
499 1.1 uch if (sc->sm_writing)
500 1.1 uch sc->sm_state = UCBADC_REGWRITE;
501 1.1 uch else
502 1.1 uch sc->sm_state = sc->sm_returnstate;
503 1.1 uch }
504 1.1 uch break;
505 1.1 uch }
506 1.1 uch break;
507 1.1 uch
508 1.1 uch case UCBADC_REGWRITE:
509 1.1 uch /*
510 1.1 uch * In : sc->sm_addr, sc->sm_reg (lower 16bit only)
511 1.1 uch */
512 1.1 uch #define TXSIB_REGWRITE_INIT 0
513 1.1 uch #define TXSIB_REGWRITE_WRITE 1
514 1.1 uch switch (sc->sm_write_state) {
515 1.1 uch case TXSIB_REGWRITE_INIT:
516 1.1 uch sc->sm_writing = 1;
517 1.1 uch sc->sm_write_state = TXSIB_REGWRITE_WRITE;
518 1.1 uch sc->sm_state = UCBADC_REGREAD;
519 1.1 uch
520 1.1 uch sc->sm_write_val = sc->sm_reg;
521 1.1 uch break;
522 1.1 uch case TXSIB_REGWRITE_WRITE:
523 1.1 uch sc->sm_writing = 0;
524 1.1 uch sc->sm_write_state = TXSIB_REGWRITE_INIT;
525 1.1 uch sc->sm_state = sc->sm_returnstate;
526 1.1 uch
527 1.1 uch reg = sc->sm_reg;
528 1.1 uch reg |= TX39_SIBSF0_WRITE;
529 1.1 uch TX39_SIBSF0_REGDATA_CLR(reg);
530 1.1 uch reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val);
531 1.1 uch tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
532 1.1 uch
533 1.1 uch break;
534 1.1 uch }
535 1.1 uch break;
536 1.1 uch }
537 1.1 uch
538 1.1 uch return 0;
539 1.1 uch }
540 1.1 uch
541 1.1 uch int
542 1.1 uch ucb1200_input(sc)
543 1.1 uch struct ucb1200_softc *sc;
544 1.1 uch {
545 1.1 uch static int _x, _y;
546 1.1 uch int xraw, yraw, pval, x, y;
547 1.1 uch
548 1.1 uch xraw = sc->sc_x;
549 1.1 uch yraw = sc->sc_y;
550 1.1 uch pval = sc->sc_p;
551 1.1 uch
552 1.1 uch x = (sc->sc_prmax * xraw + sc->sc_prmbx*yraw) / SCALE +
553 1.1 uch sc->sc_prmcx;
554 1.1 uch y = (sc->sc_prmay * xraw + sc->sc_prmby*yraw) / SCALE +
555 1.1 uch sc->sc_prmcy;
556 1.1 uch
557 1.1 uch if (pval < UCBTS_PRESS_THRESHOLD) {
558 1.1 uch sc->sc_stat = UCBTS_STAT_RELEASE;
559 1.1 uch if (sc->sc_polling < UCBTS_TAP_THRESHOLD) {
560 1.1 uch DPRINTFN(1, ("TAP!\n"));
561 1.1 uch /* button 0 DOWN */
562 1.1 uch wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0);
563 1.1 uch /* button 0 UP */
564 1.1 uch wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
565 1.1 uch } else {
566 1.1 uch wsmouse_input(sc->sc_wsmousedev, 0, _x, _y, 0,
567 1.1 uch WSMOUSE_INPUT_ABSOLUTE_X |
568 1.1 uch WSMOUSE_INPUT_ABSOLUTE_Y);
569 1.1 uch
570 1.1 uch DPRINTFN(1, ("RELEASE\n"));
571 1.1 uch }
572 1.1 uch sc->sc_polling = 0;
573 1.1 uch
574 1.1 uch return 1;
575 1.1 uch }
576 1.1 uch DPRINTFN(1, ("xraw=%d yraw=%d pressure=%d\n", xraw, yraw, pval));
577 1.1 uch
578 1.1 uch if (x < 0 || x > sc->sc_maxx || y < 0 || y > sc->sc_maxy)
579 1.1 uch return 0;
580 1.1 uch
581 1.1 uch if (sc->sc_polling == 1)
582 1.1 uch tx3912video_dot(_x = x, _y = y);
583 1.1 uch else
584 1.1 uch tx3912video_line(_x, _y, _x = x, _y = y);
585 1.1 uch
586 1.1 uch wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0,
587 1.1 uch WSMOUSE_INPUT_ABSOLUTE_X |
588 1.1 uch WSMOUSE_INPUT_ABSOLUTE_Y);
589 1.1 uch
590 1.1 uch return 0;
591 1.1 uch }
592 1.1 uch
593 1.1 uch int
594 1.1 uch ucb1200_sibintr(arg)
595 1.1 uch void *arg;
596 1.1 uch {
597 1.1 uch struct ucb1200_softc *sc = arg;
598 1.1 uch
599 1.1 uch sc->sc_stat = UCBTS_STAT_TOUCH;
600 1.1 uch
601 1.1 uch /* invoke touch screen polling */
602 1.1 uch if (!sc->sc_polling) {
603 1.1 uch sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE,
604 1.1 uch ucb1200_poll, sc);
605 1.1 uch if (!sc->sc_pollh) {
606 1.1 uch printf("%s: can't poll\n", sc->sc_dev.dv_xname);
607 1.1 uch }
608 1.1 uch }
609 1.1 uch
610 1.1 uch /* don't acknoledge interrupt until polling finish */
611 1.1 uch
612 1.1 uch return 0;
613 1.1 uch }
614 1.1 uch
615 1.1 uch /*
616 1.1 uch * sync functions. don't use runtime.
617 1.1 uch */
618 1.1 uch
619 1.1 uch void
620 1.1 uch ucb1200_intr_ack_sync(sc)
621 1.1 uch struct ucb1200_softc *sc;
622 1.1 uch {
623 1.1 uch tx_chipset_tag_t tc = sc->sc_tc;
624 1.1 uch u_int16_t reg;
625 1.1 uch
626 1.1 uch /* clear interrupt */
627 1.1 uch reg = txsibsf0_reg_read(tc, UCB1200_INTSTAT_REG);
628 1.1 uch txsibsf0_reg_write(tc, UCB1200_INTSTAT_REG, reg);
629 1.1 uch txsibsf0_reg_write(tc, UCB1200_INTSTAT_REG, 0);
630 1.1 uch }
631 1.1 uch
632 1.1 uch int
633 1.1 uch ucb1200_adc_sync(sc, src, valp)
634 1.1 uch struct ucb1200_softc *sc;
635 1.1 uch int src;
636 1.1 uch int *valp;
637 1.1 uch {
638 1.1 uch tx_chipset_tag_t tc = sc->sc_tc;
639 1.1 uch u_int16_t reg;
640 1.1 uch int i = 100; /* retry max */
641 1.1 uch
642 1.1 uch reg = UCB1200_ADCCTRL_ENABLE;
643 1.1 uch
644 1.1 uch switch (src) {
645 1.1 uch case UCBTS_POSX:
646 1.1 uch txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
647 1.1 uch UCB1200_TSCTRL_XPOSITION);
648 1.1 uch reg = UCB1200_ADCCTRL_INPUT_SET(reg,
649 1.1 uch UCB1200_ADCCTRL_INPUT_TSPX);
650 1.1 uch break;
651 1.1 uch case UCBTS_POSY:
652 1.1 uch txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
653 1.1 uch UCB1200_TSCTRL_YPOSITION);
654 1.1 uch reg = UCB1200_ADCCTRL_INPUT_SET(reg,
655 1.1 uch UCB1200_ADCCTRL_INPUT_TSPY);
656 1.1 uch break;
657 1.1 uch case UCBTS_PRESS:
658 1.1 uch txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
659 1.1 uch UCB1200_TSCTRL_PRESSURE);
660 1.1 uch reg = UCB1200_ADCCTRL_INPUT_SET(reg,
661 1.1 uch UCB1200_ADCCTRL_INPUT_TSPX);
662 1.1 uch break;
663 1.1 uch }
664 1.1 uch /* enable ADC */
665 1.1 uch txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG, reg);
666 1.1 uch
667 1.1 uch /* start A-D convert */
668 1.1 uch txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG,
669 1.1 uch reg | UCB1200_ADCCTRL_START);
670 1.1 uch txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG, reg);
671 1.1 uch
672 1.1 uch /* inquire converted value */
673 1.1 uch do {
674 1.1 uch reg = txsibsf0_reg_read(tc, UCB1200_ADCDATA_REG);
675 1.1 uch } while (!(reg & UCB1200_ADCDATA_INPROGRESS) && --i > 0);
676 1.1 uch
677 1.1 uch /* disable ADC */
678 1.1 uch txsibsf0_reg_write(tc, UCB1200_ADCCTRL_REG, 0);
679 1.1 uch
680 1.1 uch /* turn to interrupt mode */
681 1.1 uch txsibsf0_reg_write(tc, UCB1200_TSCTRL_REG,
682 1.1 uch UCB1200_TSCTRL_INTERRUPT);
683 1.1 uch
684 1.1 uch if (i == 0) {
685 1.1 uch printf("ADC not complete.\n");
686 1.1 uch return 1;
687 1.1 uch } else {
688 1.1 uch *valp = UCB1200_ADCDATA(reg);
689 1.1 uch }
690 1.1 uch
691 1.1 uch return 0;
692 1.1 uch }
693 1.1 uch
694 1.1 uch /*
695 1.1 uch * access ops.
696 1.1 uch */
697 1.1 uch
698 1.1 uch int
699 1.1 uch ucb_ts_enable(v)
700 1.1 uch void *v;
701 1.1 uch {
702 1.1 uch /* not yet */
703 1.1 uch return 0;
704 1.1 uch }
705 1.1 uch
706 1.1 uch void
707 1.1 uch ucb_ts_disable(v)
708 1.1 uch void *v;
709 1.1 uch {
710 1.1 uch /* not yet */
711 1.1 uch }
712 1.1 uch
713 1.1 uch int
714 1.1 uch ucb_ts_ioctl(v, cmd, data, flag, p)
715 1.1 uch void *v;
716 1.1 uch u_long cmd;
717 1.1 uch caddr_t data;
718 1.1 uch int flag;
719 1.1 uch struct proc *p;
720 1.1 uch {
721 1.1 uch /* not yet */
722 1.1 uch return 0;
723 1.1 uch }
724 1.1 uch
725 1.1 uch void
726 1.1 uch ucb1200_dump(sc)
727 1.1 uch struct ucb1200_softc *sc;
728 1.1 uch {
729 1.1 uch const char *regname[] = {
730 1.1 uch "IO_DATA ",
731 1.1 uch "IO_DIR ",
732 1.1 uch "POSINTEN ",
733 1.1 uch "NEGINTEN ",
734 1.1 uch "INTSTAT ",
735 1.1 uch "TELECOMCTRLA ",
736 1.1 uch "TELECOMCTRLB ",
737 1.1 uch "AUDIOCTRLA ",
738 1.1 uch "AUDIOCTRLB ",
739 1.1 uch "TOUCHSCREENCTRL",
740 1.1 uch "ADCCTRL ",
741 1.1 uch "ADCDATA ",
742 1.1 uch "ID ",
743 1.1 uch "MODE ",
744 1.1 uch "RESERVED ",
745 1.1 uch "NULL "
746 1.1 uch };
747 1.1 uch tx_chipset_tag_t tc = sc->sc_tc;
748 1.1 uch u_int16_t reg;
749 1.1 uch int i;
750 1.1 uch
751 1.1 uch for (i = 0; i < 16; i++) {
752 1.1 uch reg = txsibsf0_reg_read(tc, i);
753 1.1 uch printf("%s(%02d) 0x%04x ", regname[i], i, reg);
754 1.1 uch bitdisp(reg);
755 1.1 uch }
756 1.1 uch }
757