diff options
| author | Linus Torvalds <[email protected]> | 2009-03-28 14:03:14 -0700 | 
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2009-03-28 14:03:14 -0700 | 
| commit | 0fe41b8982001cd14ee2c77cd776735a5024e98b (patch) | |
| tree | 83e65d595c413d55259ea14fb97748ce5efe5707 /arch/arm/mach-pxa/include/mach/gpio.h | |
| parent | eedf2c5296a8dfaaf9aec1a938c1d3bd73159a30 (diff) | |
| parent | 9759d22c8348343b0da4e25d6150c41712686c14 (diff) | |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (422 commits)
  [ARM] 5435/1: fix compile warning in sanity_check_meminfo()
  [ARM] 5434/1: ARM: OMAP: Fix mailbox compile for 24xx
  [ARM] pxa: fix the bad assumption that PCMCIA sockets always start with 0
  [ARM] pxa: fix Colibri PXA300 and PXA320 LCD backlight pins
  imxfb: Fix TFT mode
  i.MX21/27: remove ifdef CONFIG_FB_IMX
  imxfb: add clock support
  mxc: add arch_reset() function
  clkdev: add possibility to get a clock based on the device name
  i.MX1: remove fb support from mach-imx
  [ARM] pxa: build arch/arm/plat-pxa/mfp.c only when PXA3xx or ARCH_MMP defined
  Gemini: Add support for Teltonika RUT100
  Gemini: gpiolib based GPIO support v2
  MAINTAINERS: add myself as Gemini architecture maintainer
  ARM: Add Gemini architecture v3
  [ARM] OMAP: Fix compile for omap2_init_common_hw()
  MAINTAINERS: Add myself as Faraday ARM core variant maintainer
  ARM: Add support for FA526 v2
  [ARM] acorn,ebsa110,footbridge,integrator,sa1100: Convert asm/io.h to linux/io.h
  [ARM] collie: fix two minor formatting nits
  ...
