diff options
Diffstat (limited to 'arch/avr32/include/asm/arch-common/portmux-gpio.h')
| -rw-r--r-- | arch/avr32/include/asm/arch-common/portmux-gpio.h | 114 | 
1 files changed, 114 insertions, 0 deletions
| diff --git a/arch/avr32/include/asm/arch-common/portmux-gpio.h b/arch/avr32/include/asm/arch-common/portmux-gpio.h new file mode 100644 index 000000000..1306cbe5d --- /dev/null +++ b/arch/avr32/include/asm/arch-common/portmux-gpio.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ +#ifndef __AVR32_PORTMUX_GPIO_H__ +#define __AVR32_PORTMUX_GPIO_H__ + +#include <asm/io.h> + +/* Register layout for this specific device */ +#include <asm/arch/gpio-impl.h> + +/* Register access macros */ +#define gpio_readl(port, reg)						\ +	__raw_readl(&((struct gpio_regs *)port)->reg) +#define gpio_writel(gpio, reg, value)					\ +	__raw_writel(value, &((struct gpio_regs *)port)->reg) + +/* Portmux API starts here. See doc/README.AVR32-port-muxing */ + +enum portmux_function { +	PORTMUX_FUNC_A, +	PORTMUX_FUNC_B, +	PORTMUX_FUNC_C, +	PORTMUX_FUNC_D, +}; + +#define PORTMUX_DIR_INPUT	(0 << 0) +#define PORTMUX_DIR_OUTPUT	(1 << 0) +#define PORTMUX_INIT_LOW	(0 << 1) +#define PORTMUX_INIT_HIGH	(1 << 1) +#define PORTMUX_PULL_UP		(1 << 2) +#define PORTMUX_PULL_DOWN	(2 << 2) +#define PORTMUX_BUSKEEPER	(3 << 2) +#define PORTMUX_DRIVE_MIN	(0 << 4) +#define PORTMUX_DRIVE_LOW	(1 << 4) +#define PORTMUX_DRIVE_HIGH	(2 << 4) +#define PORTMUX_DRIVE_MAX	(3 << 4) +#define PORTMUX_OPEN_DRAIN	(1 << 6) + +void portmux_select_peripheral(void *port, unsigned long pin_mask, +		enum portmux_function func, unsigned long flags); +void portmux_select_gpio(void *port, unsigned long pin_mask, +		unsigned long flags); + +/* Internal helper functions */ + +static inline void *gpio_pin_to_port(unsigned int pin) +{ +	return (void *)GPIO_BASE + (pin >> 5) * 0x200; +} + +static inline void __gpio_set_output_value(void *port, unsigned int pin, +		int value) +{ +	if (value) +		gpio_writel(port, OVRS, 1 << pin); +	else +		gpio_writel(port, OVRC, 1 << pin); +} + +static inline int __gpio_get_input_value(void *port, unsigned int pin) +{ +	return (gpio_readl(port, PVR) >> pin) & 1; +} + +void gpio_set_output_value(unsigned int pin, int value); +int gpio_get_input_value(unsigned int pin); + +/* GPIO API starts here */ + +/* + * GCC doesn't realize that the constant case is extremely trivial, + * so we need to help it make the right decision by using + * always_inline. + */ +__attribute__((always_inline)) +static inline void gpio_set_value(unsigned int pin, int value) +{ +	if (__builtin_constant_p(pin)) +		__gpio_set_output_value(gpio_pin_to_port(pin), +				pin & 0x1f, value); +	else +		gpio_set_output_value(pin, value); +} + +__attribute__((always_inline)) +static inline int gpio_get_value(unsigned int pin) +{ +	if (__builtin_constant_p(pin)) +		return __gpio_get_input_value(gpio_pin_to_port(pin), +				pin & 0x1f); +	else +		return gpio_get_input_value(pin); +} + +#endif /* __AVR32_PORTMUX_GPIO_H__ */ |