gpio-pxa.h 4.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Written by Philipp Zabel <philipp.zabel@gmail.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
 *
 */
#ifndef __MACH_PXA_GPIO_PXA_H
#define __MACH_PXA_GPIO_PXA_H

#include <mach/irqs.h>
#include <mach/hardware.h>

#define GPIO_REGS_VIRT	io_p2v(0x40E00000)

#define BANK_OFF(n)	(((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
28
#define GPIO_REG(x)	(*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

/* 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))


#define NR_BUILTIN_GPIO		PXA_GPIO_IRQ_NUM

#define gpio_to_bank(gpio)	((gpio) >> 5)

#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)
{
	return cpu_is_pxa25x() && gpio > 85;
}
#else
static inline int __gpio_is_inverted(unsigned gpio) { return 0; }
#endif

/*
 * 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 (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
			return af != 0 || dir != 0;
	} else
		return GPDR(gpio) & GPIO_bit(gpio);
}

#include <plat/gpio-pxa.h>
#endif /* __MACH_PXA_GPIO_PXA_H */