ucbtp.c revision 1.2 1 /* $NetBSD: ucbtp.c,v 1.2 2000/01/16 21:47:01 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 * 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 #ifdef TX391X
57 #include <hpcmips/tx/tx3912videovar.h> /* debug */
58 #endif
59 #include <hpcmips/dev/ucb1200var.h>
60 #include <hpcmips/dev/ucb1200reg.h>
61
62 #include <hpcmips/tx/txsnd.h>
63
64 #ifdef UCBTPDEBUG
65 int ucbtp_debug = 1;
66 #define DPRINTF(arg) if (ucbtp_debug) printf arg;
67 #define DPRINTFN(n, arg) if (ucbtp_debug > (n)) printf arg;
68 #else
69 #define DPRINTF(arg)
70 #define DPRINTFN(n, arg)
71 #endif
72
73 enum ucbts_stat {
74 UCBTS_STAT_DISABLE,
75 UCBTS_STAT_RELEASE,
76 UCBTS_STAT_TOUCH,
77 UCBTS_STAT_DRAG,
78 };
79
80 #define UCBTS_POSX 1
81 #define UCBTS_POSY 2
82 #define UCBTS_PRESS 3
83
84 #define UCBTS_PRESS_THRESHOLD 100
85 #define UCBTS_TAP_THRESHOLD 5
86
87 enum ucbadc_state {
88 /* 0 */ UCBADC_IDLE,
89 /* 1 */ UCBADC_ADC_INIT,
90 /* 2 */ UCBADC_ADC_FINI,
91 /* 3 */ UCBADC_MEASUMENT_INIT,
92 /* 4 */ UCBADC_MEASUMENT_FINI,
93 /* 5 */ UCBADC_ADC_ENABLE,
94 /* 6 */ UCBADC_ADC_START0,
95 /* 7 */ UCBADC_ADC_START1,
96 /* 8 */ UCBADC_ADC_DATAREAD,
97 /* 9 */ UCBADC_ADC_DATAREAD_WAIT,
98 /*10 */ UCBADC_ADC_DISABLE,
99 /*11 */ UCBADC_ADC_INTRMODE,
100 /*12 */ UCBADC_ADC_INPUT,
101 /*13 */ UCBADC_INTR_ACK0,
102 /*14 */ UCBADC_INTR_ACK1,
103 /*15 */ UCBADC_INTR_ACK2,
104 /*16 */ UCBADC_REGREAD,
105 /*17 */ UCBADC_REGWRITE
106 };
107
108 struct ucbtp_softc {
109 struct device sc_dev;
110 struct device *sc_sib; /* parent (TX39 SIB module) */
111 struct device *sc_ucb; /* parent (UCB1200 module) */
112 tx_chipset_tag_t sc_tc;
113
114 enum ucbts_stat sc_stat;
115 int sc_polling;
116 int sc_polling_finish;
117 void *sc_pollh;
118
119 struct tpcalib_softc sc_tpcalib;
120 int sc_calibrated;
121
122 /* measurement value */
123 int sc_x, sc_y, sc_p;
124 int sc_ox, sc_oy;
125
126 /*
127 * touch panel state machine
128 */
129 void *sm_ih; /* TX39 SIB subframe 0 interrupt handler */
130
131 int sm_addr; /* UCB1200 register address */
132 u_int32_t sm_reg; /* UCB1200 register data & TX39 SIB header */
133 int sm_tmpreg;
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_UNKNOWN, PLATID_UNKNOWN}},
213 { 0, 0, 639, 239, 5,
214 {{0, 0, 0, 0},
215 {0, 0, 0, 0},
216 {0, 0, 0, 0},
217 {0, 0, 0, 0},
218 {0, 0, 0, 0}}}},
219 };
220
221 struct wsmouse_calibcoords *
222 calibration_sample_lookup()
223 {
224 struct calibration_sample_table *tab;
225 platid_mask_t mask;
226
227 for (tab = calibration_sample_table;
228 tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) {
229
230 mask = PLATID_DEREF(&tab->cst_platform);
231
232 if (platid_match(&platid, &mask)) {
233 return &tab->cst_sample;
234 }
235 }
236
237 return 0;
238 }
239
240 int
241 ucbtp_calibration(sc)
242 struct ucbtp_softc *sc;
243 {
244 struct wsmouse_calibcoords *cs;
245 #ifdef TX391X
246 tx3912video_calibration_pattern(); /* debug */
247 #endif
248 tpcalib_init(&sc->sc_tpcalib);
249
250 if (!(cs = calibration_sample_lookup())) {
251 printf("no calibration data");
252 return 1;
253 }
254
255 sc->sc_calibrated =
256 tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
257 (caddr_t)cs, 0, 0) == 0 ? 1 : 0;
258
259 if (!sc->sc_calibrated)
260 printf("not ");
261 printf("calibrated");
262
263 return 0;
264 }
265
266 int
267 ucbtp_match(parent, cf, aux)
268 struct device *parent;
269 struct cfdata *cf;
270 void *aux;
271 {
272 return 1;
273 }
274
275 void
276 ucbtp_attach(parent, self, aux)
277 struct device *parent;
278 struct device *self;
279 void *aux;
280 {
281 struct ucb1200_attach_args *ucba = aux;
282 struct ucbtp_softc *sc = (void*)self;
283 struct wsmousedev_attach_args wsmaa;
284 tx_chipset_tag_t tc;
285
286 tc = sc->sc_tc = ucba->ucba_tc;
287 sc->sc_sib = ucba->ucba_sib;
288 sc->sc_ucb = ucba->ucba_ucb;
289
290 printf(": ");
291 /* touch panel interrupt */
292 tx_intr_establish(tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT),
293 IST_EDGE, IPL_TTY, ucbtp_sibintr, sc);
294
295 /* attempt to calibrate touch panel */
296 ucbtp_calibration(sc);
297
298 printf("\n");
299
300 wsmaa.accessops = &ucbtp_accessops;
301 wsmaa.accesscookie = sc;
302
303 ucb1200_state_install(parent, ucbtp_busy, self, UCB1200_TP_MODULE);
304
305 /*
306 * attach the wsmouse
307 */
308 sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
309 }
310
311 int
312 ucbtp_busy(arg)
313 void *arg;
314 {
315 struct ucbtp_softc *sc = arg;
316
317 return sc->sm_state != UCBADC_IDLE;
318 }
319
320 int
321 ucbtp_poll(arg)
322 void *arg;
323 {
324 struct ucbtp_softc *sc = arg;
325
326 if (!ucb1200_state_idle(sc->sc_ucb)) /* subframe0 busy */
327 return POLL_CONT;
328
329 if (sc->sc_polling_finish) {
330 sc->sc_polling_finish = 0;
331 return POLL_END;
332 }
333
334 /* execute A-D converter */
335 sc->sm_state = UCBADC_ADC_INIT;
336 ucbtp_adc_async(sc);
337
338 return POLL_CONT;
339 }
340
341 int
342 ucbtp_sibintr(arg)
343 void *arg;
344 {
345 struct ucbtp_softc *sc = arg;
346
347 sc->sc_stat = UCBTS_STAT_TOUCH;
348
349 /* click! */
350 tx_sound_click(sc->sc_tc);
351
352 /* invoke touch panel polling */
353 if (!sc->sc_polling) {
354 sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE,
355 ucbtp_poll, sc);
356 if (!sc->sc_pollh) {
357 printf("%s: can't poll\n", sc->sc_dev.dv_xname);
358 }
359 }
360
361 /* don't acknoledge interrupt until polling finish */
362
363 return 0;
364 }
365
366 #define REGWRITE(addr, reg, ret) ( \
367 sc->sm_addr = (addr), \
368 sc->sm_reg = (reg), \
369 sc->sm_returnstate = (ret),\
370 sc->sm_state = UCBADC_REGWRITE)
371 #define REGREAD(addr, ret) ( \
372 sc->sm_addr = (addr), \
373 sc->sm_returnstate = (ret), \
374 sc->sm_state = UCBADC_REGREAD)
375
376 int
377 ucbtp_adc_async(arg)
378 void *arg;
379 {
380 struct ucbtp_softc *sc = arg;
381 tx_chipset_tag_t tc = sc->sc_tc;
382 txreg_t reg;
383 u_int16_t reg16;
384
385 DPRINTFN(9, ("state: %d\n", sc->sm_state));
386
387 switch (sc->sm_state) {
388 default:
389 panic("ucbtp_adc: invalid state %d", sc->sm_state);
390 /* NOTREACHED */
391 break;
392
393 case UCBADC_IDLE:
394 /* nothing to do */
395 break;
396
397 case UCBADC_ADC_INIT:
398 sc->sc_polling++;
399 sc->sc_stat = UCBTS_STAT_DRAG;
400 /* enable heart beat of this state machine */
401 sc->sm_ih = tx_intr_establish(
402 tc,
403 MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
404 IST_EDGE, IPL_TTY, ucbtp_adc_async, sc);
405
406 sc->sm_state = UCBADC_MEASUMENT_INIT;
407 break;
408
409 case UCBADC_ADC_FINI:
410 /* disable heart beat of this state machine */
411 tx_intr_disestablish(tc, sc->sm_ih);
412 sc->sm_state = UCBADC_IDLE;
413 break;
414
415 case UCBADC_MEASUMENT_INIT:
416 switch (sc->sm_measurement) {
417 default:
418 panic("unknown measurement spec.");
419 /* NOTREACHED */
420 break;
421 case UCBADC_MEASUREMENT_X:
422 REGWRITE(UCB1200_TSCTRL_REG,
423 UCB1200_TSCTRL_XPOSITION,
424 UCBADC_ADC_ENABLE);
425 break;
426 case UCBADC_MEASUREMENT_Y:
427 REGWRITE(UCB1200_TSCTRL_REG,
428 UCB1200_TSCTRL_YPOSITION,
429 UCBADC_ADC_ENABLE);
430 break;
431 case UCBADC_MEASUREMENT_PRESSURE:
432 REGWRITE(UCB1200_TSCTRL_REG,
433 UCB1200_TSCTRL_PRESSURE,
434 UCBADC_ADC_ENABLE);
435 break;
436 }
437 break;
438
439 case UCBADC_MEASUMENT_FINI:
440 switch (sc->sm_measurement) {
441 case UCBADC_MEASUREMENT_X:
442 sc->sm_measurement = UCBADC_MEASUREMENT_Y;
443 sc->sm_state = UCBADC_MEASUMENT_INIT;
444 break;
445 case UCBADC_MEASUREMENT_Y:
446 sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE;
447 sc->sm_state = UCBADC_MEASUMENT_INIT;
448 break;
449 case UCBADC_MEASUREMENT_PRESSURE:
450 sc->sm_measurement = UCBADC_MEASUREMENT_X;
451 /* measument complete. pass down to wsmouse_input */
452 sc->sm_state = UCBADC_ADC_INPUT;
453 break;
454 }
455 break;
456
457 case UCBADC_ADC_ENABLE:
458 switch (sc->sm_measurement) {
459 case UCBADC_MEASUREMENT_PRESSURE:
460 /* FALLTHROUGH */
461 case UCBADC_MEASUREMENT_X:
462 sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
463 UCB1200_ADCCTRL_ENABLE,
464 UCB1200_ADCCTRL_INPUT_TSPX);
465 REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
466 UCBADC_ADC_START0);
467 break;
468 case UCBADC_MEASUREMENT_Y:
469 sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
470 UCB1200_ADCCTRL_ENABLE,
471 UCB1200_ADCCTRL_INPUT_TSPY);
472 REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
473 UCBADC_ADC_START0);
474 break;
475 }
476 break;
477
478 case UCBADC_ADC_START0:
479 REGWRITE(UCB1200_ADCCTRL_REG,
480 sc->sm_tmpreg | UCB1200_ADCCTRL_START,
481 UCBADC_ADC_START1);
482 break;
483
484 case UCBADC_ADC_START1:
485 REGWRITE(UCB1200_ADCCTRL_REG,
486 sc->sm_tmpreg,
487 UCBADC_ADC_DATAREAD);
488 sc->sm_retry = 100;
489 break;
490
491 case UCBADC_ADC_DATAREAD:
492 REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT);
493 break;
494
495 case UCBADC_ADC_DATAREAD_WAIT:
496 reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg);
497 if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) &&
498 --sc->sm_retry > 0) {
499 sc->sm_state = UCBADC_ADC_DATAREAD;
500 } else {
501 if (sc->sm_retry <= 0) {
502 printf("dataread failed\n");
503 sc->sm_state = UCBADC_ADC_FINI;
504 break;
505 }
506
507 switch (sc->sm_measurement) {
508 case UCBADC_MEASUREMENT_X:
509 sc->sc_x = UCB1200_ADCDATA(reg16);
510 DPRINTFN(9, ("x=%d\n", sc->sc_x));
511 break;
512 case UCBADC_MEASUREMENT_Y:
513 sc->sc_y = UCB1200_ADCDATA(reg16);
514 DPRINTFN(9, ("y=%d\n", sc->sc_y));
515 break;
516 case UCBADC_MEASUREMENT_PRESSURE:
517 sc->sc_p = UCB1200_ADCDATA(reg16);
518 DPRINTFN(9, ("p=%d\n", sc->sc_p));
519 break;
520 }
521
522 sc->sm_state = UCBADC_ADC_DISABLE;
523 }
524
525 break;
526
527 case UCBADC_ADC_DISABLE:
528 REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE);
529
530 break;
531 case UCBADC_ADC_INTRMODE:
532 REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT,
533 UCBADC_MEASUMENT_FINI);
534 break;
535
536 case UCBADC_ADC_INPUT:
537 if (ucbtp_input(sc) == 0)
538 sc->sm_state = UCBADC_ADC_FINI;
539 else
540 sc->sm_state = UCBADC_INTR_ACK0;
541 break;
542
543 case UCBADC_INTR_ACK0:
544 REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1);
545 break;
546
547 case UCBADC_INTR_ACK1:
548 REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2);
549 break;
550
551 case UCBADC_INTR_ACK2:
552 sc->sc_polling_finish = 1;
553 REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI);
554 break;
555
556 /*
557 * UCB1200 register access state
558 */
559 case UCBADC_REGREAD:
560 /*
561 * In : sc->sm_addr
562 * Out : sc->sm_reg (with SIBtag)
563 */
564 #define TXSIB_REGREAD_INIT 0
565 #define TXSIB_REGREAD_READ 1
566 switch (sc->sm_read_state) {
567 case TXSIB_REGREAD_INIT:
568 reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr);
569 tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
570 sc->sm_rw_retry = 100;
571 sc->sm_read_state = TXSIB_REGREAD_READ;
572 break;
573 case TXSIB_REGREAD_READ:
574 reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
575 if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) &&
576 --sc->sm_rw_retry > 0) {
577 printf("retry!\n");
578 break;
579 }
580
581 if (sc->sm_rw_retry <= 0) {
582 printf("sf0read: command failed\n");
583 sc->sm_state = UCBADC_ADC_FINI;
584 } else {
585 sc->sm_reg = reg;
586 sc->sm_read_state = TXSIB_REGREAD_INIT;
587 DPRINTFN(9, ("%08x\n", reg));
588 if (sc->sm_writing)
589 sc->sm_state = UCBADC_REGWRITE;
590 else
591 sc->sm_state = sc->sm_returnstate;
592 }
593 break;
594 }
595 break;
596
597 case UCBADC_REGWRITE:
598 /*
599 * In : sc->sm_addr, sc->sm_reg (lower 16bit only)
600 */
601 #define TXSIB_REGWRITE_INIT 0
602 #define TXSIB_REGWRITE_WRITE 1
603 switch (sc->sm_write_state) {
604 case TXSIB_REGWRITE_INIT:
605 sc->sm_writing = 1;
606 sc->sm_write_state = TXSIB_REGWRITE_WRITE;
607 sc->sm_state = UCBADC_REGREAD;
608
609 sc->sm_write_val = sc->sm_reg;
610 break;
611 case TXSIB_REGWRITE_WRITE:
612 sc->sm_writing = 0;
613 sc->sm_write_state = TXSIB_REGWRITE_INIT;
614 sc->sm_state = sc->sm_returnstate;
615
616 reg = sc->sm_reg;
617 reg |= TX39_SIBSF0_WRITE;
618 TX39_SIBSF0_REGDATA_CLR(reg);
619 reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val);
620 tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
621 break;
622 }
623 break;
624 }
625
626 return 0;
627 }
628
629 int
630 ucbtp_input(sc)
631 struct ucbtp_softc *sc;
632 {
633 int x, y;
634
635 if (!sc->sc_calibrated) { /* XXX definitely no problem */
636 printf("ucbtp_input: no calibration data\n");
637 return 1;
638 }
639
640 tpcalib_trans(&sc->sc_tpcalib, sc->sc_x, sc->sc_y, &x, &y);
641 DPRINTFN(1, ("x: %d->%d y: %d->%d pressure=%d\n",
642 sc->sc_x, x, sc->sc_y, y, sc->sc_p));
643
644 if (sc->sc_p < UCBTS_PRESS_THRESHOLD) {
645 sc->sc_stat = UCBTS_STAT_RELEASE;
646 if (sc->sc_polling < UCBTS_TAP_THRESHOLD) {
647 DPRINTFN(1, ("TAP!\n"));
648 /* button 0 DOWN */
649 wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0);
650 /* button 0 UP */
651 wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
652 } else {
653 wsmouse_input(sc->sc_wsmousedev, 0,
654 sc->sc_ox, sc->sc_oy, 0,
655 WSMOUSE_INPUT_ABSOLUTE_X |
656 WSMOUSE_INPUT_ABSOLUTE_Y);
657
658 DPRINTFN(1, ("RELEASE\n"));
659 }
660 sc->sc_polling = 0;
661
662 return 1;
663 }
664
665 #ifdef TX391X /* debug */
666 if (sc->sc_polling == 1)
667 tx3912video_dot(x, y);
668 else
669 tx3912video_line(sc->sc_ox, sc->sc_oy, x, y);
670 sc->sc_ox = x, sc->sc_oy = y;
671 #endif
672 wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0,
673 WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
674
675 return 0;
676 }
677
678 /*
679 * access ops.
680 */
681
682 int
683 ucbtp_enable(v)
684 void *v;
685 {
686 /* not yet */
687 return 0;
688 }
689
690 void
691 ucbtp_disable(v)
692 void *v;
693 {
694 /* not yet */
695 }
696
697 int
698 ucbtp_ioctl(v, cmd, data, flag, p)
699 void *v;
700 u_long cmd;
701 caddr_t data;
702 int flag;
703 struct proc *p;
704 {
705 struct ucbtp_softc *sc = v;
706
707 DPRINTF(("%s(%d): ucbtp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd));
708
709 switch (cmd) {
710 case WSMOUSEIO_GTYPE:
711 *(u_int *)data = WSMOUSE_TYPE_TPANEL;
712 break;
713
714 case WSMOUSEIO_SRES:
715 printf("%s(%d): WSMOUSRIO_SRES is not supported",
716 __FILE__, __LINE__);
717 break;
718
719 case WSMOUSEIO_SCALIBCOORDS:
720 case WSMOUSEIO_GCALIBCOORDS:
721 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p);
722
723 default:
724 return (-1);
725 }
726 return (0);
727 }
728