[BACK]Return to .sa11x0_gpio.c.swp CVS log [TXT][DIR] Up to [local] / sys / arch / arm / sa11x0

File: [local] / sys / arch / arm / sa11x0 / Attic / .sa11x0_gpio.c.swp (download)

Revision 1.1, Tue Mar 4 16:05:18 2008 UTC (16 years, 4 months ago) by nbrk
Branch: MAIN

Initial revision

b0VIM 7.1PGa&nbrkdev.my.domain/usr/src/sys/arch/arm/sa11x0/sa11x0_gpio.c	3210#"! UtpklDad kxwtM52j^

C
z/jg$

S
	
	u	*	rnk7NJ32mlI&%~obRCg2"o-*'	QP#int sagpio_irq_handler(void *arg);int sagpio_dispatch(void *arg);void sa11x0_gpio_set_intr_level(u_int, int);	(*((volatile u_int32_t *)(sagpio_regs + (reg))))#define GPIO_BOOTSTRAP_REG(reg)	\static vaddr_t sagpio_regs;static struct sagpio_softc *sagpio_softc;};	NULL, "sagpio", DV_DULLstruct cfdriver sagpio_cd = {	 };        sizeof (struct sagpio_softc), sagpio_match, sagpio_attachstruct cfattach sagpio_ca = {void	sagpio_attach(struct device *, struct device *, void *);int	sagpio_match(struct device *, void *, void *);};	int sc_npins;	int sc_maxipl;	int sc_minipl;	struct gpio_irq_handler *sc_handlers[SAGPIO_NPINS];//	u_int32_t sc_mask[3];//	void *sc_irqcookie[4];	bus_space_handle_t sc_bush;	bus_space_tag_t sc_bust;	struct device sc_dev;struct sagpio_softc {};	struct evcount gh_count;	int gh_irq;	/* intrno in an INTC */	int gh_level;	u_int gh_gpio;	int gh_spl;	void *gh_arg;	int (*gh_func)(void *);//	struct gpio_irq_handler *gh_next;struct gpio_irq_handler {#include <arm/sa11x0/sa11x0_gpiovar.h>#include <arm/sa11x0/sa11x0_gpioreg.h>#include <arm/sa11x0/sa11x0_var.h>#include <arm/sa11x0/sa11x0_reg.h>#include <arm/cpufunc.h>#include <machine/bus.h>#include <machine/intr.h>#include <sys/evcount.h>#include <sys/malloc.h>#include <sys/device.h>#include <sys/systm.h>#include <sys/param.h>#include <sys/cdefs.h> */ * Remaining lines 11-27 are OR'ed together and act like one interrupt source. * Pins 0-10 are independent interrupt sources in SA-11x0 Interrupt Controller. * It features 28 GPIO lines but some are used for "alternate" functions. * General Purpose Input-Output found on SA11[01]0./* */ * POSSIBILITY OF SUCH DAMAGE. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND * *    written permission. *    or promote products derived from this software without specific prior * 4. The name of Wasabi Systems, Inc. may not be used to endorse *      Wasabi Systems, Inc. *      This product includes software developed for the NetBSD Project by *    must display the following acknowledgement: * 3. All advertising materials mentioning features or use of this software *    documentation and/or other materials provided with the distribution. *    notice, this list of conditions and the following disclaimer in the * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer. * 1. Redistributions of source code must retain the above copyright * are met: * modification, are permitted provided that the following conditions * Redistribution and use in source and binary forms, with or without * * Written by Steve C. Woodford for Wasabi Systems, Inc. * * All rights reserved. * Copyright 2003 Wasabi Systems, Inc./*/*	$NetBSD: sa11x0_gpio.c,v 1.2 2003/07/15 00:24:55 lukem Exp $	*//*	$OpenBSD: sa11x0_gpio.c,v 1.18 2005/06/16 21:57:29 drahn Exp $ */adDqhSD5,"~|{t$	


f
G
<
;

onXD0qpl
|
w
M
L
5
			e	
		}	return(ih);		ih = sa11x0_intr_establish(NULL, gih->gh_irq, 0, level, sagpio_dispatch, NULL, NULL);		/* multiplexed, register dispatcher */	else		ih = sa11x0_intr_establish(NULL, gih->gh_irq, 0, level, sagpio_irq_handler, gih, NULL);		/* individual (intc irq = gpio pin), register common gpio handler */	if (gih->gh_irq < 11)	sa11x0_gpio_set_intr_level(gpio, level);	 */	 * Here we just emulate all 28 gpio interrupts (multiplexing them in 12 intnos really).	 * Pins [11:27] are OR'ed together and form intno 11 in an INTC.	 * SA11x0 INTC has 11 (intno 0-10) interrupts reserved for GPIO[0:10] respectively.	/*	sc->sc_handlers[gpio] = gih;	evcount_attach(&gih->gh_count, name, (void *)&gih->gh_irq, &evcount_intr);	gih->gh_irq = gpio < 11 ? gpio : 11;	gih->gh_gpio = gpio;	gih->gh_level = level;	gih->gh_spl = spl;	gih->gh_arg = arg;	gih->gh_func = func;	MALLOC(gih, struct gpio_irq_handler *, sizeof(struct gpio_irq_handler), M_DEVBUF, M_NOWAIT);		panic("%s: intr_establish: pin %d out of range", sc->sc_dev.dv_xname, gpio);	if (gpio > SAGPIO_NPINS - 1)	void *ih;	struct gpio_irq_handler *gih;	struct sagpio_softc *sc = sagpio_softc;	 */	 * XXX We do not support multiple handlers on one pin.	 * Establish an interrupt with given gpio intr level.	/*{    void *arg, char *name)sa11x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *),void *}	splx(s);	sagpio_reg_write(sc, SAGPIO_RER, grer);	sagpio_reg_write(sc, SAGPIO_FER, gfer);	}		break;		panic("%s: bad level: %d", sc->sc_dev.dv_xname, level);	default:		break;		grer |= bit;		gfer |= bit;	case IST_EDGE_BOTH:		break;		grer |= bit;		gfer &= ~bit;	case IST_EDGE_RISING:		break;		grer &= ~bit;		gfer |= bit;	case IST_EDGE_FALLING:		break;		grer &= ~bit;adp{zq?=,=;*





