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