Home | History | Annotate | Line # | Download | only in dev
ucbtp.c revision 1.3
      1 /*	$NetBSD: ucbtp.c,v 1.3 2000/03/04 19:36:34 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	80
     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 #define UCBADC_RETRY_DEFAULT		200
    135 	int		sm_retry; /* retry counter */
    136 
    137 	enum ucbadc_state sm_state;
    138 	int		sm_measurement; /* X, Y, Pressure */
    139 #define	UCBADC_MEASUREMENT_X		0
    140 #define	UCBADC_MEASUREMENT_Y		1
    141 #define	UCBADC_MEASUREMENT_PRESSURE	2
    142 	int		sm_returnstate;
    143 
    144 	int		sm_read_state, sm_write_state;
    145 	int		sm_writing;	/* writing state flag */
    146 	u_int32_t	sm_write_val;	/* temporary buffer */
    147 
    148 	int		sm_rw_retry; /* retry counter for r/w */
    149 
    150 	/* wsmouse */
    151 	struct device *sc_wsmousedev;
    152 };
    153 
    154 int	ucbtp_match	__P((struct device*, struct cfdata*, void*));
    155 void	ucbtp_attach	__P((struct device*, struct device*, void*));
    156 
    157 int	ucbtp_sibintr	__P((void*));
    158 int	ucbtp_poll __P((void*));
    159 int	ucbtp_adc_async __P((void*));
    160 int	ucbtp_input __P((struct ucbtp_softc*));
    161 int	ucbtp_busy __P((void*));
    162 
    163 int	ucbtp_enable __P((void*));
    164 int	ucbtp_ioctl __P((void*, u_long, caddr_t, int, struct proc*));
    165 void	ucbtp_disable __P((void*));
    166 
    167 struct cfattach ucbtp_ca = {
    168 	sizeof(struct ucbtp_softc), ucbtp_match, ucbtp_attach
    169 };
    170 
    171 const struct wsmouse_accessops ucbtp_accessops = {
    172 	ucbtp_enable,
    173 	ucbtp_ioctl,
    174 	ucbtp_disable,
    175 };
    176 
    177 /*
    178  * XXX currently no calibration method. this is temporary hack.
    179  */
    180 #include <machine/platid.h>
    181 
    182 struct	wsmouse_calibcoords *calibration_sample_lookup __P((void));
    183 int	ucbtp_calibration __P((struct ucbtp_softc*));
    184 
    185 struct calibration_sample_table {
    186 	platid_t	cst_platform;
    187 	struct wsmouse_calibcoords cst_sample;
    188 } calibration_sample_table[] = {
    189 	{{{PLATID_WILD, PLATID_MACH_COMPAQ_C_8XX}},  /* uch machine */
    190 	 { 0, 0, 639, 239, 5,
    191 	   {{ 507, 510, 320, 120 },
    192 	    { 898, 757,  40,  40 },
    193 	    { 900, 255,  40, 200 },
    194 	    { 109, 249, 600, 200 },
    195 	    { 110, 753, 600,  40 }}}},
    196 
    197 	{{{PLATID_WILD, PLATID_MACH_COMPAQ_C_2010}}, /* uch machine */
    198 	 { 0, 0, 639, 239, 5,
    199 	   {{ 506, 487, 320, 120 },
    200 	    { 880, 250,  40,  40 },
    201 	    { 880, 718,  40, 200 },
    202 	    { 140, 726, 600, 200 },
    203 	    { 137, 250, 600,  40 }}}},
    204 
    205 	{{{PLATID_WILD, PLATID_MACH_SHARP_MOBILON_HC4100}}, /* uch machine */
    206 	 { 0, 0, 639, 239, 5,
    207 	   {{ 497, 501, 320, 120 },
    208 	    { 752, 893,  40,  40 },
    209 	    { 242, 891,  40, 200 },
    210 	    { 241, 115, 600, 200 },
    211 	    { 747, 101, 600,  40 }}}},
    212 
    213 	{{{PLATID_UNKNOWN, PLATID_UNKNOWN}},
    214 	 { 0, 0, 639, 239, 5,
    215 	   {{0, 0, 0, 0},
    216 	    {0, 0, 0, 0},
    217 	    {0, 0, 0, 0},
    218 	    {0, 0, 0, 0},
    219 	    {0, 0, 0, 0}}}},
    220 };
    221 
    222 struct wsmouse_calibcoords *
    223 calibration_sample_lookup()
    224 {
    225 	struct calibration_sample_table *tab;
    226 	platid_mask_t mask;
    227 
    228 	for (tab = calibration_sample_table;
    229 	     tab->cst_platform.dw.dw1 != PLATID_UNKNOWN; tab++) {
    230 
    231 		mask = PLATID_DEREF(&tab->cst_platform);
    232 
    233 		if (platid_match(&platid, &mask)) {
    234 			return &tab->cst_sample;
    235 		}
    236 	}
    237 
    238 	return 0;
    239 }
    240 
    241 int
    242 ucbtp_calibration(sc)
    243 	struct ucbtp_softc *sc;
    244 {
    245 	struct wsmouse_calibcoords *cs;
    246 #ifdef TX391X
    247 	tx3912video_calibration_pattern(); /* debug */
    248 #endif
    249 	tpcalib_init(&sc->sc_tpcalib);
    250 
    251 	if (!(cs = calibration_sample_lookup())) {
    252 		printf("no calibration data");
    253 		return 1;
    254 	}
    255 
    256 	sc->sc_calibrated =
    257 		tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
    258 			      (caddr_t)cs, 0, 0) == 0 ? 1 : 0;
    259 
    260 	if (!sc->sc_calibrated)
    261 		printf("not ");
    262 	printf("calibrated");
    263 
    264 	return 0;
    265 }
    266 
    267 int
    268 ucbtp_match(parent, cf, aux)
    269 	struct device *parent;
    270 	struct cfdata *cf;
    271 	void *aux;
    272 {
    273 	return 1;
    274 }
    275 
    276 void
    277 ucbtp_attach(parent, self, aux)
    278 	struct device *parent;
    279 	struct device *self;
    280 	void *aux;
    281 {
    282 	struct ucb1200_attach_args *ucba = aux;
    283 	struct ucbtp_softc *sc = (void*)self;
    284 	struct wsmousedev_attach_args wsmaa;
    285 	tx_chipset_tag_t tc;
    286 
    287 	tc = sc->sc_tc = ucba->ucba_tc;
    288 	sc->sc_sib = ucba->ucba_sib;
    289 	sc->sc_ucb = ucba->ucba_ucb;
    290 
    291 	printf(": ");
    292 	/* touch panel interrupt */
    293 	tx_intr_establish(tc, MAKEINTR(1, TX39_INTRSTATUS1_SIBIRQPOSINT),
    294 			  IST_EDGE, IPL_TTY, ucbtp_sibintr, sc);
    295 
    296 	/* attempt to calibrate touch panel */
    297 	ucbtp_calibration(sc);
    298 
    299 	printf("\n");
    300 
    301 	wsmaa.accessops = &ucbtp_accessops;
    302 	wsmaa.accesscookie = sc;
    303 
    304 	ucb1200_state_install(parent, ucbtp_busy, self, UCB1200_TP_MODULE);
    305 
    306 	/*
    307 	 * attach the wsmouse
    308 	 */
    309 	sc->sc_wsmousedev = config_found(self, &wsmaa, wsmousedevprint);
    310 }
    311 
    312 int
    313 ucbtp_busy(arg)
    314 	void *arg;
    315 {
    316 	struct ucbtp_softc *sc = arg;
    317 
    318 	return sc->sm_state != UCBADC_IDLE;
    319 }
    320 
    321 int
    322 ucbtp_poll(arg)
    323 	void *arg;
    324 {
    325 	struct ucbtp_softc *sc = arg;
    326 
    327 	if (!ucb1200_state_idle(sc->sc_ucb)) /* subframe0 busy */
    328 		return POLL_CONT;
    329 
    330 	if (sc->sc_polling_finish) {
    331 		sc->sc_polling_finish = 0;
    332 		return POLL_END;
    333 	}
    334 
    335 	/* execute A-D converter */
    336 	sc->sm_state = UCBADC_ADC_INIT;
    337 	ucbtp_adc_async(sc);
    338 
    339 	return POLL_CONT;
    340 }
    341 
    342 int
    343 ucbtp_sibintr(arg)
    344 	void *arg;
    345 {
    346 	struct ucbtp_softc *sc = arg;
    347 
    348 	sc->sc_stat = UCBTS_STAT_TOUCH;
    349 
    350 	/* click! */
    351 	tx_sound_click(sc->sc_tc);
    352 
    353 	/* invoke touch panel polling */
    354 	if (!sc->sc_polling) {
    355 		sc->sc_pollh = tx39_poll_establish(sc->sc_tc, 1, IST_EDGE,
    356 						   ucbtp_poll, sc);
    357 		if (!sc->sc_pollh) {
    358 			printf("%s: can't poll\n", sc->sc_dev.dv_xname);
    359 		}
    360 	}
    361 
    362 	/* don't acknoledge interrupt until polling finish */
    363 
    364 	return 0;
    365 }
    366 
    367 #define REGWRITE(addr, reg, ret) ( \
    368 	sc->sm_addr = (addr), \
    369 	sc->sm_reg = (reg), \
    370 	sc->sm_returnstate = (ret),\
    371 	sc->sm_state = UCBADC_REGWRITE)
    372 #define REGREAD(addr, ret) ( \
    373 	sc->sm_addr = (addr), \
    374 	sc->sm_returnstate = (ret), \
    375 	sc->sm_state = UCBADC_REGREAD)
    376 
    377 int
    378 ucbtp_adc_async(arg)
    379 	void *arg;
    380 {
    381 	struct ucbtp_softc *sc = arg;
    382 	tx_chipset_tag_t tc = sc->sc_tc;
    383 	txreg_t reg;
    384 	u_int16_t reg16;
    385 
    386 	DPRINTFN(9, ("state: %d\n", sc->sm_state));
    387 
    388 	switch (sc->sm_state) {
    389 	default:
    390 		panic("ucbtp_adc: invalid state %d", sc->sm_state);
    391 		/* NOTREACHED */
    392 		break;
    393 
    394 	case UCBADC_IDLE:
    395 		/* nothing to do */
    396 		break;
    397 
    398 	case UCBADC_ADC_INIT:
    399 		sc->sc_polling++;
    400 		sc->sc_stat = UCBTS_STAT_DRAG;
    401 		/* enable heart beat of this state machine */
    402 		sc->sm_ih = tx_intr_establish(
    403 			tc,
    404 			MAKEINTR(1, TX39_INTRSTATUS1_SIBSF0INT),
    405 			IST_EDGE, IPL_TTY, ucbtp_adc_async, sc);
    406 
    407 		sc->sm_state = UCBADC_MEASUMENT_INIT;
    408 		break;
    409 
    410 	case UCBADC_ADC_FINI:
    411 		/* disable heart beat of this state machine */
    412 		tx_intr_disestablish(tc, sc->sm_ih);
    413 		sc->sm_state = UCBADC_IDLE;
    414 		break;
    415 
    416 	case UCBADC_MEASUMENT_INIT:
    417 		switch (sc->sm_measurement) {
    418 		default:
    419 			panic("unknown measurement spec.");
    420 			/* NOTREACHED */
    421 			break;
    422 		case UCBADC_MEASUREMENT_X:
    423 			REGWRITE(UCB1200_TSCTRL_REG,
    424 				 UCB1200_TSCTRL_XPOSITION,
    425 				 UCBADC_ADC_ENABLE);
    426 			break;
    427 		case UCBADC_MEASUREMENT_Y:
    428 			REGWRITE(UCB1200_TSCTRL_REG,
    429 				 UCB1200_TSCTRL_YPOSITION,
    430 				 UCBADC_ADC_ENABLE);
    431 			break;
    432 		case UCBADC_MEASUREMENT_PRESSURE:
    433 			REGWRITE(UCB1200_TSCTRL_REG,
    434 				 UCB1200_TSCTRL_PRESSURE,
    435 				 UCBADC_ADC_ENABLE);
    436 			break;
    437 		}
    438 		break;
    439 
    440 	case UCBADC_MEASUMENT_FINI:
    441 		switch (sc->sm_measurement) {
    442 		case UCBADC_MEASUREMENT_X:
    443 			sc->sm_measurement = UCBADC_MEASUREMENT_Y;
    444 			sc->sm_state = UCBADC_MEASUMENT_INIT;
    445 			break;
    446 		case UCBADC_MEASUREMENT_Y:
    447 			sc->sm_measurement = UCBADC_MEASUREMENT_PRESSURE;
    448 			sc->sm_state = UCBADC_MEASUMENT_INIT;
    449 			break;
    450 		case UCBADC_MEASUREMENT_PRESSURE:
    451 			sc->sm_measurement = UCBADC_MEASUREMENT_X;
    452 			/* measument complete. pass down to wsmouse_input */
    453 			sc->sm_state = UCBADC_ADC_INPUT;
    454 			break;
    455 		}
    456 		break;
    457 
    458 	case UCBADC_ADC_ENABLE:
    459 		switch (sc->sm_measurement) {
    460 		case UCBADC_MEASUREMENT_PRESSURE:
    461 			/* FALLTHROUGH */
    462 		case UCBADC_MEASUREMENT_X:
    463 			sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
    464 				UCB1200_ADCCTRL_ENABLE,
    465 				UCB1200_ADCCTRL_INPUT_TSPX);
    466 			REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
    467 				 UCBADC_ADC_START0);
    468 			break;
    469 		case UCBADC_MEASUREMENT_Y:
    470 			sc->sm_tmpreg = UCB1200_ADCCTRL_INPUT_SET(
    471 				UCB1200_ADCCTRL_ENABLE,
    472 				UCB1200_ADCCTRL_INPUT_TSPY);
    473 			REGWRITE(UCB1200_ADCCTRL_REG, sc->sm_tmpreg,
    474 				 UCBADC_ADC_START0);
    475 			break;
    476 		}
    477 		break;
    478 
    479 	case UCBADC_ADC_START0:
    480 		REGWRITE(UCB1200_ADCCTRL_REG,
    481 			 sc->sm_tmpreg | UCB1200_ADCCTRL_START,
    482 			 UCBADC_ADC_START1);
    483 		break;
    484 
    485 	case UCBADC_ADC_START1:
    486 		REGWRITE(UCB1200_ADCCTRL_REG,
    487 			 sc->sm_tmpreg,
    488 			 UCBADC_ADC_DATAREAD);
    489 		sc->sm_retry = UCBADC_RETRY_DEFAULT;
    490 		break;
    491 
    492 	case UCBADC_ADC_DATAREAD:
    493 		REGREAD(UCB1200_ADCDATA_REG, UCBADC_ADC_DATAREAD_WAIT);
    494 		break;
    495 
    496 	case UCBADC_ADC_DATAREAD_WAIT:
    497 		reg16 = TX39_SIBSF0_REGDATA(sc->sm_reg);
    498 		if (!(reg16 & UCB1200_ADCDATA_INPROGRESS) &&
    499 		    --sc->sm_retry > 0) {
    500 			sc->sm_state = UCBADC_ADC_DATAREAD;
    501 		} else {
    502 			if (sc->sm_retry <= 0) {
    503 				printf("dataread failed\n");
    504 				sc->sm_state = UCBADC_ADC_FINI;
    505 				break;
    506 			}
    507 
    508 			switch (sc->sm_measurement) {
    509 			case UCBADC_MEASUREMENT_X:
    510 				sc->sc_x = UCB1200_ADCDATA(reg16);
    511 				DPRINTFN(9, ("x=%d\n", sc->sc_x));
    512 				break;
    513 			case UCBADC_MEASUREMENT_Y:
    514 				sc->sc_y = UCB1200_ADCDATA(reg16);
    515 				DPRINTFN(9, ("y=%d\n", sc->sc_y));
    516 				break;
    517 			case UCBADC_MEASUREMENT_PRESSURE:
    518 				sc->sc_p = UCB1200_ADCDATA(reg16);
    519 				DPRINTFN(9, ("p=%d\n", sc->sc_p));
    520 				break;
    521 			}
    522 
    523 			sc->sm_state = UCBADC_ADC_DISABLE;
    524 		}
    525 
    526 		break;
    527 
    528 	case UCBADC_ADC_DISABLE:
    529 		REGWRITE(UCB1200_ADCCTRL_REG, 0, UCBADC_ADC_INTRMODE);
    530 
    531 		break;
    532 	case UCBADC_ADC_INTRMODE:
    533 		REGWRITE(UCB1200_TSCTRL_REG, UCB1200_TSCTRL_INTERRUPT,
    534 			 UCBADC_MEASUMENT_FINI);
    535 		break;
    536 
    537 	case UCBADC_ADC_INPUT:
    538 		if (ucbtp_input(sc) == 0)
    539 			sc->sm_state = UCBADC_ADC_FINI;
    540 		else
    541 			sc->sm_state = UCBADC_INTR_ACK0;
    542 		break;
    543 
    544 	case UCBADC_INTR_ACK0:
    545 		REGREAD(UCB1200_INTSTAT_REG, UCBADC_INTR_ACK1);
    546 		break;
    547 
    548 	case UCBADC_INTR_ACK1:
    549 		REGWRITE(UCB1200_INTSTAT_REG, sc->sm_reg, UCBADC_INTR_ACK2);
    550 		break;
    551 
    552 	case UCBADC_INTR_ACK2:
    553 		sc->sc_polling_finish = 1;
    554 		REGWRITE(UCB1200_INTSTAT_REG, 0, UCBADC_ADC_FINI);
    555 		break;
    556 
    557 	/*
    558 	 * UCB1200 register access state
    559 	 */
    560 	case UCBADC_REGREAD:
    561 		/*
    562 		 * In	: sc->sm_addr
    563 		 * Out	: sc->sm_reg  (with SIBtag)
    564 		 */
    565 #define TXSIB_REGREAD_INIT	0
    566 #define TXSIB_REGREAD_READ	1
    567 		switch (sc->sm_read_state) {
    568 		case TXSIB_REGREAD_INIT:
    569 			reg = TX39_SIBSF0_REGADDR_SET(0, sc->sm_addr);
    570 			tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
    571 			sc->sm_rw_retry = UCBADC_RETRY_DEFAULT;
    572 			sc->sm_read_state = TXSIB_REGREAD_READ;
    573 			break;
    574 		case TXSIB_REGREAD_READ:
    575 			reg = tx_conf_read(tc, TX39_SIBSF0STAT_REG);
    576 			if ((TX39_SIBSF0_REGADDR(reg) != sc->sm_addr) &&
    577 			    --sc->sm_rw_retry > 0) {
    578 				printf("retry!\n");
    579 				break;
    580 			}
    581 
    582 			if (sc->sm_rw_retry <= 0) {
    583 				printf("sf0read: command failed\n");
    584 				sc->sm_state = UCBADC_ADC_FINI;
    585 			} else {
    586 				sc->sm_reg = reg;
    587 				sc->sm_read_state = TXSIB_REGREAD_INIT;
    588 				DPRINTFN(9, ("%08x\n", reg));
    589 				if (sc->sm_writing)
    590 					sc->sm_state = UCBADC_REGWRITE;
    591 				else
    592 					sc->sm_state = sc->sm_returnstate;
    593 			}
    594 			break;
    595 		}
    596 		break;
    597 
    598 	case UCBADC_REGWRITE:
    599 		/*
    600 		 * In	: sc->sm_addr, sc->sm_reg (lower 16bit only)
    601 		 */
    602 #define TXSIB_REGWRITE_INIT	0
    603 #define TXSIB_REGWRITE_WRITE	1
    604 		switch (sc->sm_write_state) {
    605 		case TXSIB_REGWRITE_INIT:
    606 			sc->sm_writing = 1;
    607 			sc->sm_write_state = TXSIB_REGWRITE_WRITE;
    608 			sc->sm_state = UCBADC_REGREAD;
    609 
    610 			sc->sm_write_val = sc->sm_reg;
    611 			break;
    612 		case TXSIB_REGWRITE_WRITE:
    613 			sc->sm_writing = 0;
    614 			sc->sm_write_state = TXSIB_REGWRITE_INIT;
    615 			sc->sm_state = sc->sm_returnstate;
    616 
    617 			reg = sc->sm_reg;
    618 			reg |= TX39_SIBSF0_WRITE;
    619 			TX39_SIBSF0_REGDATA_CLR(reg);
    620 			reg = TX39_SIBSF0_REGDATA_SET(reg, sc->sm_write_val);
    621 			tx_conf_write(tc, TX39_SIBSF0CTRL_REG, reg);
    622 			break;
    623 		}
    624 		break;
    625 	}
    626 
    627 	return 0;
    628 }
    629 
    630 int
    631 ucbtp_input(sc)
    632 	struct ucbtp_softc *sc;
    633 {
    634 	int x, y;
    635 
    636 	if (!sc->sc_calibrated) {
    637 		DPRINTFN(2, ("x=%d y=%d p=%d\n",
    638 			     sc->sc_x, sc->sc_y, sc->sc_p));
    639 		printf("ucbtp_input: no calibration data\n");
    640 		return 0;
    641 	}
    642 
    643 	tpcalib_trans(&sc->sc_tpcalib, sc->sc_x, sc->sc_y, &x, &y);
    644 	DPRINTFN(2, ("x: %d->%d y: %d->%d pressure=%d\n",
    645 		     sc->sc_x, x, sc->sc_y, y, sc->sc_p));
    646 
    647 	if (sc->sc_p < UCBTS_PRESS_THRESHOLD) {
    648 		sc->sc_stat = UCBTS_STAT_RELEASE;
    649 		if (sc->sc_polling < UCBTS_TAP_THRESHOLD) {
    650 			DPRINTFN(2, ("TAP!\n"));
    651 			/* button 0 DOWN */
    652 			wsmouse_input(sc->sc_wsmousedev, 1, 0, 0, 0, 0);
    653 			/* button 0 UP */
    654 			wsmouse_input(sc->sc_wsmousedev, 0, 0, 0, 0, 0);
    655 		} else {
    656 			wsmouse_input(sc->sc_wsmousedev, 0,
    657 				      sc->sc_ox, sc->sc_oy, 0,
    658 				      WSMOUSE_INPUT_ABSOLUTE_X |
    659 				      WSMOUSE_INPUT_ABSOLUTE_Y);
    660 
    661 			DPRINTFN(2, ("RELEASE\n"));
    662 		}
    663 		sc->sc_polling = 0;
    664 
    665 		return 1;
    666 	}
    667 
    668 #ifdef TX391X /* debug */
    669 	if (sc->sc_polling == 1)
    670 		tx3912video_dot(x, y);
    671 	else
    672 		tx3912video_line(sc->sc_ox, sc->sc_oy, x, y);
    673 	sc->sc_ox = x, sc->sc_oy = y;
    674 #endif
    675 	wsmouse_input(sc->sc_wsmousedev, 1, x, y, 0,
    676 		      WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y);
    677 
    678 	return 0;
    679 }
    680 
    681 /*
    682  * access ops.
    683  */
    684 
    685 int
    686 ucbtp_enable(v)
    687 	void *v;
    688 {
    689 	/* not yet */
    690 	return 0;
    691 }
    692 
    693 void
    694 ucbtp_disable(v)
    695 	void *v;
    696 {
    697 	/* not yet */
    698 }
    699 
    700 int
    701 ucbtp_ioctl(v, cmd, data, flag, p)
    702 	void *v;
    703 	u_long cmd;
    704 	caddr_t data;
    705 	int flag;
    706 	struct proc *p;
    707 {
    708 	struct ucbtp_softc *sc = v;
    709 
    710 	DPRINTF(("%s(%d): ucbtp_ioctl(%08lx)\n", __FILE__, __LINE__, cmd));
    711 
    712 	switch (cmd) {
    713 	case WSMOUSEIO_GTYPE:
    714 		*(u_int *)data = WSMOUSE_TYPE_TPANEL;
    715 		break;
    716 
    717 	case WSMOUSEIO_SRES:
    718 		printf("%s(%d): WSMOUSRIO_SRES is not supported",
    719 		       __FILE__, __LINE__);
    720 		break;
    721 
    722 	case WSMOUSEIO_SCALIBCOORDS:
    723 	case WSMOUSEIO_GCALIBCOORDS:
    724                 return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, p);
    725 
    726 	default:
    727 		return (-1);
    728 	}
    729 	return (0);
    730 }
    731