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