Diffstat (limited to 'arch/arm/mach-pxa/include/mach/gpio.h')
| -rw-r--r-- | arch/arm/mach-pxa/include/mach/gpio.h | 126 | 
1 files changed, 101 insertions, 25 deletions
| diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h index 2c538d8c362d..b024a8b37439 100644 --- a/arch/arm/mach-pxa/include/mach/gpio.h +++ b/arch/arm/mach-pxa/include/mach/gpio.h @@ -24,42 +24,118 @@  #ifndef __ASM_ARCH_PXA_GPIO_H  #define __ASM_ARCH_PXA_GPIO_H -#include <mach/pxa-regs.h> -#include <asm/irq.h> +#include <mach/irqs.h>  #include <mach/hardware.h> -  #include <asm-generic/gpio.h> +#define GPIO_REGS_VIRT	io_p2v(0x40E00000) + +#define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) +#define GPIO_REG(x)	(*(volatile u32 *)(GPIO_REGS_VIRT + (x))) + +/* GPIO Pin Level Registers */ +#define GPLR0		GPIO_REG(BANK_OFF(0) + 0x00) +#define GPLR1		GPIO_REG(BANK_OFF(1) + 0x00) +#define GPLR2		GPIO_REG(BANK_OFF(2) + 0x00) +#define GPLR3		GPIO_REG(BANK_OFF(3) + 0x00) + +/* GPIO Pin Direction Registers */ +#define GPDR0		GPIO_REG(BANK_OFF(0) + 0x0c) +#define GPDR1		GPIO_REG(BANK_OFF(1) + 0x0c) +#define GPDR2		GPIO_REG(BANK_OFF(2) + 0x0c) +#define GPDR3		GPIO_REG(BANK_OFF(3) + 0x0c) + +/* GPIO Pin Output Set Registers */ +#define GPSR0		GPIO_REG(BANK_OFF(0) + 0x18) +#define GPSR1		GPIO_REG(BANK_OFF(1) + 0x18) +#define GPSR2		GPIO_REG(BANK_OFF(2) + 0x18) +#define GPSR3		GPIO_REG(BANK_OFF(3) + 0x18) + +/* GPIO Pin Output Clear Registers */ +#define GPCR0		GPIO_REG(BANK_OFF(0) + 0x24) +#define GPCR1		GPIO_REG(BANK_OFF(1) + 0x24) +#define GPCR2		GPIO_REG(BANK_OFF(2) + 0x24) +#define GPCR3		GPIO_REG(BANK_OFF(3) + 0x24) + +/* GPIO Rising Edge Detect Registers */ +#define GRER0		GPIO_REG(BANK_OFF(0) + 0x30) +#define GRER1		GPIO_REG(BANK_OFF(1) + 0x30) +#define GRER2		GPIO_REG(BANK_OFF(2) + 0x30) +#define GRER3		GPIO_REG(BANK_OFF(3) + 0x30) + +/* GPIO Falling Edge Detect Registers */ +#define GFER0		GPIO_REG(BANK_OFF(0) + 0x3c) +#define GFER1		GPIO_REG(BANK_OFF(1) + 0x3c) +#define GFER2		GPIO_REG(BANK_OFF(2) + 0x3c) +#define GFER3		GPIO_REG(BANK_OFF(3) + 0x3c) + +/* GPIO Edge Detect Status Registers */ +#define GEDR0		GPIO_REG(BANK_OFF(0) + 0x48) +#define GEDR1		GPIO_REG(BANK_OFF(1) + 0x48) +#define GEDR2		GPIO_REG(BANK_OFF(2) + 0x48) +#define GEDR3		GPIO_REG(BANK_OFF(3) + 0x48) + +/* GPIO Alternate Function Select Registers */ +#define GAFR0_L		GPIO_REG(0x0054) +#define GAFR0_U		GPIO_REG(0x0058) +#define GAFR1_L		GPIO_REG(0x005C) +#define GAFR1_U		GPIO_REG(0x0060) +#define GAFR2_L		GPIO_REG(0x0064) +#define GAFR2_U		GPIO_REG(0x0068) +#define GAFR3_L		GPIO_REG(0x006C) +#define GAFR3_U		GPIO_REG(0x0070) + +/* More handy macros.  The argument is a literal GPIO number. */ + +#define GPIO_bit(x)	(1 << ((x) & 0x1f)) + +#define GPLR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x00) +#define GPDR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x0c) +#define GPSR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x18) +#define GPCR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x24) +#define GRER(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x30) +#define GFER(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x3c) +#define GEDR(x)		GPIO_REG(BANK_OFF((x) >> 5) + 0x48) +#define GAFR(x)		GPIO_REG(0x54 + (((x) & 0x70) >> 2)) + -/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85). - * Those cases currently cause holes in the GPIO number space. - */  #define NR_BUILTIN_GPIO 128 -static inline int gpio_get_value(unsigned gpio) +#define gpio_to_bank(gpio)	((gpio) >> 5) +#define gpio_to_irq(gpio)	IRQ_GPIO(gpio) +#define irq_to_gpio(irq)	IRQ_TO_GPIO(irq) + +#ifdef CONFIG_CPU_PXA26x +/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted, + * as well as their Alternate Function value being '1' for GPIO in GAFRx. + */ +static inline int __gpio_is_inverted(unsigned gpio)  { -	if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) -		return GPLR(gpio) & GPIO_bit(gpio); -	else -		return __gpio_get_value(gpio); +	return cpu_is_pxa25x() && gpio > 85;  } +#else +static inline int __gpio_is_inverted(unsigned gpio) { return 0; } +#endif -static inline void gpio_set_value(unsigned gpio, int value) +/* + * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate + * function of a GPIO, and GPDRx cannot be altered once configured. It + * is attributed as "occupied" here (I know this terminology isn't + * accurate, you are welcome to propose a better one :-) + */ +static inline int __gpio_is_occupied(unsigned gpio)  { -	if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) { -		if (value) -			GPSR(gpio) = GPIO_bit(gpio); +	if (cpu_is_pxa27x() || cpu_is_pxa25x()) { +		int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3; +		int dir = GPDR(gpio) & GPIO_bit(gpio); + +		if (__gpio_is_inverted(gpio)) +			return af != 1 || dir == 0;  		else -			GPCR(gpio) = GPIO_bit(gpio); -	} else { -		__gpio_set_value(gpio, value); -	} +			return af != 0 || dir != 0; +	} else +		return GPDR(gpio) & GPIO_bit(gpio);  } -#define gpio_cansleep __gpio_cansleep - -#define gpio_to_irq(gpio)	IRQ_GPIO(gpio) -#define irq_to_gpio(irq)	IRQ_TO_GPIO(irq) - - +#include <plat/gpio.h>  #endif |