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