diff options
| -rw-r--r-- | arch/blackfin/cpu/Makefile | 2 | ||||
| -rw-r--r-- | arch/blackfin/cpu/gpio.c | 145 | ||||
| -rw-r--r-- | arch/blackfin/include/asm/gpio.h | 62 | ||||
| -rw-r--r-- | arch/blackfin/include/asm/portmux.h | 5 | ||||
| -rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
| -rw-r--r-- | drivers/gpio/adi_gpio2.c | 440 | ||||
| -rw-r--r-- | include/configs/bf548-ezkit.h | 2 | ||||
| -rw-r--r-- | include/configs/bf609-ezkit.h | 2 | ||||
| -rw-r--r-- | include/configs/bfin_adi_common.h | 4 | 
9 files changed, 479 insertions, 184 deletions
| diff --git a/arch/blackfin/cpu/Makefile b/arch/blackfin/cpu/Makefile index 929fc8b7c..1421cb2ca 100644 --- a/arch/blackfin/cpu/Makefile +++ b/arch/blackfin/cpu/Makefile @@ -18,7 +18,7 @@ CEXTRA   := initcode.o  SEXTRA   := start.o  SOBJS    := interrupt.o cache.o  COBJS-y  += cpu.o -COBJS-y  += gpio.o +COBJS-$(CONFIG_ADI_GPIO1) += gpio.o  COBJS-y  += interrupts.o  COBJS-$(CONFIG_JTAG_CONSOLE) += jtag-console.o  COBJS-y  += os_log.o diff --git a/arch/blackfin/cpu/gpio.c b/arch/blackfin/cpu/gpio.c index f684be531..f74a0b7c0 100644 --- a/arch/blackfin/cpu/gpio.c +++ b/arch/blackfin/cpu/gpio.c @@ -1,5 +1,6 @@  /* - * GPIO Abstraction Layer + * ADI GPIO1 Abstraction Layer + * Support BF50x, BF51x, BF52x, BF53x and BF561 only.   *   * Copyright 2006-2010 Analog Devices Inc.   * @@ -55,25 +56,6 @@ static struct gpio_port_t * const gpio_array[] = {  	(struct gpio_port_t *) FIO0_FLAG_D,  	(struct gpio_port_t *) FIO1_FLAG_D,  	(struct gpio_port_t *) FIO2_FLAG_D, -#elif defined(CONFIG_BF54x) -	(struct gpio_port_t *)PORTA_FER, -	(struct gpio_port_t *)PORTB_FER, -	(struct gpio_port_t *)PORTC_FER, -	(struct gpio_port_t *)PORTD_FER, -	(struct gpio_port_t *)PORTE_FER, -	(struct gpio_port_t *)PORTF_FER, -	(struct gpio_port_t *)PORTG_FER, -	(struct gpio_port_t *)PORTH_FER, -	(struct gpio_port_t *)PORTI_FER, -	(struct gpio_port_t *)PORTJ_FER, -#elif defined(CONFIG_BF60x) -	(struct gpio_port_t *)PORTA_FER, -	(struct gpio_port_t *)PORTB_FER, -	(struct gpio_port_t *)PORTC_FER, -	(struct gpio_port_t *)PORTD_FER, -	(struct gpio_port_t *)PORTE_FER, -	(struct gpio_port_t *)PORTF_FER, -	(struct gpio_port_t *)PORTG_FER,  #else  # error no gpio arrays defined  #endif @@ -174,12 +156,6 @@ DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));  inline int check_gpio(unsigned gpio)  { -#if defined(CONFIG_BF54x) -	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 -	    || gpio == GPIO_PH14 || gpio == GPIO_PH15 -	    || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) -		return -EINVAL; -#endif  	if (gpio >= MAX_BLACKFIN_GPIOS)  		return -EINVAL;  	return 0; @@ -218,18 +194,6 @@ static void port_setup(unsigned gpio, unsigned short usage)  	else  		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);  	SSYNC(); -#elif defined(CONFIG_BF54x) -	if (usage == GPIO_USAGE) -		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); -	else -		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); -	SSYNC(); -#elif defined(CONFIG_BF60x) -	if (usage == GPIO_USAGE) -		gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio); -	else -		gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio); -	SSYNC();  #endif  } @@ -304,30 +268,6 @@ static void portmux_setup(unsigned short per)  		}  	}  } -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -inline void portmux_setup(unsigned short per) -{ -	u32 pmux; -	u16 ident = P_IDENT(per); -	u16 function = P_FUNCT2MUX(per); - -	pmux = gpio_array[gpio_bank(ident)]->port_mux; - -	pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); -	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); - -	gpio_array[gpio_bank(ident)]->port_mux = pmux; -} - -inline u16 get_portmux(unsigned short per) -{ -	u32 pmux; -	u16 ident = P_IDENT(per); - -	pmux = gpio_array[gpio_bank(ident)]->port_mux; - -	return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); -}  #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)  inline void portmux_setup(unsigned short per)  { @@ -344,7 +284,6 @@ inline void portmux_setup(unsigned short per)  # define portmux_setup(...)  do { } while (0)  #endif -#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x)  /***********************************************************  *  * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -491,15 +430,6 @@ GET_GPIO_P(both)  GET_GPIO_P(maska)  GET_GPIO_P(maskb) -#else /* CONFIG_BF54x */ - -unsigned short get_gpio_dir(unsigned gpio) -{ -	return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); -} - -#endif /* CONFIG_BF54x */ -  /***********************************************************  *  * FUNCTIONS:	Blackfin Peripheral Resource Allocation @@ -548,11 +478,7 @@ int peripheral_request(unsigned short per, const char *label)  		 * be requested and used by several drivers  		 */ -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -		if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { -#else  		if (!(per & P_MAYSHARE)) { -#endif  			/*  			 * Allow that the identical pin function can  			 * be requested from the same driver twice @@ -641,7 +567,7 @@ void peripheral_free_list(const unsigned short per[])  * MODIFICATION HISTORY :  **************************************************************/ -int bfin_gpio_request(unsigned gpio, const char *label) +int gpio_request(unsigned gpio, const char *label)  {  	if (check_gpio(gpio) < 0)  		return -EINVAL; @@ -665,11 +591,9 @@ int bfin_gpio_request(unsigned gpio, const char *label)  		       gpio, get_label(gpio));  		return -EBUSY;  	} -#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x)  	else {	/* Reset POLAR setting when acquiring a gpio for the first time */  		set_gpio_polar(gpio, 0);  	} -#endif  	reserve(gpio, gpio);  	set_label(gpio, label); @@ -679,27 +603,27 @@ int bfin_gpio_request(unsigned gpio, const char *label)  	return 0;  } -#ifdef CONFIG_BFIN_GPIO_TRACK -void bfin_gpio_free(unsigned gpio) +int gpio_free(unsigned gpio)  {  	if (check_gpio(gpio) < 0) -		return; +		return -1;  	if (unlikely(!is_reserved(gpio, gpio, 0))) {  		gpio_error(gpio); -		return; +		return -1;  	}  	unreserve(gpio, gpio);  	set_label(gpio, "free"); + +	return 0;  } -#endif -#ifdef BFIN_SPECIAL_GPIO_BANKS +#ifdef ADI_SPECIAL_GPIO_BANKS  DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); -int bfin_special_gpio_request(unsigned gpio, const char *label) +int special_gpio_request(unsigned gpio, const char *label)  {  	/*  	 * Allow that the identical GPIO can @@ -731,7 +655,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label)  	return 0;  } -void bfin_special_gpio_free(unsigned gpio) +void special_gpio_free(unsigned gpio)  {  	if (unlikely(!is_reserved(special_gpio, gpio, 0))) {  		gpio_error(gpio); @@ -744,21 +668,13 @@ void bfin_special_gpio_free(unsigned gpio)  }  #endif -static inline void __bfin_gpio_direction_input(unsigned gpio) +static inline void __gpio_direction_input(unsigned gpio)  { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); -#else  	gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); -#endif -#if defined(CONFIG_BF60x) -	gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio); -#else  	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); -#endif  } -int bfin_gpio_direction_input(unsigned gpio) +int gpio_direction_input(unsigned gpio)  {  	unsigned long flags; @@ -768,31 +684,24 @@ int bfin_gpio_direction_input(unsigned gpio)  	}  	local_irq_save(flags); -	__bfin_gpio_direction_input(gpio); +	__gpio_direction_input(gpio);  	AWA_DUMMY_READ(inen);  	local_irq_restore(flags);  	return 0;  } -void bfin_gpio_toggle_value(unsigned gpio) -{ -#ifdef CONFIG_BF54x -	gpio_set_value(gpio, !gpio_get_value(gpio)); -#else -	gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); -#endif -} - -void bfin_gpio_set_value(unsigned gpio, int arg) +int gpio_set_value(unsigned gpio, int arg)  {  	if (arg)  		gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);  	else  		gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + +	return 0;  } -int bfin_gpio_direction_output(unsigned gpio, int value) +int gpio_direction_output(unsigned gpio, int value)  {  	unsigned long flags; @@ -803,17 +712,9 @@ int bfin_gpio_direction_output(unsigned gpio, int value)  	local_irq_save(flags); -#if defined(CONFIG_BF60x) -	gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio); -#else  	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); -#endif  	gpio_set_value(gpio, value); -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); -#else  	gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); -#endif  	AWA_DUMMY_READ(dir);  	local_irq_restore(flags); @@ -821,11 +722,8 @@ int bfin_gpio_direction_output(unsigned gpio, int value)  	return 0;  } -int bfin_gpio_get_value(unsigned gpio) +int gpio_get_value(unsigned gpio)  { -#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) -	return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); -#else  	unsigned long flags;  	if (unlikely(get_gpio_edge(gpio))) { @@ -838,7 +736,6 @@ int bfin_gpio_get_value(unsigned gpio)  		return ret;  	} else  		return get_gpio_data(gpio); -#endif  }  /* If we are booting from SPI and our board lacks a strong enough pull up, @@ -860,8 +757,7 @@ void bfin_reset_boot_spi_cs(unsigned short pin)  	udelay(1);  } -#ifdef CONFIG_BFIN_GPIO_TRACK -void bfin_gpio_labels(void) +void gpio_labels(void)  {  	int c, gpio; @@ -877,4 +773,3 @@ void bfin_gpio_labels(void)  			continue;  	}  } -#endif diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 05131b5e8..58a619110 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -7,6 +7,8 @@  #ifndef __ARCH_BLACKFIN_GPIO_H__  #define __ARCH_BLACKFIN_GPIO_H__ +#include <asm-generic/gpio.h> +  #define gpio_bank(x)	((x) >> 4)  #define gpio_bit(x)	(1<<((x) & 0xF))  #define gpio_sub_n(x)	((x) & 0xF) @@ -65,10 +67,11 @@  #define PERIPHERAL_USAGE 1  #define GPIO_USAGE 0 +#define MAX_GPIOS MAX_BLACKFIN_GPIOS  #ifndef __ASSEMBLY__ -#if !defined(CONFIG_BF54x) && !defined(CONFIG_BF60x) +#ifdef CONFIG_ADI_GPIO1  void set_gpio_dir(unsigned, unsigned short);  void set_gpio_inen(unsigned, unsigned short);  void set_gpio_polar(unsigned, unsigned short); @@ -140,61 +143,16 @@ struct gpio_port_t {  };  #endif -#ifdef CONFIG_BFIN_GPIO_TRACK -void bfin_gpio_labels(void); -void bfin_gpio_free(unsigned gpio); -#else -#define bfin_gpio_labels() -#define bfin_gpio_free(gpio) -#define bfin_gpio_request(gpio, label) bfin_gpio_request(gpio) -#define bfin_special_gpio_request(gpio, label) bfin_special_gpio_request(gpio) -#endif - -#ifdef BFIN_SPECIAL_GPIO_BANKS -void bfin_special_gpio_free(unsigned gpio); -int bfin_special_gpio_request(unsigned gpio, const char *label); +#ifdef ADI_SPECIAL_GPIO_BANKS +void special_gpio_free(unsigned gpio); +int special_gpio_request(unsigned gpio, const char *label);  #endif -int bfin_gpio_request(unsigned gpio, const char *label); -int bfin_gpio_direction_input(unsigned gpio); -int bfin_gpio_direction_output(unsigned gpio, int value); -int bfin_gpio_get_value(unsigned gpio); -void bfin_gpio_set_value(unsigned gpio, int value); -void bfin_gpio_toggle_value(unsigned gpio); - -static inline int gpio_request(unsigned gpio, const char *label) -{ -	return bfin_gpio_request(gpio, label); -} - -static inline void gpio_free(unsigned gpio) -{ -	return bfin_gpio_free(gpio); -} - -static inline int gpio_direction_input(unsigned gpio) -{ -	return bfin_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(unsigned gpio, int value) -{ -	return bfin_gpio_direction_output(gpio, value); -} - -static inline int gpio_get_value(unsigned gpio) -{ -	return bfin_gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned gpio, int value) -{ -	return bfin_gpio_set_value(gpio, value); -} +void gpio_labels(void);  static inline int gpio_is_valid(int number)  { -	return number >= 0 && number < MAX_BLACKFIN_GPIOS; +	return number >= 0 && number < MAX_GPIOS;  }  #include <linux/ctype.h> @@ -248,7 +206,7 @@ static inline int name_to_gpio(const char *name)  }  #define name_to_gpio(n) name_to_gpio(n) -#define gpio_status() bfin_gpio_labels() +#define gpio_status() gpio_labels()  #endif /* __ASSEMBLY__ */ diff --git a/arch/blackfin/include/asm/portmux.h b/arch/blackfin/include/asm/portmux.h index 300ef44fd..003694b51 100644 --- a/arch/blackfin/include/asm/portmux.h +++ b/arch/blackfin/include/asm/portmux.h @@ -17,11 +17,6 @@  #define P_MAYSHARE	0x2000  #define P_DONTCARE	0x1000 -#ifndef CONFIG_BFIN_GPIO_TRACK -#define peripheral_request(per, label) peripheral_request(per) -#define peripheral_request_list(per, label) peripheral_request_list(per) -#endif -  #ifndef __ASSEMBLY__  int peripheral_request(unsigned short per, const char *label); diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 830e8e691..f77c1ec1e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -48,6 +48,7 @@ COBJS-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o  COBJS-$(CONFIG_BCM2835_GPIO)	+= bcm2835_gpio.o  COBJS-$(CONFIG_S3C2440_GPIO)	+= s3c2440_gpio.o  COBJS-$(CONFIG_XILINX_GPIO)	+= xilinx_gpio.o +COBJS-$(CONFIG_ADI_GPIO2)	+= adi_gpio2.o  COBJS	:= $(COBJS-y)  SRCS 	:= $(COBJS:.o=.c) diff --git a/drivers/gpio/adi_gpio2.c b/drivers/gpio/adi_gpio2.c new file mode 100644 index 000000000..7a034eba1 --- /dev/null +++ b/drivers/gpio/adi_gpio2.c @@ -0,0 +1,440 @@ +/* + * ADI GPIO2 Abstraction Layer + * Support BF54x, BF60x and future processors. + * + * Copyright 2008-2013 Analog Devices Inc. + * + * Licensed under the GPL-2 or later + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/gpio.h> +#include <asm/portmux.h> + +static struct gpio_port_t * const gpio_array[] = { +	(struct gpio_port_t *)PORTA_FER, +	(struct gpio_port_t *)PORTB_FER, +	(struct gpio_port_t *)PORTC_FER, +	(struct gpio_port_t *)PORTD_FER, +	(struct gpio_port_t *)PORTE_FER, +	(struct gpio_port_t *)PORTF_FER, +	(struct gpio_port_t *)PORTG_FER, +#if defined(CONFIG_BF54x) +	(struct gpio_port_t *)PORTH_FER, +	(struct gpio_port_t *)PORTI_FER, +	(struct gpio_port_t *)PORTJ_FER, +#endif +}; + +#define RESOURCE_LABEL_SIZE	16 + +static struct str_ident { +	char name[RESOURCE_LABEL_SIZE]; +} str_ident[MAX_RESOURCES]; + +static void gpio_error(unsigned gpio) +{ +	printf("adi_gpio2: GPIO %d wasn't requested!\n", gpio); +} + +static void set_label(unsigned short ident, const char *label) +{ +	if (label) { +		strncpy(str_ident[ident].name, label, +			RESOURCE_LABEL_SIZE); +		str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0; +	} +} + +static char *get_label(unsigned short ident) +{ +	return *str_ident[ident].name ? str_ident[ident].name : "UNKNOWN"; +} + +static int cmp_label(unsigned short ident, const char *label) +{ +	if (label == NULL) +		printf("adi_gpio2: please provide none-null label\n"); + +	if (label) +		return strcmp(str_ident[ident].name, label); +	else +		return -EINVAL; +} + +#define map_entry(m, i)      reserved_##m##_map[gpio_bank(i)] +#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i)) +#define reserve(m, i)        (map_entry(m, i) |= gpio_bit(i)) +#define unreserve(m, i)      (map_entry(m, i) &= ~gpio_bit(i)) +#define DECLARE_RESERVED_MAP(m, c) unsigned short reserved_##m##_map[c] + +static DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM); +static DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES)); + +inline int check_gpio(unsigned gpio) +{ +#if defined(CONFIG_BF54x) +	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 || +		gpio == GPIO_PH14 || gpio == GPIO_PH15 || +		gpio == GPIO_PJ14 || gpio == GPIO_PJ15) +		return -EINVAL; +#endif +	if (gpio >= MAX_GPIOS) +		return -EINVAL; +	return 0; +} + +static void port_setup(unsigned gpio, unsigned short usage) +{ +#if defined(CONFIG_BF54x) +	if (usage == GPIO_USAGE) +		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); +	else +		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); +#else +	if (usage == GPIO_USAGE) +		gpio_array[gpio_bank(gpio)]->port_fer_clear = gpio_bit(gpio); +	else +		gpio_array[gpio_bank(gpio)]->port_fer_set = gpio_bit(gpio); +#endif +	SSYNC(); +} + +inline void portmux_setup(unsigned short per) +{ +	u32 pmux; +	u16 ident = P_IDENT(per); +	u16 function = P_FUNCT2MUX(per); + +	pmux = gpio_array[gpio_bank(ident)]->port_mux; + +	pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); +	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); + +	gpio_array[gpio_bank(ident)]->port_mux = pmux; +} + +inline u16 get_portmux(unsigned short per) +{ +	u32 pmux; +	u16 ident = P_IDENT(per); + +	pmux = gpio_array[gpio_bank(ident)]->port_mux; + +	return pmux >> (2 * gpio_sub_n(ident)) & 0x3; +} + +unsigned short get_gpio_dir(unsigned gpio) +{ +	return 0x01 & +		(gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)); +} + +/*********************************************************** +* +* FUNCTIONS:	Peripheral Resource Allocation +*		and PortMux Setup +* +* INPUTS/OUTPUTS: +* per	Peripheral Identifier +* label	String +* +* DESCRIPTION: Peripheral Resource Allocation and Setup API +**************************************************************/ + +int peripheral_request(unsigned short per, const char *label) +{ +	unsigned short ident = P_IDENT(per); + +	/* +	 * Don't cares are pins with only one dedicated function +	 */ + +	if (per & P_DONTCARE) +		return 0; + +	if (!(per & P_DEFINED)) +		return -ENODEV; + +	BUG_ON(ident >= MAX_RESOURCES); + +	/* If a pin can be muxed as either GPIO or peripheral, make +	 * sure it is not already a GPIO pin when we request it. +	 */ +	if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) { +		printf("%s: Peripheral %d is already reserved as GPIO by %s!\n", +		       __func__, ident, get_label(ident)); +		return -EBUSY; +	} + +	if (unlikely(is_reserved(peri, ident, 1))) { +		/* +		 * Pin functions like AMC address strobes my +		 * be requested and used by several drivers +		 */ + +		if (!((per & P_MAYSHARE) && +			get_portmux(per) == P_FUNCT2MUX(per))) { +			/* +			 * Allow that the identical pin function can +			 * be requested from the same driver twice +			 */ + +			if (cmp_label(ident, label) == 0) +				goto anyway; + +			printf("%s: Peripheral %d function %d is already " +				"reserved by %s!\n", __func__, ident, +				P_FUNCT2MUX(per), get_label(ident)); +			return -EBUSY; +		} +	} + + anyway: +	reserve(peri, ident); + +	portmux_setup(per); +	port_setup(ident, PERIPHERAL_USAGE); + +	set_label(ident, label); + +	return 0; +} + +int peripheral_request_list(const unsigned short per[], const char *label) +{ +	u16 cnt; +	int ret; + +	for (cnt = 0; per[cnt] != 0; cnt++) { +		ret = peripheral_request(per[cnt], label); + +		if (ret < 0) { +			for (; cnt > 0; cnt--) +				peripheral_free(per[cnt - 1]); + +			return ret; +		} +	} + +	return 0; +} + +void peripheral_free(unsigned short per) +{ +	unsigned short ident = P_IDENT(per); + +	if (per & P_DONTCARE) +		return; + +	if (!(per & P_DEFINED)) +		return; + +	if (unlikely(!is_reserved(peri, ident, 0))) +		return; + +	if (!(per & P_MAYSHARE)) +		port_setup(ident, GPIO_USAGE); + +	unreserve(peri, ident); + +	set_label(ident, "free"); +} + +void peripheral_free_list(const unsigned short per[]) +{ +	u16 cnt; +	for (cnt = 0; per[cnt] != 0; cnt++) +		peripheral_free(per[cnt]); +} + +/*********************************************************** +* +* FUNCTIONS: GPIO Driver +* +* INPUTS/OUTPUTS: +* gpio	PIO Number between 0 and MAX_GPIOS +* label	String +* +* DESCRIPTION: GPIO Driver API +**************************************************************/ + +int gpio_request(unsigned gpio, const char *label) +{ +	if (check_gpio(gpio) < 0) +		return -EINVAL; + +	/* +	 * Allow that the identical GPIO can +	 * be requested from the same driver twice +	 * Do nothing and return - +	 */ + +	if (cmp_label(gpio, label) == 0) +		return 0; + +	if (unlikely(is_reserved(gpio, gpio, 1))) { +		printf("adi_gpio2: GPIO %d is already reserved by %s!\n", +			gpio, get_label(gpio)); +		return -EBUSY; +	} +	if (unlikely(is_reserved(peri, gpio, 1))) { +		printf("adi_gpio2: GPIO %d is already reserved as Peripheral " +			"by %s!\n", gpio, get_label(gpio)); +		return -EBUSY; +	} + +	reserve(gpio, gpio); +	set_label(gpio, label); + +	port_setup(gpio, GPIO_USAGE); + +	return 0; +} + +int gpio_free(unsigned gpio) +{ +	if (check_gpio(gpio) < 0) +		return -1; + +	if (unlikely(!is_reserved(gpio, gpio, 0))) { +		gpio_error(gpio); +		return -1; +	} + +	unreserve(gpio, gpio); + +	set_label(gpio, "free"); + +	return 0; +} + +#ifdef ADI_SPECIAL_GPIO_BANKS +static DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); + +int special_gpio_request(unsigned gpio, const char *label) +{ +	/* +	 * Allow that the identical GPIO can +	 * be requested from the same driver twice +	 * Do nothing and return - +	 */ + +	if (cmp_label(gpio, label) == 0) +		return 0; + +	if (unlikely(is_reserved(special_gpio, gpio, 1))) { +		printf("adi_gpio2: GPIO %d is already reserved by %s!\n", +			gpio, get_label(gpio)); +		return -EBUSY; +	} +	if (unlikely(is_reserved(peri, gpio, 1))) { +		printf("adi_gpio2: GPIO %d is already reserved as Peripheral " +			"by %s!\n", gpio, get_label(gpio)); + +		return -EBUSY; +	} + +	reserve(special_gpio, gpio); +	reserve(peri, gpio); + +	set_label(gpio, label); +	port_setup(gpio, GPIO_USAGE); + +	return 0; +} + +void special_gpio_free(unsigned gpio) +{ +	if (unlikely(!is_reserved(special_gpio, gpio, 0))) { +		gpio_error(gpio); +		return; +	} + +	reserve(special_gpio, gpio); +	reserve(peri, gpio); +	set_label(gpio, "free"); +} +#endif + +static inline void __gpio_direction_input(unsigned gpio) +{ +	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); +#if defined(CONFIG_BF54x) +	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); +#else +	gpio_array[gpio_bank(gpio)]->inen_set = gpio_bit(gpio); +#endif +} + +int gpio_direction_input(unsigned gpio) +{ +	unsigned long flags; + +	if (!is_reserved(gpio, gpio, 0)) { +		gpio_error(gpio); +		return -EINVAL; +	} + +	local_irq_save(flags); +	__gpio_direction_input(gpio); +	local_irq_restore(flags); + +	return 0; +} + +int gpio_set_value(unsigned gpio, int arg) +{ +	if (arg) +		gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); +	else +		gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); + +	return 0; +} + +int gpio_direction_output(unsigned gpio, int value) +{ +	unsigned long flags; + +	if (!is_reserved(gpio, gpio, 0)) { +		gpio_error(gpio); +		return -EINVAL; +	} + +	local_irq_save(flags); + +#if defined(CONFIG_BF54x) +	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); +#else +	gpio_array[gpio_bank(gpio)]->inen_clear = gpio_bit(gpio); +#endif +	gpio_set_value(gpio, value); +	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); + +	local_irq_restore(flags); + +	return 0; +} + +int gpio_get_value(unsigned gpio) +{ +	return 1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); +} + +void gpio_labels(void) +{ +	int c, gpio; + +	for (c = 0; c < MAX_RESOURCES; c++) { +		gpio = is_reserved(gpio, c, 1); +		if (!check_gpio(c) && gpio) +			printf("GPIO_%d:\t%s\tGPIO %s\n", c, get_label(c), +				get_gpio_dir(c) ? "OUTPUT" : "INPUT"); +		else if (is_reserved(peri, c, 1)) +			printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c)); +		else +			continue; +	} +} diff --git a/include/configs/bf548-ezkit.h b/include/configs/bf548-ezkit.h index 7ed0ea9ab..da5f02943 100644 --- a/include/configs/bf548-ezkit.h +++ b/include/configs/bf548-ezkit.h @@ -182,6 +182,8 @@  #define CONFIG_UART_CONSOLE	1  #define CONFIG_BFIN_SPI_IMG_SIZE 0x50000 +#define CONFIG_ADI_GPIO2 +  #undef CONFIG_VIDEO  #ifdef CONFIG_VIDEO  #define EASYLOGO_HEADER < asm/bfin_logo_230x230_gzip.h > diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h index e7b02a532..1a43e1b43 100644 --- a/include/configs/bf609-ezkit.h +++ b/include/configs/bf609-ezkit.h @@ -149,6 +149,8 @@  #define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 20*1024*1024 + 4)  #define CONFIG_BFIN_SOFT_SWITCH +#define CONFIG_ADI_GPIO2 +  #if 0  #define CONFIG_UART_MEM 1024  #undef CONFIG_UART_CONSOLE diff --git a/include/configs/bfin_adi_common.h b/include/configs/bfin_adi_common.h index c751dd74c..e1a6fe305 100644 --- a/include/configs/bfin_adi_common.h +++ b/include/configs/bfin_adi_common.h @@ -323,5 +323,7 @@  #  define CONFIG_WATCHDOG_TIMEOUT_MSECS 5000  # endif  #endif - +#ifndef CONFIG_ADI_GPIO2 +# define CONFIG_ADI_GPIO1 +#endif  #endif |