z
x
w
s
:
8


MKf[O





M
C
@
?
0
				z	y	R	,	+			~{3/*lkZxcb*VIF@8nlCp	if ((ip & GPIO_PIN(gih->gh_gpio)) == 0) {	ip = sagpio_reg_read(sc, SAGPIO_EDR);	 */	 * All we need to do is to clear status bit and call real handler.	/*	uint32_t	ip;	struct gpio_irq_handler *gih = arg;	struct sagpio_softc *sc = sagpio_softc;{sagpio_irq_handler(void *arg)int}	return(0);		}				printf("%s: no registered intr handler for pin %d\n", sc->sc_dev.dv_xname, ip);				/* edge detect occured on this pin but handler is missing */			else				sc->sc_handlers[ipbit]->gh_func(sc->sc_handlers[ipbit]->gh_arg);				/* run! */			if (sc->sc_handlers[ipbit] != NULL)			sa11x0_gpio_clear_intr(ipbit);			/* clear status */		if (ip & ipbit) {	for (ipbit = GPIO_PIN(11); ipbit < GPIO_PIN(28); ipbit <<= 1)	}		return(1);		printf("%s: dispatch: stray interrupt (GEDR=0x%8.x)\n", sc->sc_dev.dv_xname, ip);	if ((ip & 0x0ffff800) == 0) {	/* check if activity has been detected on pins[11:27] */	ip = sagpio_reg_read(sc, SAGPIO_EDR);	/* multiplexed interrupt; see what pin(s) caused it */	uint32_t	ip, ipbit;	struct sagpio_softc *sc = sagpio_softc;{sagpio_dispatch(void *arg)int}	return(irqstr);		snprintf(irqstr, sizeof irqstr, "irq %ld", gh->gh_irq);	else 		snprintf(irqstr, sizeof irqstr, "couldn't establish interrupt");	if (gh == NULL)	struct gpio_irq_handler *gh = cookie;	static char irqstr[32];{sa11x0_gpio_intr_string(void *cookie)const char *}	sagpio_regs = gpio_regs;{sa11x0_gpio_bootstrap(vaddr_t gpio_regs)void */ * This is called during bootstrap to inform us SAGPIO virtual address./*}	sagpio_softc = sc;//	sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL;	sc->sc_maxipl = IPL_NONE;	sc->sc_minipl = IPL_NONE;	/* XXX do not touch pin directions? */	sagpio_reg_write(sc, SAGPIO_EDR, 0);	/* clear all previous Edge Detects *///	sagpio_reg_write(sc, SAGPIO_FER, 0);//	sagpio_reg_write(sc, SAGPIO_RER, 0);	/* disable all Rising/Falling Edge detects */	memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers));	/* NULLify */	}		return;		printf("%s: Can't map registers!\n", sc->sc_dev.dv_xname);		/* XXX panic here? */	    &sc->sc_bush)) {	if (bus_space_map(sc->sc_bust, saa->sai_addr, saa->sai_size, 0,	}		return;		printf("%s: Attaching to non-SA1110 cputype\n", sc->sc_dev.dv_xname);		/* XXX */	} else  {		sc->sc_npins = SAGPIO_NPINS;	if (cputype == CPU_ID_SA1110) {	printf(": SA-11x0 GPIO Controller\n");	sc->sc_bust = saa->sai_iot;	struct saip_attach_args *saa = aux;	struct sagpio_softc *sc = (struct sagpio_softc *)self;{sagpio_attach(struct device *parent, struct device *self, void *aux)void}	return (1);	saa->sai_size = SAGPIO_NPORTS;		return (0);	if (sagpio_softc != NULL && saa->sai_addr != SAGPIO_BASE)	struct saip_attach_args *saa = aux;{sagpio_match(struct device *parent, void *cf, void *aux)int}	return;		panic("sagpio_reg_write: not bootstrapped");	else		GPIO_BOOTSTRAP_REG(reg) = val;	if (sagpio_regs)	else		bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);	if (sc != NULL){sagpio_reg_write(struct sagpio_softc *sc, int reg, u_int32_t val)void}	panic("sagpio_reg_read: not bootstrapped");		return (GPIO_BOOTSTRAP_REG(reg));	if (sagpio_regs)	else		return (bus_space_read_4(sc->sc_bust, sc->sc_bush, reg));	if (sc != NULL){sagpio_reg_read(struct sagpio_softc *sc, int reg)uint32_tvoid sagpio_reg_write(struct sagpio_softc *sc, int reg, u_int32_t val);u_int32_t sagpio_reg_read(struct sagpio_softc *sc, int reg);adqUIGF@uSRDBA;






t
e
L


UA>-+*&rq87(








l
k
8
6
5
1



							~	T	P	K	"	 	yoU;1&i-|xsPN%$ji532/rpol84/{srbaJ!		gfer &= ~bit;	case IST_NONE:	switch (level) {	grer = sagpio_reg_read(sc, SAGPIO_RER);	gfer = sagpio_reg_read(sc, SAGPIO_FER);	bit = GPIO_PIN(gpio);	s = splhigh();	int s;	u_int32_t grer;	/* rising edge */	u_int32_t gfer;	/* falling edge */	u_int32_t bit;	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_set_intr_level(u_int gpio, int level)void */ * Configure the edge sensitivity of interrupt pins/*}	sa11x0_gpio_set_intr_level(gh->gh_gpio, gh->gh_level);	struct gpio_irq_handler *gh = v;{sa11x0_gpio_intr_unmask(void *v)void */ * Quick function to unmask (enable) a GPIO interrupt/*}	sa11x0_gpio_set_intr_level(gh->gh_gpio, IST_NONE);	struct gpio_irq_handler *gh = v;{sa11x0_gpio_intr_mask(void *v)void */ * Quick function to mask (disable) a GPIO interrupt/*}	sagpio_reg_write(sc, SAGPIO_EDR, GPIO_PIN(gpio));	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_clear_intr(u_int gpio)void */ * the interrupt handler is running. (yes this is for the keyboard driver) * Suppose this causes a slight race if a key is pressed while * extra spurious interrupts to occur. * GPIO pins may be toggle in an interrupt and we dont want * Quick function to clear interrupt status on a pin/* }	sagpio_reg_write(sc, SAGPIO_PDR, reg);	}			/* NOTREACHED */			panic("%s: bogus pin direction %d", sc->sc_dev.dv_xname, dir);		default:			break;			reg |= GPIO_PIN(gpio);		case SAGPIO_DIR_OUTPUT:			break;			reg &= ~(GPIO_PIN(gpio));		case SAGPIO_DIR_INPUT:	switch (dir) {	reg = sagpio_reg_read(sc, SAGPIO_PDR);	uint32_t	reg;	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_set_dir(u_int gpio, int dir)void */ * Quick function to change pin direction/* }	sagpio_reg_write(sc, SAGPIO_PCR, GPIO_PIN(gpio));	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_clear_bit(u_int gpio)void */ * Quick function to set pin to 0/* }	sagpio_reg_write(sc, SAGPIO_PSR, GPIO_PIN(gpio));	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_set_bit(u_int gpio)void */ * Quick function to set pin to 1/* }		return(SAGPIO_LEVEL_HIGH);	else		return(SAGPIO_LEVEL_LOW);	if (bit == 0)	bit = sagpio_reg_read(sc, SAGPIO_PLR) & GPIO_PIN(gpio);		KDASSERT(gpio < sc->sc_npins);	if (sc != NULL)	int bit;	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_get_bit(u_int gpio)int */ * Quick function to read pin value/* }	return (oldfn);	}			/* NOTREACHED */			panic("%s: bogus gpio function %d\n", sc->sc_dev.dv_xname, fn);		default:			break;			sagpio_reg_write(sc, SAGPIO_AFR, oldfn | GPIO_PIN(gpio));		case SAGPIO_FUNC_ALT:			break;			sagpio_reg_write(sc, SAGPIO_AFR, oldfn & ~(GPIO_PIN(gpio)));		case SAGPIO_FUNC_GPIO:	switch (fn) {	oldfn = sa11x0_gpio_get_function(gpio);				KDASSERT(gpio < sc->sc_npins);	if (sc != NULL)	u_int oldfn;	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_set_function(u_int gpio, u_int fn)u_int}	return (rv);	/* 0 == GPIO, 1 == Alt. func. */	rv = sagpio_reg_read(sc, SAGPIO_AFR) & GPIO_PIN(gpio);		KDASSERT(gpio < sc->sc_npins);	if (sc != NULL)	u_int32_t rv;	struct sagpio_softc *sc = sagpio_softc;{sa11x0_gpio_get_function(u_int gpio)u_int}	return(0);	gih->gh_func(gih->gh_arg);	sa11x0_gpio_clear_intr(gih->gh_gpio);	}		return(1);		printf("%s: irq_handler: stray interrupt (GEDR=0x%8.x)\n", sc->sc_dev.dv_xname, ip);