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