diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/adi_gpio2.c | 4 | ||||
| -rw-r--r-- | drivers/gpio/at91_gpio.c | 295 | ||||
| -rw-r--r-- | drivers/gpio/omap_gpio.c | 19 | ||||
| -rw-r--r-- | drivers/gpio/pca953x.c | 5 | 
4 files changed, 186 insertions, 137 deletions
| diff --git a/drivers/gpio/adi_gpio2.c b/drivers/gpio/adi_gpio2.c index 7a034eba1..051073cee 100644 --- a/drivers/gpio/adi_gpio2.c +++ b/drivers/gpio/adi_gpio2.c @@ -352,8 +352,8 @@ void special_gpio_free(unsigned gpio)  		return;  	} -	reserve(special_gpio, gpio); -	reserve(peri, gpio); +	unreserve(special_gpio, gpio); +	unreserve(peri, gpio);  	set_label(gpio, "free");  }  #endif diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index 23229148d..af0978675 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -1,5 +1,5 @@  /* - * Memory Setup stuff - taken from blob memsetup.S + * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>   *   * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)   * @@ -8,16 +8,6 @@   * SPDX-License-Identifier:	GPL-2.0+   */ -/* - * WARNING: - * - * As the code is right now, it expects all PIO ports A,B,C,... - * to be evenly spaced in the memory map: - * ATMEL_BASE_PIOA + port * sizeof at91pio_t - * This might not necessaryly be true in future Atmel SoCs. - * This code should be fixed to use a pointer array to the ports. - */ -  #include <config.h>  #include <common.h>  #include <asm/io.h> @@ -25,19 +15,42 @@  #include <asm/arch/hardware.h>  #include <asm/arch/at91_pio.h> +static struct at91_port *at91_pio_get_port(unsigned port) +{ +	switch (port) { +	case AT91_PIO_PORTA: +		return (struct at91_port *)ATMEL_BASE_PIOA; +	case AT91_PIO_PORTB: +		return (struct at91_port *)ATMEL_BASE_PIOB; +	case AT91_PIO_PORTC: +		return (struct at91_port *)ATMEL_BASE_PIOC; +#if (ATMEL_PIO_PORTS > 3) +	case AT91_PIO_PORTD: +		return (struct at91_port *)ATMEL_BASE_PIOD; +#if (ATMEL_PIO_PORTS > 4) +	case AT91_PIO_PORTE: +		return (struct at91_port *)ATMEL_BASE_PIOE; +#endif +#endif +	default: +		return NULL; +	} +} +  int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin;  		if (use_pullup) -			writel(1 << pin, &pio->port[port].puer); +			writel(1 << pin, &at91_port->puer);  		else -			writel(1 << pin, &pio->port[port].pudr); -		writel(mask, &pio->port[port].per); +			writel(1 << pin, &at91_port->pudr); +		writel(mask, &at91_port->per);  	} +  	return 0;  } @@ -46,15 +59,16 @@ int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)   */  int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); +		writel(mask, &at91_port->idr);  		at91_set_pio_pullup(port, pin, use_pullup); -		writel(mask, &pio->port[port].per); +		writel(mask, &at91_port->per);  	} +  	return 0;  } @@ -63,23 +77,24 @@ int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)   */  int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); +		writel(mask, &at91_port->idr);  		at91_set_pio_pullup(port, pin, use_pullup);  #if defined(CPU_HAS_PIO3) -		writel(readl(&pio->port[port].abcdsr1) & ~mask, -			&pio->port[port].abcdsr1); -		writel(readl(&pio->port[port].abcdsr2) & ~mask, -			&pio->port[port].abcdsr2); +		writel(readl(&at91_port->abcdsr1) & ~mask, +		       &at91_port->abcdsr1); +		writel(readl(&at91_port->abcdsr2) & ~mask, +		       &at91_port->abcdsr2);  #else -		writel(mask, &pio->port[port].asr); +		writel(mask, &at91_port->asr);  #endif -		writel(mask, &pio->port[port].pdr); +		writel(mask, &at91_port->pdr);  	} +  	return 0;  } @@ -88,23 +103,24 @@ int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)   */  int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); +		writel(mask, &at91_port->idr);  		at91_set_pio_pullup(port, pin, use_pullup);  #if defined(CPU_HAS_PIO3) -		writel(readl(&pio->port[port].abcdsr1) | mask, -			&pio->port[port].abcdsr1); -		writel(readl(&pio->port[port].abcdsr2) & ~mask, -			&pio->port[port].abcdsr2); +		writel(readl(&at91_port->abcdsr1) | mask, +		       &at91_port->abcdsr1); +		writel(readl(&at91_port->abcdsr2) & ~mask, +		       &at91_port->abcdsr2);  #else -		writel(mask, &pio->port[port].bsr); +		writel(mask, &at91_port->bsr);  #endif -		writel(mask, &pio->port[port].pdr); +		writel(mask, &at91_port->pdr);  	} +  	return 0;  } @@ -114,19 +130,20 @@ int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)   */  int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); +		writel(mask, &at91_port->idr);  		at91_set_pio_pullup(port, pin, use_pullup); -		writel(readl(&pio->port[port].abcdsr1) & ~mask, -			&pio->port[port].abcdsr1); -		writel(readl(&pio->port[port].abcdsr2) | mask, -			&pio->port[port].abcdsr2); -		writel(mask, &pio->port[port].pdr); +		writel(readl(&at91_port->abcdsr1) & ~mask, +		       &at91_port->abcdsr1); +		writel(readl(&at91_port->abcdsr2) | mask, +		       &at91_port->abcdsr2); +		writel(mask, &at91_port->pdr);  	} +  	return 0;  } @@ -135,19 +152,20 @@ int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)   */  int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); +		writel(mask, &at91_port->idr);  		at91_set_pio_pullup(port, pin, use_pullup); -		writel(readl(&pio->port[port].abcdsr1) | mask, -			&pio->port[port].abcdsr1); -		writel(readl(&pio->port[port].abcdsr2) | mask, -			&pio->port[port].abcdsr2); -		writel(mask, &pio->port[port].pdr); +		writel(readl(&at91_port->abcdsr1) | mask, +		       &at91_port->abcdsr1); +		writel(readl(&at91_port->abcdsr2) | mask, +		       &at91_port->abcdsr2); +		writel(mask, &at91_port->pdr);  	} +  	return 0;  }  #endif @@ -158,16 +176,17 @@ int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)   */  int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); +		writel(mask, &at91_port->idr);  		at91_set_pio_pullup(port, pin, use_pullup); -		writel(mask, &pio->port[port].odr); -		writel(mask, &pio->port[port].per); +		writel(mask, &at91_port->odr); +		writel(mask, &at91_port->per);  	} +  	return 0;  } @@ -177,20 +196,21 @@ int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)   */  int at91_set_pio_output(unsigned port, u32 pin, int value)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask;  	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].idr); -		writel(mask, &pio->port[port].pudr); +		writel(mask, &at91_port->idr); +		writel(mask, &at91_port->pudr);  		if (value) -			writel(mask, &pio->port[port].sodr); +			writel(mask, &at91_port->sodr);  		else -			writel(mask, &pio->port[port].codr); -		writel(mask, &pio->port[port].oer); -		writel(mask, &pio->port[port].per); +			writel(mask, &at91_port->codr); +		writel(mask, &at91_port->oer); +		writel(mask, &at91_port->per);  	} +  	return 0;  } @@ -199,20 +219,21 @@ int at91_set_pio_output(unsigned port, u32 pin, int value)   */  int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin;  		if (is_on) {  #if defined(CPU_HAS_PIO3) -			writel(mask, &pio->port[port].ifscdr); +			writel(mask, &at91_port->ifscdr);  #endif -			writel(mask, &pio->port[port].ifer); +			writel(mask, &at91_port->ifer);  		} else { -			writel(mask, &pio->port[port].ifdr); +			writel(mask, &at91_port->ifdr);  		}  	} +  	return 0;  } @@ -222,19 +243,20 @@ int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)   */  int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin;  		if (is_on) { -			writel(mask, &pio->port[port].ifscer); -			writel(div & PIO_SCDR_DIV, &pio->port[port].scdr); -			writel(mask, &pio->port[port].ifer); +			writel(mask, &at91_port->ifscer); +			writel(div & PIO_SCDR_DIV, &at91_port->scdr); +			writel(mask, &at91_port->ifer);  		} else { -			writel(mask, &pio->port[port].ifdr); +			writel(mask, &at91_port->ifdr);  		}  	} +  	return 0;  } @@ -244,17 +266,18 @@ int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)   */  int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(mask, &pio->port[port].pudr); +		writel(mask, &at91_port->pudr);  		if (is_on) -			writel(mask, &pio->port[port].ppder); +			writel(mask, &at91_port->ppder);  		else -			writel(mask, &pio->port[port].ppddr); +			writel(mask, &at91_port->ppddr);  	} +  	return 0;  } @@ -263,14 +286,15 @@ int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)   */  int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		writel(readl(&pio->port[port].schmitt) | mask, -			&pio->port[port].schmitt); +		writel(readl(&at91_port->schmitt) | mask, +		       &at91_port->schmitt);  	} +  	return 0;  }  #endif @@ -281,16 +305,17 @@ int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)   */  int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin;  		if (is_on) -			writel(mask, &pio->port[port].mder); +			writel(mask, &at91_port->mder);  		else -			writel(mask, &pio->port[port].mddr); +			writel(mask, &at91_port->mddr);  	} +  	return 0;  } @@ -299,16 +324,17 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)   */  int at91_set_pio_value(unsigned port, unsigned pin, int value)  { -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin;  		if (value) -			writel(mask, &pio->port[port].sodr); +			writel(mask, &at91_port->sodr);  		else -			writel(mask, &pio->port[port].codr); +			writel(mask, &at91_port->codr);  	} +  	return 0;  } @@ -317,13 +343,56 @@ int at91_set_pio_value(unsigned port, unsigned pin, int value)   */  int at91_get_pio_value(unsigned port, unsigned pin)  { -	u32		pdsr = 0; -	at91_pio_t	*pio = (at91_pio_t *) ATMEL_BASE_PIOA; -	u32		mask; +	struct at91_port *at91_port = at91_pio_get_port(port); +	u32 pdsr = 0, mask; -	if ((port < ATMEL_PIO_PORTS) && (pin < 32)) { +	if (at91_port && (pin < 32)) {  		mask = 1 << pin; -		pdsr = readl(&pio->port[port].pdsr) & mask; +		pdsr = readl(&at91_port->pdsr) & mask;  	} +  	return pdsr != 0;  } + +/* Common GPIO API */ + +#define at91_gpio_to_port(gpio)		(gpio / 32) +#define at91_gpio_to_pin(gpio)		(gpio % 32) + +int gpio_request(unsigned gpio, const char *label) +{ +	return 0; +} + +int gpio_free(unsigned gpio) +{ +	return 0; +} + +int gpio_direction_input(unsigned gpio) +{ +	at91_set_pio_input(at91_gpio_to_port(gpio), +			   at91_gpio_to_pin(gpio), 0); +	return 0; +} + +int gpio_direction_output(unsigned gpio, int value) +{ +	at91_set_pio_output(at91_gpio_to_port(gpio), +			    at91_gpio_to_pin(gpio), value); +	return 0; +} + +int gpio_get_value(unsigned gpio) +{ +	return at91_get_pio_value(at91_gpio_to_port(gpio), +				  at91_gpio_to_pin(gpio)); +} + +int gpio_set_value(unsigned gpio, int value) +{ +	at91_set_pio_value(at91_gpio_to_port(gpio), +			   at91_gpio_to_pin(gpio), value); + +	return 0; +} diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index f16e9ae4d..13dcf7987 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -2,20 +2,7 @@   * Copyright (c) 2009 Wind River Systems, Inc.   * Tom Rix <Tom.Rix@windriver.com>   * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier:	GPL-2.0   *   * This work is derived from the linux 2.6.27 kernel source   * To fetch, use the kernel repository @@ -30,10 +17,6 @@   *   * Copyright (C) 2003-2005 Nokia Corporation   * Written by Juha Yrjölä <juha.yrjola@nokia.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation.   */  #include <common.h>  #include <asm/gpio.h> diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index be1374592..7371cd4a8 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -47,9 +47,6 @@ struct pca953x_chip_ngpio {  static struct pca953x_chip_ngpio pca953x_chip_ngpios[] =      CONFIG_SYS_I2C_PCA953X_WIDTH; -#define NUM_CHIP_GPIOS (sizeof(pca953x_chip_ngpios) / \ -			sizeof(struct pca953x_chip_ngpio)) -  /*   * Determine the number of GPIO pins supported. If we don't know we assume   * 8 pins. @@ -58,7 +55,7 @@ static int pca953x_ngpio(uint8_t chip)  {  	int i; -	for (i = 0; i < NUM_CHIP_GPIOS; i++) +	for (i = 0; i < ARRAY_SIZE(pca953x_chip_ngpios); i++)  		if (pca953x_chip_ngpios[i].chip == chip)  			return pca953x_chip_ngpios[i].ngpio; |