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