Home | History | Annotate | Line # | Download | only in sa11x0
sa1111_kbc.c revision 1.2
      1  1.2  lukem /*      $NetBSD: sa1111_kbc.c,v 1.2 2003/07/15 00:24:50 lukem Exp $ */
      2  1.1    bsh 
      3  1.1    bsh /*
      4  1.1    bsh  * Copyright (c) 2002  Genetec Corporation.  All rights reserved.
      5  1.1    bsh  * Written by Hiroyuki Bessho for Genetec Corporation.
      6  1.1    bsh  *
      7  1.1    bsh  * Redistribution and use in source and binary forms, with or without
      8  1.1    bsh  * modification, are permitted provided that the following conditions
      9  1.1    bsh  * are met:
     10  1.1    bsh  * 1. Redistributions of source code must retain the above copyright
     11  1.1    bsh  *    notice, this list of conditions and the following disclaimer.
     12  1.1    bsh  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1    bsh  *    notice, this list of conditions and the following disclaimer in the
     14  1.1    bsh  *    documentation and/or other materials provided with the distribution.
     15  1.1    bsh  * 3. The name of Genetec Corporation may not be used to endorse or
     16  1.1    bsh  *    promote products derived from this software without specific prior
     17  1.1    bsh  *    written permission.
     18  1.1    bsh  *
     19  1.1    bsh  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
     20  1.1    bsh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1    bsh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1    bsh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
     23  1.1    bsh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1    bsh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1    bsh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1    bsh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1    bsh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1    bsh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1    bsh  * POSSIBILITY OF SUCH DAMAGE.
     30  1.1    bsh  *
     31  1.1    bsh  * Driver for keyboard controller in SA-1111 companion chip.
     32  1.1    bsh  *
     33  1.1    bsh  * PC keyboard driver (sys/dev/pckbc/pckbd.c) works only with 8042
     34  1.1    bsh  * keyboard controller driver (sys/dev/ic/pckbc.c).  This file
     35  1.1    bsh  * provides same functions as those of 8042 driver.
     36  1.1    bsh  *
     37  1.1    bsh  * XXX: we need cleaner interface between the keyboard driver and
     38  1.1    bsh  *      keyboard controller drivers.
     39  1.1    bsh  */
     40  1.1    bsh /*
     41  1.1    bsh  * Copyright (c) 1998
     42  1.1    bsh  *	Matthias Drochner.  All rights reserved.
     43  1.1    bsh  *
     44  1.1    bsh  * Redistribution and use in source and binary forms, with or without
     45  1.1    bsh  * modification, are permitted provided that the following conditions
     46  1.1    bsh  * are met:
     47  1.1    bsh  * 1. Redistributions of source code must retain the above copyright
     48  1.1    bsh  *    notice, this list of conditions and the following disclaimer.
     49  1.1    bsh  * 2. Redistributions in binary form must reproduce the above copyright
     50  1.1    bsh  *    notice, this list of conditions and the following disclaimer in the
     51  1.1    bsh  *    documentation and/or other materials provided with the distribution.
     52  1.1    bsh  * 3. All advertising materials mentioning features or use of this software
     53  1.1    bsh  *    must display the following acknowledgement:
     54  1.1    bsh  *	This product includes software developed for the NetBSD Project
     55  1.1    bsh  *	by Matthias Drochner.
     56  1.1    bsh  * 4. The name of the author may not be used to endorse or promote products
     57  1.1    bsh  *    derived from this software without specific prior written permission.
     58  1.1    bsh  *
     59  1.1    bsh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     60  1.1    bsh  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     61  1.1    bsh  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     62  1.1    bsh  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     63  1.1    bsh  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     64  1.1    bsh  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     65  1.1    bsh  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     66  1.1    bsh  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     67  1.1    bsh  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     68  1.1    bsh  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     69  1.1    bsh  */
     70  1.2  lukem 
     71  1.2  lukem #include <sys/cdefs.h>
     72  1.2  lukem __KERNEL_RCSID(0, "$NetBSD: sa1111_kbc.c,v 1.2 2003/07/15 00:24:50 lukem Exp $");
     73  1.1    bsh 
     74  1.1    bsh #include <sys/param.h>
     75  1.1    bsh #include <sys/systm.h>
     76  1.1    bsh #include <sys/types.h>
     77  1.1    bsh #include <sys/callout.h>
     78  1.1    bsh #include <sys/kernel.h>
     79  1.1    bsh #include <sys/proc.h>
     80  1.1    bsh #include <sys/conf.h>
     81  1.1    bsh #include <sys/device.h>
     82  1.1    bsh #include <sys/malloc.h>
     83  1.1    bsh #include <sys/errno.h>
     84  1.1    bsh #include <sys/queue.h>
     85  1.1    bsh #include <sys/lock.h>
     86  1.1    bsh 
     87  1.1    bsh #include <machine/bus.h>
     88  1.1    bsh #include <arm/sa11x0/sa1111_reg.h>
     89  1.1    bsh #include <arm/sa11x0/sa1111_var.h>
     90  1.1    bsh 
     91  1.1    bsh #include <dev/ic/pckbcvar.h>		/* for prototypes */
     92  1.1    bsh 
     93  1.1    bsh #include "pckbd.h"
     94  1.1    bsh #include "rnd.h"
     95  1.1    bsh #include "locators.h"
     96  1.1    bsh 
     97  1.1    bsh /* descriptor for one device command */
     98  1.1    bsh struct pckbc_devcmd {
     99  1.1    bsh 	TAILQ_ENTRY(pckbc_devcmd) next;
    100  1.1    bsh 	int flags;
    101  1.1    bsh #define KBC_CMDFLAG_SYNC 1 /* give descriptor back to caller */
    102  1.1    bsh #define KBC_CMDFLAG_SLOW 2
    103  1.1    bsh 	u_char cmd[4];
    104  1.1    bsh 	int cmdlen, cmdidx, retries;
    105  1.1    bsh 	u_char response[4];
    106  1.1    bsh 	int status, responselen, responseidx;
    107  1.1    bsh };
    108  1.1    bsh 
    109  1.1    bsh struct sackbc_softc {
    110  1.1    bsh 	struct device dev;
    111  1.1    bsh 
    112  1.1    bsh 	bus_space_tag_t    iot;
    113  1.1    bsh 	bus_space_handle_t ioh;
    114  1.1    bsh 
    115  1.1    bsh 	void	*ih_rx;			/* receive interrupt */
    116  1.1    bsh 	int	intr;			/* interrupt number */
    117  1.1    bsh 
    118  1.1    bsh 	int	polling;	/* don't process data in interrupt handler */
    119  1.1    bsh 	int	poll_stat;	/* data read from inr handler if polling */
    120  1.1    bsh 	int	poll_data;	/* status read from intr handler if polling */
    121  1.1    bsh 
    122  1.1    bsh 	TAILQ_HEAD(, pckbc_devcmd) cmdqueue; /* active commands */
    123  1.1    bsh 	TAILQ_HEAD(, pckbc_devcmd) freequeue; /* free commands */
    124  1.1    bsh #define NCMD  5
    125  1.1    bsh 	struct pckbc_devcmd cmd[NCMD];
    126  1.1    bsh 
    127  1.1    bsh 	struct callout t_cleanup;
    128  1.1    bsh 	pckbc_inputfcn inputhandler;
    129  1.1    bsh 	void *inputarg;
    130  1.1    bsh 	const char *subname;
    131  1.1    bsh 
    132  1.1    bsh };
    133  1.1    bsh 
    134  1.1    bsh #define CMD_IN_QUEUE(q) (TAILQ_FIRST(&(q)->cmdqueue) != NULL)
    135  1.1    bsh 
    136  1.1    bsh #define N_KBC_SLOTS  2
    137  1.1    bsh /*static struct sackbc_softc *sackbc_slot[N_KBC_SLOTS] = { NULL, NULL };*/
    138  1.1    bsh 
    139  1.1    bsh static	int	sackbc_match(struct device *, struct cfdata *, void *);
    140  1.1    bsh static	void	sackbc_attach(struct device *, struct device *, void *);
    141  1.1    bsh static int	 sackbc_cmdresponse( struct sackbc_softc *, int );
    142  1.1    bsh 
    143  1.1    bsh CFATTACH_DECL(sackbc, sizeof(struct sackbc_softc), sackbc_match,
    144  1.1    bsh     sackbc_attach, NULL, NULL);
    145  1.1    bsh 
    146  1.1    bsh /* XXX should not be here */
    147  1.1    bsh #define KBC_DEVCMD_ACK 0xfa
    148  1.1    bsh #define KBC_DEVCMD_RESEND 0xfe
    149  1.1    bsh 
    150  1.1    bsh #define	KBD_DELAY	DELAY(8)
    151  1.1    bsh 
    152  1.1    bsh /*#define SACKBCDEBUG*/
    153  1.1    bsh 
    154  1.1    bsh #ifdef SACKBCDEBUG
    155  1.1    bsh #define DPRINTF(arg)  printf arg
    156  1.1    bsh #else
    157  1.1    bsh #define DPRINTF(arg)
    158  1.1    bsh #endif
    159  1.1    bsh 
    160  1.1    bsh static void sackbc_poll_cmd1( struct sackbc_softc *, struct pckbc_devcmd * );
    161  1.1    bsh 
    162  1.1    bsh 
    163  1.1    bsh 
    164  1.1    bsh static int
    165  1.1    bsh sackbc_match(struct device *parent, struct cfdata *cf, void *aux)
    166  1.1    bsh {
    167  1.1    bsh 	struct sa1111_attach_args *aa = (struct sa1111_attach_args *)aux;
    168  1.1    bsh 
    169  1.1    bsh 	switch( aa->sa_addr ){
    170  1.1    bsh 	case SACC_KBD0: case SACC_KBD1:
    171  1.1    bsh 		return 1;
    172  1.1    bsh 	}
    173  1.1    bsh 	return 0;
    174  1.1    bsh }
    175  1.1    bsh 
    176  1.1    bsh #if 0
    177  1.1    bsh static int
    178  1.1    bsh sackbc_txint( void *cookie )
    179  1.1    bsh {
    180  1.1    bsh 	struct sackbc_softc *sc = cookie;
    181  1.1    bsh 
    182  1.1    bsh 	bus_space_read_4( sc->iot, sc->ioh, SACCKBD_STAT );
    183  1.1    bsh 
    184  1.1    bsh 	return 0;
    185  1.1    bsh }
    186  1.1    bsh #endif
    187  1.1    bsh 
    188  1.1    bsh static int
    189  1.1    bsh sackbc_rxint( void *cookie )
    190  1.1    bsh {
    191  1.1    bsh 	struct sackbc_softc *sc = cookie;
    192  1.1    bsh 	int stat, code=-1;
    193  1.1    bsh 
    194  1.1    bsh 	stat = bus_space_read_4( sc->iot, sc->ioh, SACCKBD_STAT );
    195  1.1    bsh 	DPRINTF(( "sackbc_rxint stat=%x\n", stat ));
    196  1.1    bsh 	if( stat & KBDSTAT_RXF ){
    197  1.1    bsh 		code = bus_space_read_4( sc->iot, sc->ioh, SACCKBD_DATA );
    198  1.1    bsh 
    199  1.1    bsh 		if( sc->polling ){
    200  1.1    bsh 			sc->poll_data = code;
    201  1.1    bsh 			sc->poll_stat = stat;
    202  1.1    bsh 		}
    203  1.1    bsh 		else if (CMD_IN_QUEUE(sc) && sackbc_cmdresponse(sc, code))
    204  1.1    bsh 			;
    205  1.1    bsh 		else if( sc->inputhandler ){
    206  1.1    bsh 			(* sc->inputhandler)( sc->inputarg, code );
    207  1.1    bsh 		}
    208  1.1    bsh 		return 1;
    209  1.1    bsh 	}
    210  1.1    bsh 
    211  1.1    bsh 	return 0;
    212  1.1    bsh }
    213  1.1    bsh 
    214  1.1    bsh static int
    215  1.1    bsh sackbcprint(void *aux, const char *pnp)
    216  1.1    bsh {
    217  1.1    bsh 	return (QUIET);
    218  1.1    bsh }
    219  1.1    bsh 
    220  1.1    bsh static void
    221  1.1    bsh sackbc_setup_intrhandler(struct sackbc_softc *sc)
    222  1.1    bsh {
    223  1.1    bsh 	if( !(sc->polling) && sc->ih_rx==NULL ){
    224  1.1    bsh 		sc->ih_rx = sacc_intr_establish(
    225  1.1    bsh 			(sacc_chipset_tag_t *)(sc->dev.dv_parent),
    226  1.1    bsh 			sc->intr+1, IST_EDGE_RAISE, IPL_TTY, sackbc_rxint, sc );
    227  1.1    bsh 		if( sc->ih_rx == NULL ){
    228  1.1    bsh 			printf( "%s: can't establish interrupt\n",
    229  1.1    bsh 			    sc->dev.dv_xname );
    230  1.1    bsh 		}
    231  1.1    bsh 	}
    232  1.1    bsh }
    233  1.1    bsh 
    234  1.1    bsh static void
    235  1.1    bsh sackbc_disable_intrhandler( struct sackbc_softc *sc )
    236  1.1    bsh {
    237  1.1    bsh 	if( sc->polling && sc->ih_rx ){
    238  1.1    bsh 		sacc_intr_disestablish(
    239  1.1    bsh 			(sacc_chipset_tag_t *)(sc->dev.dv_parent),
    240  1.1    bsh 			sc->ih_rx );
    241  1.1    bsh 		sc->ih_rx = NULL;
    242  1.1    bsh 	}
    243  1.1    bsh }
    244  1.1    bsh 
    245  1.1    bsh static int
    246  1.1    bsh sackbc_submatch(struct device *parent, struct cfdata *cf, void *aux)
    247  1.1    bsh {
    248  1.1    bsh 	struct pckbc_attach_args *pa = aux;
    249  1.1    bsh 
    250  1.1    bsh 	DPRINTF(( "slot = %d ", cf->cf_loc[SACKBCCF_SLOT] ));
    251  1.1    bsh 
    252  1.1    bsh 	if( pa->pa_slot == PCKBCCF_SLOT_DEFAULT )
    253  1.1    bsh 		pa->pa_slot = cf->cf_loc[SACKBCCF_SLOT];
    254  1.1    bsh 
    255  1.1    bsh 	return config_match(parent, cf, aux);
    256  1.1    bsh }
    257  1.1    bsh 
    258  1.1    bsh static	void
    259  1.1    bsh sackbc_attach(struct device *parent, struct device *self, void *aux)
    260  1.1    bsh {
    261  1.1    bsh 	struct sackbc_softc *sc = (struct sackbc_softc *)self;
    262  1.1    bsh 	struct sacc_softc *psc = (struct sacc_softc *)parent;
    263  1.1    bsh 	struct sa1111_attach_args *aa = (struct sa1111_attach_args *)aux;
    264  1.1    bsh 	uint32_t tmp, clock_bit;
    265  1.1    bsh 	int i, found, intr;
    266  1.1    bsh 
    267  1.1    bsh 	switch( aa->sa_addr ){
    268  1.1    bsh 	case SACC_KBD0: clock_bit = (1<<6); intr = 21; break;
    269  1.1    bsh 	case SACC_KBD1: clock_bit = (1<<5); intr = 18; break;
    270  1.1    bsh 	default:
    271  1.1    bsh 		return;
    272  1.1    bsh 	}
    273  1.1    bsh 
    274  1.1    bsh 	if( aa->sa_size <= 0 )
    275  1.1    bsh 		aa->sa_size = SACCKBD_SIZE;
    276  1.1    bsh 	if( aa->sa_intr == SACCCF_INTR_DEFAULT )
    277  1.1    bsh 		aa->sa_intr = intr;
    278  1.1    bsh 
    279  1.1    bsh 	sc->iot = psc->sc_iot;
    280  1.1    bsh 	if( bus_space_subregion( psc->sc_iot, psc->sc_ioh,
    281  1.1    bsh 	    aa->sa_addr, aa->sa_size, &sc->ioh ) ){
    282  1.1    bsh 		printf( ": can't map subregion\n" );
    283  1.1    bsh 		return;
    284  1.1    bsh 	}
    285  1.1    bsh 
    286  1.1    bsh 	/* enable clock for PS/2 kbd or mouse */
    287  1.1    bsh 	tmp = bus_space_read_4( psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR );
    288  1.1    bsh 	bus_space_write_4( psc->sc_iot, psc->sc_ioh, SACCSC_SKPCR,
    289  1.1    bsh 	    tmp | clock_bit );
    290  1.1    bsh 
    291  1.1    bsh 	sc->ih_rx = NULL;
    292  1.1    bsh 	sc->intr = aa->sa_intr;
    293  1.1    bsh 	sc->inputhandler = NULL;
    294  1.1    bsh 	sc->subname = sc->dev.dv_xname;
    295  1.1    bsh 
    296  1.1    bsh 	TAILQ_INIT(&sc->cmdqueue);
    297  1.1    bsh 	TAILQ_INIT(&sc->freequeue);
    298  1.1    bsh 
    299  1.1    bsh 	for (i = 0; i < NCMD; i++) {
    300  1.1    bsh 		TAILQ_INSERT_TAIL(&sc->freequeue, &(sc->cmd[i]), next);
    301  1.1    bsh 	}
    302  1.1    bsh 	sc->polling = 0;
    303  1.1    bsh 
    304  1.1    bsh 	tmp = bus_space_read_4( sc->iot, sc->ioh, SACCKBD_CR );
    305  1.1    bsh 	bus_space_write_4( sc->iot, sc->ioh, SACCKBD_CR, tmp | KBDCR_ENA );
    306  1.1    bsh 
    307  1.1    bsh 	/* XXX: this is necessary to get keyboard working. but I don't know why */
    308  1.1    bsh 	bus_space_write_4( sc->iot, sc->ioh, SACCKBD_CLKDIV, 2 );
    309  1.1    bsh 
    310  1.1    bsh 	tmp = bus_space_read_4( sc->iot, sc->ioh, SACCKBD_STAT );
    311  1.1    bsh 	if( (tmp & KBDSTAT_ENA) == 0 ){
    312  1.1    bsh 		printf("??? can't enable KBD controller\n");
    313  1.1    bsh 		return;
    314  1.1    bsh 	}
    315  1.1    bsh 
    316  1.1    bsh 	printf("\n");
    317  1.1    bsh 
    318  1.1    bsh 	{
    319  1.1    bsh 		struct pckbc_attach_args pa;
    320  1.1    bsh 
    321  1.1    bsh 		pa.pa_tag = sc;
    322  1.1    bsh 		pa.pa_slot = PCKBCCF_SLOT_DEFAULT; /* Bogus */
    323  1.1    bsh 
    324  1.1    bsh 		found = (config_found_sm(self, &pa,
    325  1.1    bsh 		    sackbcprint, sackbc_submatch) != NULL);
    326  1.1    bsh 
    327  1.1    bsh #if 0 && NRND > 0			/* XXX: not yet */
    328  1.1    bsh 		if (found && (t->t_slotdata[slot] != NULL))
    329  1.1    bsh 			rnd_attach_source(&t->t_slotdata[slot]->rnd_source,
    330  1.1    bsh 			    sc->subname[slot], RND_TYPE_TTY, 0);
    331  1.1    bsh #endif
    332  1.1    bsh 	}
    333  1.1    bsh 
    334  1.1    bsh }
    335  1.1    bsh 
    336  1.1    bsh 
    337  1.1    bsh static inline int
    338  1.1    bsh sackbc_wait_output( struct sackbc_softc *sc )
    339  1.1    bsh {
    340  1.1    bsh 	u_int i, stat;
    341  1.1    bsh 
    342  1.1    bsh 	for (i = 100000; i; i--){
    343  1.1    bsh 		stat = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_STAT);
    344  1.1    bsh 		delay(100);
    345  1.1    bsh 		if( stat & KBDSTAT_TXE)
    346  1.1    bsh 			return 1;
    347  1.1    bsh 	}
    348  1.1    bsh 	return 0;
    349  1.1    bsh }
    350  1.1    bsh 
    351  1.1    bsh static int
    352  1.1    bsh sackbc_poll_data1( struct sackbc_softc *sc )
    353  1.1    bsh {
    354  1.1    bsh 	int i, s, stat, c = -1;
    355  1.1    bsh 
    356  1.1    bsh 	s = spltty();
    357  1.1    bsh 
    358  1.1    bsh 	if (sc->polling){
    359  1.1    bsh 		stat	= sc->poll_stat;
    360  1.1    bsh 		c	= sc->poll_data;
    361  1.1    bsh 		sc->poll_data = -1;
    362  1.1    bsh 		sc->poll_stat = -1;
    363  1.1    bsh 		if( stat >= 0 &&
    364  1.1    bsh 		    (stat & (KBDSTAT_RXF|KBDSTAT_STP)) == KBDSTAT_RXF ){
    365  1.1    bsh 			splx(s);
    366  1.1    bsh 			return c;
    367  1.1    bsh 		}
    368  1.1    bsh 	}
    369  1.1    bsh 
    370  1.1    bsh 	/* if 1 port read takes 1us (?), this polls for 100ms */
    371  1.1    bsh 	for (i = 100000; i; i--) {
    372  1.1    bsh 		stat = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_STAT);
    373  1.1    bsh 		if( (stat & (KBDSTAT_RXF|KBDSTAT_STP)) == KBDSTAT_RXF ){
    374  1.1    bsh 			KBD_DELAY;
    375  1.1    bsh 			c = bus_space_read_4(sc->iot, sc->ioh, SACCKBD_DATA);
    376  1.1    bsh 			break;
    377  1.1    bsh 		}
    378  1.1    bsh 	}
    379  1.1    bsh 
    380  1.1    bsh 	splx(s);
    381  1.1    bsh 	return (c);
    382  1.1    bsh }
    383  1.1    bsh 
    384  1.1    bsh static int
    385  1.1    bsh sackbc_send_cmd( struct sackbc_softc *sc, int val )
    386  1.1    bsh {
    387  1.1    bsh 	if ( !sackbc_wait_output(sc) )
    388  1.1    bsh 		return (0);
    389  1.1    bsh 	bus_space_write_1( sc->iot, sc->ioh, SACCKBD_DATA, val );
    390  1.1    bsh 	return (1);
    391  1.1    bsh }
    392  1.1    bsh 
    393  1.1    bsh #define sackbc_send_devcmd	sackbc_send_cmd
    394  1.1    bsh 
    395  1.1    bsh /*
    396  1.1    bsh  * Clean up a command queue, throw away everything.
    397  1.1    bsh  */
    398  1.1    bsh static void
    399  1.1    bsh sackbc_cleanqueue( struct sackbc_softc *sc )
    400  1.1    bsh {
    401  1.1    bsh 	struct pckbc_devcmd *cmd;
    402  1.1    bsh #ifdef SACKBCDEBUG
    403  1.1    bsh 	int i;
    404  1.1    bsh #endif
    405  1.1    bsh 
    406  1.1    bsh 	while ((cmd = TAILQ_FIRST(&sc->cmdqueue))) {
    407  1.1    bsh 		TAILQ_REMOVE(&sc->cmdqueue, cmd, next);
    408  1.1    bsh #ifdef SACKBCDEBUG
    409  1.1    bsh 		printf("sackbc_cleanqueue: removing");
    410  1.1    bsh 		for (i = 0; i < cmd->cmdlen; i++)
    411  1.1    bsh 			printf(" %02x", cmd->cmd[i]);
    412  1.1    bsh 		printf("\n");
    413  1.1    bsh #endif
    414  1.1    bsh 		TAILQ_INSERT_TAIL(&sc->freequeue, cmd, next);
    415  1.1    bsh 	}
    416  1.1    bsh }
    417  1.1    bsh 
    418  1.1    bsh /*
    419  1.1    bsh  * Timeout error handler: clean queues and data port.
    420  1.1    bsh  * XXX could be less invasive.
    421  1.1    bsh  */
    422  1.1    bsh static void
    423  1.1    bsh sackbc_cleanup(void *self)
    424  1.1    bsh {
    425  1.1    bsh 	struct sackbc_softc *sc = self;
    426  1.1    bsh 	int s;
    427  1.1    bsh 
    428  1.1    bsh 	printf("sackbc: command timeout\n");
    429  1.1    bsh 
    430  1.1    bsh 	s = spltty();
    431  1.1    bsh 
    432  1.1    bsh 	sackbc_cleanqueue(sc);
    433  1.1    bsh 
    434  1.1    bsh 	while (bus_space_read_4(sc->iot, sc->ioh, SACCKBD_STAT) & KBDSTAT_RXF) {
    435  1.1    bsh 		KBD_DELAY;
    436  1.1    bsh 		(void) bus_space_read_4(sc->iot, sc->ioh, SACCKBD_DATA);
    437  1.1    bsh 	}
    438  1.1    bsh 
    439  1.1    bsh 	/* reset KBC? */
    440  1.1    bsh 
    441  1.1    bsh 	splx(s);
    442  1.1    bsh }
    443  1.1    bsh 
    444  1.1    bsh 
    445  1.1    bsh /*
    446  1.1    bsh  * Pass command to device during normal operation.
    447  1.1    bsh  * to be called at spltty()
    448  1.1    bsh  */
    449  1.1    bsh static void
    450  1.1    bsh sackbc_start( struct sackbc_softc *sc )
    451  1.1    bsh {
    452  1.1    bsh 	struct pckbc_devcmd *cmd = TAILQ_FIRST(&sc->cmdqueue);
    453  1.1    bsh 
    454  1.1    bsh 	if (sc->polling) {
    455  1.1    bsh 		while(cmd){
    456  1.1    bsh 			sackbc_poll_cmd1(sc, cmd);
    457  1.1    bsh 			if (cmd->status)
    458  1.1    bsh 				printf("sackbc_start: command error\n");
    459  1.1    bsh 
    460  1.1    bsh 			TAILQ_REMOVE(&sc->cmdqueue, cmd, next);
    461  1.1    bsh 			if (cmd->flags & KBC_CMDFLAG_SYNC)
    462  1.1    bsh 				wakeup(cmd);
    463  1.1    bsh 			else {
    464  1.1    bsh 				callout_stop(&sc->t_cleanup);
    465  1.1    bsh 				TAILQ_INSERT_TAIL(&sc->freequeue, cmd, next);
    466  1.1    bsh 			}
    467  1.1    bsh 			cmd = TAILQ_FIRST(&sc->cmdqueue);
    468  1.1    bsh 		}
    469  1.1    bsh 		return;
    470  1.1    bsh 	}
    471  1.1    bsh 
    472  1.1    bsh 	if (!sackbc_send_devcmd(sc, cmd->cmd[cmd->cmdidx])) {
    473  1.1    bsh 		printf("sackbc_start: send error\n");
    474  1.1    bsh 		/* XXX what now? */
    475  1.1    bsh 		return;
    476  1.1    bsh 	}
    477  1.1    bsh }
    478  1.1    bsh 
    479  1.1    bsh /*
    480  1.1    bsh  * Handle command responses coming in asynchonously,
    481  1.1    bsh  * return nonzero if valid response.
    482  1.1    bsh  * to be called at spltty()
    483  1.1    bsh  */
    484  1.1    bsh static int
    485  1.1    bsh sackbc_cmdresponse( struct sackbc_softc *sc, int data)
    486  1.1    bsh {
    487  1.1    bsh 	struct pckbc_devcmd *cmd = TAILQ_FIRST(&sc->cmdqueue);
    488  1.1    bsh #ifdef DIAGNOSTIC
    489  1.1    bsh 	if (!cmd)
    490  1.1    bsh 		panic("sackbc_cmdresponse: no active command");
    491  1.1    bsh #endif
    492  1.1    bsh 	if (cmd->cmdidx < cmd->cmdlen) {
    493  1.1    bsh 		if (data != KBC_DEVCMD_ACK && data != KBC_DEVCMD_RESEND)
    494  1.1    bsh 			return (0);
    495  1.1    bsh 
    496  1.1    bsh 		if (data == KBC_DEVCMD_RESEND) {
    497  1.1    bsh 			if (cmd->retries++ < 5) {
    498  1.1    bsh 				/* try again last command */
    499  1.1    bsh 				goto restart;
    500  1.1    bsh 			} else {
    501  1.1    bsh 				printf("pckbc: cmd failed\n");
    502  1.1    bsh 				cmd->status = EIO;
    503  1.1    bsh 				/* dequeue */
    504  1.1    bsh 			}
    505  1.1    bsh 		} else {
    506  1.1    bsh 			if (++cmd->cmdidx < cmd->cmdlen)
    507  1.1    bsh 				goto restart;
    508  1.1    bsh 			if (cmd->responselen)
    509  1.1    bsh 				return (1);
    510  1.1    bsh 			/* else dequeue */
    511  1.1    bsh 		}
    512  1.1    bsh 	} else if (cmd->responseidx < cmd->responselen) {
    513  1.1    bsh 		cmd->response[cmd->responseidx++] = data;
    514  1.1    bsh 		if (cmd->responseidx < cmd->responselen)
    515  1.1    bsh 			return (1);
    516  1.1    bsh 		/* else dequeue */
    517  1.1    bsh 	} else
    518  1.1    bsh 		return (0);
    519  1.1    bsh 
    520  1.1    bsh 	/* dequeue: */
    521  1.1    bsh 	TAILQ_REMOVE(&sc->cmdqueue, cmd, next);
    522  1.1    bsh 	if (cmd->flags & KBC_CMDFLAG_SYNC)
    523  1.1    bsh 		wakeup(cmd);
    524  1.1    bsh 	else {
    525  1.1    bsh 		callout_stop(&sc->t_cleanup);
    526  1.1    bsh 		TAILQ_INSERT_TAIL(&sc->freequeue, cmd, next);
    527  1.1    bsh 	}
    528  1.1    bsh 	if (!CMD_IN_QUEUE(sc))
    529  1.1    bsh 		return (1);
    530  1.1    bsh restart:
    531  1.1    bsh 	sackbc_start(sc);
    532  1.1    bsh 	return (1);
    533  1.1    bsh }
    534  1.1    bsh 
    535  1.1    bsh /*
    536  1.1    bsh  * Pass command to device, poll for ACK and data.
    537  1.1    bsh  * to be called at spltty()
    538  1.1    bsh  */
    539  1.1    bsh static void
    540  1.1    bsh sackbc_poll_cmd1( struct sackbc_softc *sc, struct pckbc_devcmd *cmd )
    541  1.1    bsh {
    542  1.1    bsh 	int i, c = 0;
    543  1.1    bsh 
    544  1.1    bsh 	while (cmd->cmdidx < cmd->cmdlen) {
    545  1.1    bsh 		DPRINTF((" tx: %x ", cmd->cmd[cmd->cmdidx]));
    546  1.1    bsh 		if (!sackbc_send_devcmd(sc, cmd->cmd[cmd->cmdidx])) {
    547  1.1    bsh 			printf("sackbc_cmd: send error\n");
    548  1.1    bsh 			cmd->status = EIO;
    549  1.1    bsh 			return;
    550  1.1    bsh 		}
    551  1.1    bsh 		delay(1000);
    552  1.1    bsh 		for (i = 10; i; i--) { /* 1s ??? */
    553  1.1    bsh 			c = sackbc_poll_data1(sc);
    554  1.1    bsh 			if (c != -1){
    555  1.1    bsh 				DPRINTF((" rx: %x", c ));
    556  1.1    bsh 				break;
    557  1.1    bsh 			}
    558  1.1    bsh 		}
    559  1.1    bsh 
    560  1.1    bsh 		if (c == KBC_DEVCMD_ACK) {
    561  1.1    bsh 			cmd->cmdidx++;
    562  1.1    bsh 			continue;
    563  1.1    bsh 		}
    564  1.1    bsh 		if (c == KBC_DEVCMD_RESEND) {
    565  1.1    bsh 			DPRINTF(("sackbc_cmd: RESEND\n"));
    566  1.1    bsh 
    567  1.1    bsh 			if (cmd->retries++ < 5)
    568  1.1    bsh 				continue;
    569  1.1    bsh 			else {
    570  1.1    bsh 				DPRINTF(("sackbc: cmd failed\n"));
    571  1.1    bsh 
    572  1.1    bsh 				cmd->status = EIO;
    573  1.1    bsh 				return;
    574  1.1    bsh 			}
    575  1.1    bsh 		}
    576  1.1    bsh 		if (c == -1) {
    577  1.1    bsh 			DPRINTF(("pckbc_cmd: timeout\n"));
    578  1.1    bsh 
    579  1.1    bsh 			cmd->status = EIO;
    580  1.1    bsh 			return;
    581  1.1    bsh 		}
    582  1.1    bsh 		DPRINTF(("pckbc_cmd: lost 0x%x\n", c));
    583  1.1    bsh 
    584  1.1    bsh 	}
    585  1.1    bsh 
    586  1.1    bsh 	while (cmd->responseidx < cmd->responselen) {
    587  1.1    bsh 		if (cmd->flags & KBC_CMDFLAG_SLOW)
    588  1.1    bsh 			i = 100; /* 10s ??? */
    589  1.1    bsh 		else
    590  1.1    bsh 			i = 10; /* 1s ??? */
    591  1.1    bsh 		while (i--) {
    592  1.1    bsh 			c = sackbc_poll_data1(sc);
    593  1.1    bsh 			if (c != -1){
    594  1.1    bsh 				DPRINTF((" resp: %x", c));
    595  1.1    bsh 				break;
    596  1.1    bsh 			}
    597  1.1    bsh 		}
    598  1.1    bsh 		if (c == -1) {
    599  1.1    bsh 			DPRINTF(("pckbc_cmd: no response"));
    600  1.1    bsh 
    601  1.1    bsh 			cmd->status = ETIMEDOUT;
    602  1.1    bsh 			return;
    603  1.1    bsh 		} else
    604  1.1    bsh 			cmd->response[cmd->responseidx++] = c;
    605  1.1    bsh 	}
    606  1.1    bsh 	DPRINTF(("\n"));
    607  1.1    bsh }
    608  1.1    bsh 
    609  1.1    bsh 
    610  1.1    bsh /*
    611  1.1    bsh  * Glue functions for pckbd on sackbc.
    612  1.1    bsh  * These functions emulate those in dev/ic/pckbc.c.
    613  1.1    bsh  *
    614  1.1    bsh  */
    615  1.1    bsh 
    616  1.1    bsh void
    617  1.1    bsh pckbc_set_inputhandler( pckbc_tag_t self, pckbc_slot_t slot,
    618  1.1    bsh     pckbc_inputfcn func, void *arg, char *name)
    619  1.1    bsh {
    620  1.1    bsh 	struct sackbc_softc *sc = (struct sackbc_softc *) self;
    621  1.1    bsh 
    622  1.1    bsh 	if( sc == NULL )
    623  1.1    bsh 		return;
    624  1.1    bsh 
    625  1.1    bsh 	DPRINTF(( "set_inputhandler %p %p\n", func, arg ));
    626  1.1    bsh 
    627  1.1    bsh 	sc->inputhandler = func;
    628  1.1    bsh 	sc->inputarg = arg;
    629  1.1    bsh 	sc->subname = name;
    630  1.1    bsh 
    631  1.1    bsh 	sackbc_setup_intrhandler(sc);
    632  1.1    bsh }
    633  1.1    bsh 
    634  1.1    bsh 
    635  1.1    bsh /* for use in autoconfiguration */
    636  1.1    bsh int
    637  1.1    bsh pckbc_poll_cmd(pckbc_tag_t self, pckbc_slot_t slot,
    638  1.1    bsh     u_char *cmd, int len, int responselen, u_char *respbuf, int slow)
    639  1.1    bsh {
    640  1.1    bsh 	struct pckbc_devcmd nc;
    641  1.1    bsh struct sackbc_softc *sc = (struct sackbc_softc *) self;
    642  1.1    bsh 
    643  1.1    bsh 	if( sc == NULL )
    644  1.1    bsh 		return EINVAL;
    645  1.1    bsh 
    646  1.1    bsh 	if ((len > 4) || (responselen > 4))
    647  1.1    bsh 		return EINVAL;
    648  1.1    bsh 
    649  1.1    bsh 	memset(&nc, 0, sizeof(nc));
    650  1.1    bsh 	memcpy(nc.cmd, cmd, len);
    651  1.1    bsh 	nc.cmdlen = len;
    652  1.1    bsh 	nc.responselen = responselen;
    653  1.1    bsh 	nc.flags = (slow ? KBC_CMDFLAG_SLOW : 0);
    654  1.1    bsh 
    655  1.1    bsh 	sackbc_poll_cmd1(sc, &nc);
    656  1.1    bsh 
    657  1.1    bsh 	if (nc.status == 0 && respbuf)
    658  1.1    bsh 		memcpy(respbuf, nc.response, responselen);
    659  1.1    bsh 
    660  1.1    bsh 	return (nc.status);
    661  1.1    bsh }
    662  1.1    bsh 
    663  1.1    bsh 
    664  1.1    bsh /*
    665  1.1    bsh  * switch scancode translation on / off
    666  1.1    bsh  * return nonzero on success
    667  1.1    bsh  */
    668  1.1    bsh int
    669  1.1    bsh pckbc_xt_translation(pckbc_tag_t self, pckbc_slot_t slot, int on)
    670  1.1    bsh {
    671  1.1    bsh 	/* KBD/Mouse controller doesn't have scancode translation */
    672  1.1    bsh 	return !on;
    673  1.1    bsh }
    674  1.1    bsh 
    675  1.1    bsh void
    676  1.1    bsh pckbc_slot_enable(pckbc_tag_t self, pckbc_slot_t slot, int on)
    677  1.1    bsh {
    678  1.1    bsh #if 0
    679  1.1    bsh 	struct sackbc_softc *sc = (struct sackbc_softc *) self;
    680  1.1    bsh 	int cmd;
    681  1.1    bsh 
    682  1.1    bsh 	cmd = on ? KBC_KBDENABLE : KBC_KBDDISABLE;
    683  1.1    bsh 	if ( !sackbc_send_cmd(sc, cmd ) )
    684  1.1    bsh 		printf("sackbc_slot_enable(%d) failed\n", on);
    685  1.1    bsh #endif
    686  1.1    bsh }
    687  1.1    bsh 
    688  1.1    bsh 
    689  1.1    bsh void
    690  1.1    bsh pckbc_flush(pckbc_tag_t self, pckbc_slot_t slot)
    691  1.1    bsh {
    692  1.1    bsh 	struct sackbc_softc *sc  = (struct sackbc_softc *)self;
    693  1.1    bsh 
    694  1.1    bsh 	(void) sackbc_poll_data1(sc);
    695  1.1    bsh }
    696  1.1    bsh 
    697  1.1    bsh #if 0
    698  1.1    bsh int
    699  1.1    bsh sackbc_poll_data( struct sackbc_softc *sc )
    700  1.1    bsh {
    701  1.1    bsh 	struct pckbc_internal *t = self;
    702  1.1    bsh 	struct pckbc_slotdata *q = t->t_slotdata[slot];
    703  1.1    bsh 	int c;
    704  1.1    bsh 
    705  1.1    bsh 	c = pckbc_poll_data1(t, slot, t->t_haveaux);
    706  1.1    bsh 	if (c != -1 && q && CMD_IN_QUEUE(q)) {
    707  1.1    bsh 		/* we jumped into a running command - try to
    708  1.1    bsh 		 deliver the response */
    709  1.1    bsh 		if (pckbc_cmdresponse(t, slot, c))
    710  1.1    bsh 			return (-1);
    711  1.1    bsh 	}
    712  1.1    bsh 	return (c);
    713  1.1    bsh }
    714  1.1    bsh #endif
    715  1.1    bsh 
    716  1.1    bsh void
    717  1.1    bsh pckbc_set_poll(pckbc_tag_t self, pckbc_slot_t slot, int on)
    718  1.1    bsh {
    719  1.1    bsh 	struct sackbc_softc *sc = (struct sackbc_softc *)self;
    720  1.1    bsh 	int s;
    721  1.1    bsh 
    722  1.1    bsh 	s = spltty();
    723  1.1    bsh 
    724  1.1    bsh 	if( sc->polling != on ){
    725  1.1    bsh 
    726  1.1    bsh 		sc->polling = on;
    727  1.1    bsh 
    728  1.1    bsh 		if( on ){
    729  1.1    bsh 			sc->poll_data = sc->poll_stat = -1;
    730  1.1    bsh 			sackbc_disable_intrhandler(sc);
    731  1.1    bsh 		}
    732  1.1    bsh 		else {
    733  1.1    bsh 			/*
    734  1.1    bsh 			 * If disabling polling on a device that's
    735  1.1    bsh 			 * been configured, make sure there are no
    736  1.1    bsh 			 * bytes left in the FIFO, holding up the
    737  1.1    bsh 			 * interrupt line.  Otherwise we won't get any
    738  1.1    bsh 			 * further interrupts.
    739  1.1    bsh 			 */
    740  1.1    bsh 			sackbc_rxint(sc);
    741  1.1    bsh 			sackbc_setup_intrhandler(sc);
    742  1.1    bsh 		}
    743  1.1    bsh 	}
    744  1.1    bsh 	splx(s);
    745  1.1    bsh }
    746  1.1    bsh 
    747  1.1    bsh /*
    748  1.1    bsh  * Put command into the device's command queue, return zero or errno.
    749  1.1    bsh  */
    750  1.1    bsh int
    751  1.1    bsh pckbc_enqueue_cmd( pckbc_tag_t self, pckbc_slot_t slot, u_char *cmd,
    752  1.1    bsh     int len, int responselen, int sync, u_char *respbuf)
    753  1.1    bsh {
    754  1.1    bsh 	struct sackbc_softc *sc = (struct sackbc_softc *)self;
    755  1.1    bsh 	struct pckbc_devcmd *nc;
    756  1.1    bsh 	int s, isactive, res = 0;
    757  1.1    bsh 
    758  1.1    bsh 	if ( sc == NULL || (len > 4) || (responselen > 4) )
    759  1.1    bsh 		return (EINVAL);
    760  1.1    bsh 
    761  1.1    bsh 	s = spltty();
    762  1.1    bsh 	nc = TAILQ_FIRST(&sc->freequeue);
    763  1.1    bsh 	if (nc) {
    764  1.1    bsh 		TAILQ_REMOVE(&sc->freequeue, nc, next);
    765  1.1    bsh 	}
    766  1.1    bsh 	splx(s);
    767  1.1    bsh 	if (!nc)
    768  1.1    bsh 		return (ENOMEM);
    769  1.1    bsh 
    770  1.1    bsh 	memset(nc, 0, sizeof(*nc));
    771  1.1    bsh 	memcpy(nc->cmd, cmd, len);
    772  1.1    bsh 	nc->cmdlen = len;
    773  1.1    bsh 	nc->responselen = responselen;
    774  1.1    bsh 	nc->flags = (sync ? KBC_CMDFLAG_SYNC : 0);
    775  1.1    bsh 
    776  1.1    bsh 	s = spltty();
    777  1.1    bsh 
    778  1.1    bsh 	if (sc->polling && sync) {
    779  1.1    bsh 		/*
    780  1.1    bsh 		 * XXX We should poll until the queue is empty.
    781  1.1    bsh 		 * But we don't come here normally, so make
    782  1.1    bsh 		 * it simple and throw away everything.
    783  1.1    bsh 		 */
    784  1.1    bsh 		sackbc_cleanqueue(sc);
    785  1.1    bsh 	}
    786  1.1    bsh 
    787  1.1    bsh 	isactive = CMD_IN_QUEUE(sc);
    788  1.1    bsh 	TAILQ_INSERT_TAIL(&sc->cmdqueue, nc, next);
    789  1.1    bsh 	if (!isactive)
    790  1.1    bsh 		sackbc_start(sc);
    791  1.1    bsh 
    792  1.1    bsh 	if (sc->polling)
    793  1.1    bsh 		res = (sync ? nc->status : 0);
    794  1.1    bsh 	else if (sync) {
    795  1.1    bsh 		if ((res = tsleep(nc, 0, "kbccmd", 1*hz))) {
    796  1.1    bsh 			TAILQ_REMOVE(&sc->cmdqueue, nc, next);
    797  1.1    bsh 			sackbc_cleanup(sc);
    798  1.1    bsh 		} else
    799  1.1    bsh 			res = nc->status;
    800  1.1    bsh 	} else
    801  1.1    bsh 		callout_reset(&sc->t_cleanup, hz, sackbc_cleanup, sc);
    802  1.1    bsh 
    803  1.1    bsh 	if (sync) {
    804  1.1    bsh 		if (respbuf)
    805  1.1    bsh 			memcpy(respbuf, nc->response, responselen);
    806  1.1    bsh 		TAILQ_INSERT_TAIL(&sc->freequeue, nc, next);
    807  1.1    bsh 	}
    808  1.1    bsh 
    809  1.1    bsh 	splx(s);
    810  1.1    bsh 
    811  1.1    bsh 	return (res);
    812  1.1    bsh }
    813  1.1    bsh 
    814  1.1    bsh int
    815  1.1    bsh pckbc_poll_data(pckbc_tag_t self, pckbc_slot_t slot)
    816  1.1    bsh {
    817  1.1    bsh 	struct sackbc_softc *sc = (struct sackbc_softc *)self;
    818  1.1    bsh 	int c;
    819  1.1    bsh 
    820  1.1    bsh 	c = sackbc_poll_data1(sc);
    821  1.1    bsh 	if (c != -1 && CMD_IN_QUEUE(sc)) {
    822  1.1    bsh 		/* we jumped into a running command - try to
    823  1.1    bsh 		 deliver the response */
    824  1.1    bsh 		if (sackbc_cmdresponse(sc, c))
    825  1.1    bsh 			return -1;
    826  1.1    bsh 	}
    827  1.1    bsh 	return (c);
    828  1.1    bsh }
    829