Home | History | Annotate | Line # | Download | only in dev
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