Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7facc2f9 authored by eric miao's avatar eric miao Committed by Russell King
Browse files

[ARM] pxa: add MFP-alike pin configuration support for pxa{25x, 27x}



Pin configuration on pxa{25x,27x} has now separated from generic GPIO
into dedicated mfp-pxa2xx.c by this patch. The name "mfp" is borrowed
from pxa3xx and is used here to alert the difference between the two
concepts: pin configuration and generic GPIOs.  A GPIO can be called
a "GPIO" _only_ when the corresponding pin is configured so.

A pin configuration on pxa{25x,27x} is composed of:

    - alternate function selection (or pin mux as commonly called)
    - low power state or sleep state
    - wakeup enabling from low power mode

The following MFP_xxx bit definitions in mfp.h are re-used:

    - MFP_PIN(x)
    - MFP_AFx
    - MFP_LPM_DRIVE_{LOW, HIGH}
    - MFP_LPM_EDGE_*

Selecting alternate function on pxa{25x, 27x} involves configuration
of GPIO direction register GPDRx, so a new bit and MFP_DIR_{IN, OUT}
are introduced. And pin configurations are defined by the following
two macros:

    - MFP_CFG_IN  : for input alternate functions
    - MFP_CFG_OUT : for output alternate functions

Every configuration should provide a low power state if it configured
as output using MFP_CFG_OUT().  As a general guideline, the low power
state should be decided to minimize the overall power dissipation. As
an example, it is better to drive the pin as high level in low power
mode if the GPIO is configured as an active low chip select.

Pins configured as GPIO are defined by MFP_CFG_IN(). This is to avoid
side effects when it is firstly configured as output.  The actual
direction of the GPIO is configured by gpio_direction_{input, output}

Wakeup enabling on pxa{25x, 27x} is actually GPIO based wakeup, thus
the device based enable_irq_wake() mechanism is not applicable here.

E.g.  invoking enable_irq_wake() with a GPIO IRQ as in the following
code to enable OTG wakeup is by no means portable and intuitive, and
it is valid _only_ when GPIO35 is configured as USB_P2_1:

    enable_irq_wake( gpio_to_irq(35) );

To make things worse, not every GPIO is able to wakeup the system.
Only a small number of them can, on either rising or falling edge,
or when level is high (for keypad GPIOs).

Thus, another new bit is introduced to indicate that the GPIO will
wakeup the system:

    - MFP_LPM_WAKEUP_ENABLE

The following macros can be used in platform code, and be OR'ed to
the GPIO configuration to enable its wakeup:

    - WAKEUP_ON_EDGE_{RISE, FALL, BOTH}
    - WAKEUP_ON_LEVEL_HIGH

The WAKEUP_ON_LEVEL_HIGH is used for keypad GPIOs _only_, there is
no edge settings for those GPIOs.

These WAKEUP_ON_* flags OR'ed on wrong GPIOs will be ignored in case
that platform code author is careless enough.

The tradeoff here is that the wakeup source is fully determined by
the platform configuration, instead of enable_irq_wake().

Signed-off-by: default avatareric miao <eric.miao@marvell.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent a683b14d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@
# Common support (must be linked before board specific support)
obj-y				+= clock.o devices.o generic.o irq.o dma.o \
				   time.o gpio.o
obj-$(CONFIG_PXA25x)		+= pxa25x.o
obj-$(CONFIG_PXA27x)		+= pxa27x.o
obj-$(CONFIG_PXA25x)		+= pxa25x.o mfp-pxa2xx.o
obj-$(CONFIG_PXA27x)		+= pxa27x.o mfp-pxa2xx.o
obj-$(CONFIG_PXA3xx)		+= pxa3xx.o mfp-pxa3xx.o smemc.o
obj-$(CONFIG_CPU_PXA300)	+= pxa300.o
obj-$(CONFIG_CPU_PXA320)	+= pxa320.o
+190 −0
Original line number Diff line number Diff line
/*
 *  linux/arch/arm/mach-pxa/mfp-pxa2xx.c
 *
 *  PXA2xx pin mux configuration support
 *
 *  The GPIOs on PXA2xx can be configured as one of many alternate
 *  functions, this is by concept samilar to the MFP configuration
 *  on PXA3xx,  what's more important, the low power pin state and
 *  wakeup detection are also supported by the same framework.
 *
 *  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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sysdev.h>

#include <asm/arch/hardware.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/mfp-pxa2xx.h>

#include "generic.h"

#define PGSR(x)		__REG2(0x40F00020, ((x) & 0x60) >> 3)

#define PWER_WE35	(1 << 24)

static struct {
	unsigned	valid		: 1;
	unsigned	can_wakeup	: 1;
	unsigned	keypad_gpio	: 1;
	unsigned int	mask; /* bit mask in PWER or PKWR */
	unsigned long	config;
} gpio_desc[MFP_PIN_GPIO127 + 1];

static inline int __mfp_config_gpio(unsigned gpio, unsigned long c)
{
	unsigned long gafr, mask = GPIO_bit(gpio);
	int fn;

	fn = MFP_AF(c);
	if (fn > 3)
		return -EINVAL;

	/* alternate function and direction */
	gafr = GAFR(gpio) & ~(0x3 << ((gpio & 0xf) * 2));
	GAFR(gpio) = gafr |  (fn  << ((gpio & 0xf) * 2));

	if (c & MFP_DIR_OUT)
		GPDR(gpio) |= mask;
	else
		GPDR(gpio) &= ~mask;

	/* low power state */
	switch (c & MFP_LPM_STATE_MASK) {
	case MFP_LPM_DRIVE_HIGH:
		PGSR(gpio) |= mask;
		break;
	case MFP_LPM_DRIVE_LOW:
		PGSR(gpio) &= ~mask;
		break;
	case MFP_LPM_INPUT:
		break;
	default:
		pr_warning("%s: invalid low power state for GPIO%d\n",
				__func__, gpio);
		return -EINVAL;
	}

	/* wakeup enabling */
	if ((c & MFP_LPM_WAKEUP_ENABLE) == 0)
		return 0;

	if (!gpio_desc[gpio].can_wakeup || c & MFP_DIR_OUT) {
		pr_warning("%s: GPIO%d unable to wakeup\n",
				__func__, gpio);
		return -EINVAL;
	}

	if (gpio_desc[gpio].keypad_gpio)
		PKWR |= gpio_desc[gpio].mask;
	else {
		PWER |= gpio_desc[gpio].mask;

		if (c & MFP_LPM_EDGE_RISE)
			PRER |= gpio_desc[gpio].mask;

		if (c & MFP_LPM_EDGE_FALL)
			PFER |= gpio_desc[gpio].mask;
	}

	return 0;
}

void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
{
	unsigned long flags;
	unsigned long *c;
	int i, gpio;

	for (i = 0, c = mfp_cfgs; i < num; i++, c++) {

		gpio = mfp_to_gpio(MFP_PIN(*c));

		if (!gpio_desc[gpio].valid) {
			pr_warning("%s: GPIO%d is invalid pin\n",
				__func__, gpio);
			continue;
		}

		local_irq_save(flags);

		gpio_desc[gpio].config = *c;
		__mfp_config_gpio(gpio, *c);

		local_irq_restore(flags);
	}
}

#ifdef CONFIG_PXA25x
static int __init pxa25x_mfp_init(void)
{
	int i;

	if (cpu_is_pxa25x()) {
		for (i = 0; i <= 84; i++)
			gpio_desc[i].valid = 1;

		for (i = 0; i <= 15; i++) {
			gpio_desc[i].can_wakeup = 1;
			gpio_desc[i].mask = GPIO_bit(i);
		}
	}

	return 0;
}
postcore_initcall(pxa25x_mfp_init);
#endif /* CONFIG_PXA25x */

#ifdef CONFIG_PXA27x
static int pxa27x_pkwr_gpio[] __initdata = {
	13, 16, 17, 34, 36, 37, 38, 39, 90, 91, 93, 94,
	95, 96, 97, 98, 99, 100, 101, 102
};

static int __init pxa27x_mfp_init(void)
{
	int i, gpio;

	if (cpu_is_pxa27x()) {
		for (i = 0; i <= 120; i++) {
			/* skip GPIO2, 5, 6, 7, 8, they are not
			 * valid pins allow configuration
			 */
			if (i == 2 || i == 5 || i == 6 ||
			    i == 7 || i == 8)
				continue;

			gpio_desc[i].valid = 1;
		}

		/* Keypad GPIOs */
		for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
			gpio = pxa27x_pkwr_gpio[i];
			gpio_desc[gpio].can_wakeup = 1;
			gpio_desc[gpio].keypad_gpio = 1;
			gpio_desc[gpio].mask = 1 << i;
		}

		/* Overwrite GPIO13 as a PWER wakeup source */
		for (i = 0; i <= 15; i++) {
			/* skip GPIO2, 5, 6, 7, 8 */
			if (GPIO_bit(i) & 0x1e4)
				continue;

			gpio_desc[i].can_wakeup = 1;
			gpio_desc[i].mask = GPIO_bit(i);
		}

		gpio_desc[35].can_wakeup = 1;
		gpio_desc[35].mask = PWER_WE35;
	}

	return 0;
}
postcore_initcall(pxa27x_mfp_init);
#endif /* CONFIG_PXA27x */
+161 −0
Original line number Diff line number Diff line
#ifndef __ASM_ARCH_MFP_PXA25X_H
#define __ASM_ARCH_MFP_PXA25X_H

#include <asm/arch/mfp.h>
#include <asm/arch/mfp-pxa2xx.h>

/* GPIO */
#define GPIO2_GPIO		MFP_CFG_IN(GPIO2, AF0)
#define GPIO3_GPIO		MFP_CFG_IN(GPIO3, AF0)
#define GPIO4_GPIO		MFP_CFG_IN(GPIO4, AF0)
#define GPIO5_GPIO		MFP_CFG_IN(GPIO5, AF0)
#define GPIO6_GPIO		MFP_CFG_IN(GPIO6, AF0)
#define GPIO7_GPIO		MFP_CFG_IN(GPIO7, AF0)
#define GPIO8_GPIO		MFP_CFG_IN(GPIO8, AF0)

#define GPIO1_RST		MFP_CFG_IN(GPIO1, AF1)

/* Crystal and Clock Signals */
#define GPIO10_RTCCLK		MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
#define GPIO70_RTC_CLK		MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
#define GPIO7_48MHz		MFP_CFG_OUT(GPIO7,  AF1, DRIVE_LOW)
#define GPIO11_3_6MHz		MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
#define GPIO71_3_6MHz		MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW)
#define GPIO12_32KHz		MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
#define GPIO72_32kHz		MFP_CFG_OUT(GPIO72, AF1, DRIVE_LOW)

/* SDRAM and Static Memory I/O Signals */
#define GPIO15_nCS_1		MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
#define GPIO78_nCS_2		MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
#define GPIO79_nCS_3		MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
#define GPIO80_nCS_4		MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
#define GPIO33_nCS_5		MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)

/* Miscellaneous I/O and DMA Signals */
#define GPIO18_RDY		MFP_CFG_IN(GPIO18, AF1)
#define GPIO20_DREQ_0		MFP_CFG_IN(GPIO20, AF1)
#define GPIO19_DREQ_1		MFP_CFG_IN(GPIO19, AF1)

/* Alternate Bus Master Mode I/O Signals */
#define GPIO13_MBGNT		MFP_CFG_OUT(GPIO13, AF2, DRIVE_LOW)
#define GPIO73_MBGNT		MFP_CFG_OUT(GPIO73, AF1, DRIVE_LOW)
#define GPIO14_MBREQ		MFP_CFG_IN(GPIO14, AF1)
#define GPIO66_MBREQ		MFP_CFG_IN(GPIO66, AF1)

/* PC CARD */
#define GPIO52_nPCE_1		MFP_CFG_OUT(GPIO52, AF2, DRIVE_HIGH)
#define GPIO53_nPCE_2		MFP_CFG_OUT(GPIO53, AF2, DRIVE_HIGH)
#define GPIO55_nPREG		MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
#define GPIO50_nPIOR		MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
#define GPIO51_nPIOW		MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
#define GPIO49_nPWE		MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
#define GPIO48_nPOE		MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
#define GPIO57_nIOIS16		MFP_CFG_IN(GPIO57, AF1)
#define GPIO56_nPWAIT		MFP_CFG_IN(GPIO56, AF1)
#define GPIO54_nPSKTSEL		MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)

/* FFUART */
#define GPIO34_FFUART_RXD	MFP_CFG_IN(GPIO34, AF1)
#define GPIO35_FFUART_CTS	MFP_CFG_IN(GPIO35, AF1)
#define GPIO36_FFUART_DCD	MFP_CFG_IN(GPIO36, AF1)
#define GPIO37_FFUART_DSR	MFP_CFG_IN(GPIO37, AF1)
#define GPIO38_FFUART_RI	MFP_CFG_IN(GPIO38, AF1)
#define GPIO39_FFUART_TXD	MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
#define GPIO40_FFUART_DTR	MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
#define GPIO41_FFUART_RTS	MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)

/* BTUART */
#define GPIO42_BTUART_RXD	MFP_CFG_IN(GPIO42, AF1)
#define GPIO43_BTUART_TXD	MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
#define GPIO44_BTUART_CTS	MFP_CFG_IN(GPIO44, AF1)
#define GPIO45_BTUART_RTS	MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)

/* STUART */
#define GPIO46_STUART_RXD	MFP_CFG_IN(GPIO46, AF2)
#define GPIO47_STUART_TXD	MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)

/* HWUART */
#define GPIO42_HWUART_RXD	MFP_CFG_IN(GPIO42, AF3)
#define GPIO43_HWUART_TXD	MFP_CFG_OUT(GPIO43, AF3, DRIVE_HIGH)
#define GPIO44_HWUART_CTS	MFP_CFG_IN(GPIO44, AF3)
#define GPIO45_HWUART_RTS	MFP_CFG_OUT(GPIO45, AF3, DRIVE_HIGH)
#define GPIO48_HWUART_TXD	MFP_CFG_OUT(GPIO48, AF1, DRIVE_HIGH)
#define GPIO49_HWUART_RXD	MFP_CFG_IN(GPIO49, AF1)
#define GPIO50_HWUART_CTS	MFP_CFG_IN(GPIO50, AF1)
#define GPIO51_HWUART_RTS	MFP_CFG_OUT(GPIO51, AF1, DRIVE_HIGH)

/* FICP */
#define GPIO46_FICP_RXD		MFP_CFG_IN(GPIO46, AF1)
#define GPIO47_FICP_TXD		MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)

/* PWM 0/1 */
#define GPIO16_PWM0_OUT		MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
#define GPIO17_PWM1_OUT		MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)

/* AC97 */
#define GPIO28_AC97_BITCLK	MFP_CFG_IN(GPIO28, AF1)
#define GPIO29_AC97_SDATA_IN_0	MFP_CFG_IN(GPIO29, AF1)
#define GPIO30_AC97_SDATA_OUT	MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
#define GPIO31_AC97_SYNC	MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
#define GPIO32_AC97_SDATA_IN_1	MFP_CFG_IN(GPIO32, AF1)

/* I2S */
#define GPIO28_I2S_BITCLK_IN	MFP_CFG_IN(GPIO28, AF2)
#define GPIO28_I2S_BITCLK_OUT	MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
#define GPIO29_I2S_SDATA_IN	MFP_CFG_IN(GPIO29, AF2)
#define GPIO30_I2S_SDATA_OUT	MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
#define GPIO31_I2S_SYNC		MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
#define GPIO32_I2S_SYSCLK	MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)

/* SSP 1 */
#define GPIO23_SSP1_SCLK	MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
#define GPIO24_SSP1_SFRM	MFP_CFG_OUT(GPIO24, AF2, DRIVE_LOW)
#define GPIO25_SSP1_TXD		MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
#define GPIO26_SSP1_RXD		MFP_CFG_IN(GPIO26, AF1)
#define GPIO27_SSP1_EXTCLK	MFP_CFG_IN(GPIO27, AF1)

/* SSP 2 - NSSP */
#define GPIO81_SSP2_CLK_OUT 	MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
#define GPIO81_SSP2_CLK_IN  	MFP_CFG_IN(GPIO81, AF1)
#define GPIO82_SSP2_FRM_OUT 	MFP_CFG_OUT(GPIO82, AF1, DRIVE_LOW)
#define GPIO82_SSP2_FRM_IN  	MFP_CFG_IN(GPIO82, AF1)
#define GPIO83_SSP2_TXD      	MFP_CFG_OUT(GPIO83, AF1, DRIVE_LOW)
#define GPIO83_SSP2_RXD      	MFP_CFG_IN(GPIO83, AF2)
#define GPIO84_SSP2_TXD      	MFP_CFG_OUT(GPIO84, AF1, DRIVE_LOW)
#define GPIO84_SSP2_RXD      	MFP_CFG_IN(GPIO84, AF2)

/* MMC */
#define GPIO6_MMC_CLK		MFP_CFG_OUT(GPIO6, AF1, DRIVE_LOW)
#define GPIO8_MMC_CS0		MFP_CFG_OUT(GPIO8, AF1, DRIVE_LOW)
#define GPIO9_MMC_CS1		MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
#define GPIO34_MMC_CS0		MFP_CFG_OUT(GPIO34, AF2, DRIVE_LOW)
#define GPIO39_MMC_CS1		MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
#define GPIO53_MMC_CLK		MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
#define GPIO54_MMC_CLK		MFP_CFG_OUT(GPIO54, AF1, DRIVE_LOW)
#define GPIO69_MMC_CLK		MFP_CFG_OUT(GPIO69, AF1, DRIVE_LOW)
#define GPIO67_MMC_CS0		MFP_CFG_OUT(GPIO67, AF1, DRIVE_LOW)
#define GPIO68_MMC_CS1		MFP_CFG_OUT(GPIO68, AF1, DRIVE_LOW)

/* LCD */
#define GPIO58_LCD_LDD_0	MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
#define GPIO59_LCD_LDD_1	MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
#define GPIO60_LCD_LDD_2	MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
#define GPIO61_LCD_LDD_3	MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
#define GPIO62_LCD_LDD_4	MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
#define GPIO63_LCD_LDD_5	MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
#define GPIO64_LCD_LDD_6	MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
#define GPIO65_LCD_LDD_7	MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
#define GPIO66_LCD_LDD_8	MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
#define GPIO67_LCD_LDD_9	MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
#define GPIO68_LCD_LDD_10	MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
#define GPIO69_LCD_LDD_11	MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
#define GPIO70_LCD_LDD_12	MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
#define GPIO71_LCD_LDD_13	MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
#define GPIO72_LCD_LDD_14	MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
#define GPIO73_LCD_LDD_15	MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
#define GPIO74_LCD_FCLK		MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
#define GPIO75_LCD_LCLK		MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
#define GPIO76_LCD_PCLK		MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
#define GPIO77_LCD_ACBIAS	MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)

#endif /* __ASM_ARCH_MFP_PXA25X_H */
+431 −0

File added.

Preview size limit exceeded, changes collapsed.

+131 −0
Original line number Diff line number Diff line
#ifndef __ASM_ARCH_MFP_PXA2XX_H
#define __ASM_ARCH_MFP_PXA2XX_H

#include <asm/arch/mfp.h>

/*
 * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
 *
 *  MFP_PIN(x)
 *  MFP_AFx
 *  MFP_LPM_DRIVE_{LOW, HIGH}
 *  MFP_LPM_EDGE_x
 *
 * other MFP_x bit definitions will be ignored
 *
 * and adds the below two bits specifically for pxa2xx:
 *
 * bit     23 - Input/Output (PXA2xx specific)
 * bit     24 - Wakeup Enable(PXA2xx specific)
 */

#define MFP_DIR_IN		(0x0 << 23)
#define MFP_DIR_OUT		(0x1 << 23)
#define MFP_DIR_MASK		(0x1 << 23)
#define MFP_DIR(x)		(((x) >> 23) & 0x1)

#define MFP_LPM_WAKEUP_ENABLE	(0x1 << 24)
#define WAKEUP_ON_EDGE_RISE	(MFP_LPM_WAKEUP_ENABLE | MFP_LPM_EDGE_RISE)
#define WAKEUP_ON_EDGE_FALL	(MFP_LPM_WAKEUP_ENABLE | MFP_LPM_EDGE_FALL)
#define WAKEUP_ON_EDGE_BOTH	(MFP_LPM_WAKEUP_ENABLE | MFP_LPM_EDGE_BOTH)

/* specifically for enabling wakeup on keypad GPIOs */
#define WAKEUP_ON_LEVEL_HIGH	(MFP_LPM_WAKEUP_ENABLE)

#define MFP_CFG_IN(pin, af)		\
	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_IN))

/* NOTE:  pins configured as output _must_ provide a low power state,
 * and this state should help to minimize the power dissipation.
 */
#define MFP_CFG_OUT(pin, af, state)	\
	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))

/* Common configurations for pxa25x and pxa27x
 *
 * Note: pins configured as GPIO are always initialized to input
 * so not to cause any side effect
 */
#define GPIO0_GPIO	MFP_CFG_IN(GPIO0, AF0)
#define GPIO1_GPIO	MFP_CFG_IN(GPIO1, AF0)
#define GPIO9_GPIO	MFP_CFG_IN(GPIO9, AF0)
#define GPIO10_GPIO	MFP_CFG_IN(GPIO10, AF0)
#define GPIO11_GPIO	MFP_CFG_IN(GPIO11, AF0)
#define GPIO12_GPIO	MFP_CFG_IN(GPIO12, AF0)
#define GPIO13_GPIO	MFP_CFG_IN(GPIO13, AF0)
#define GPIO14_GPIO	MFP_CFG_IN(GPIO14, AF0)
#define GPIO15_GPIO	MFP_CFG_IN(GPIO15, AF0)
#define GPIO16_GPIO	MFP_CFG_IN(GPIO16, AF0)
#define GPIO17_GPIO	MFP_CFG_IN(GPIO17, AF0)
#define GPIO18_GPIO	MFP_CFG_IN(GPIO18, AF0)
#define GPIO19_GPIO	MFP_CFG_IN(GPIO19, AF0)
#define GPIO20_GPIO	MFP_CFG_IN(GPIO20, AF0)
#define GPIO21_GPIO	MFP_CFG_IN(GPIO21, AF0)
#define GPIO22_GPIO	MFP_CFG_IN(GPIO22, AF0)
#define GPIO23_GPIO	MFP_CFG_IN(GPIO23, AF0)
#define GPIO24_GPIO	MFP_CFG_IN(GPIO24, AF0)
#define GPIO25_GPIO	MFP_CFG_IN(GPIO25, AF0)
#define GPIO26_GPIO	MFP_CFG_IN(GPIO26, AF0)
#define GPIO27_GPIO	MFP_CFG_IN(GPIO27, AF0)
#define GPIO28_GPIO	MFP_CFG_IN(GPIO28, AF0)
#define GPIO29_GPIO	MFP_CFG_IN(GPIO29, AF0)
#define GPIO30_GPIO	MFP_CFG_IN(GPIO30, AF0)
#define GPIO31_GPIO	MFP_CFG_IN(GPIO31, AF0)
#define GPIO32_GPIO	MFP_CFG_IN(GPIO32, AF0)
#define GPIO33_GPIO	MFP_CFG_IN(GPIO33, AF0)
#define GPIO34_GPIO	MFP_CFG_IN(GPIO34, AF0)
#define GPIO35_GPIO	MFP_CFG_IN(GPIO35, AF0)
#define GPIO36_GPIO	MFP_CFG_IN(GPIO36, AF0)
#define GPIO37_GPIO	MFP_CFG_IN(GPIO37, AF0)
#define GPIO38_GPIO	MFP_CFG_IN(GPIO38, AF0)
#define GPIO39_GPIO	MFP_CFG_IN(GPIO39, AF0)
#define GPIO40_GPIO	MFP_CFG_IN(GPIO40, AF0)
#define GPIO41_GPIO	MFP_CFG_IN(GPIO41, AF0)
#define GPIO42_GPIO	MFP_CFG_IN(GPIO42, AF0)
#define GPIO43_GPIO	MFP_CFG_IN(GPIO43, AF0)
#define GPIO44_GPIO	MFP_CFG_IN(GPIO44, AF0)
#define GPIO45_GPIO	MFP_CFG_IN(GPIO45, AF0)
#define GPIO46_GPIO	MFP_CFG_IN(GPIO46, AF0)
#define GPIO47_GPIO	MFP_CFG_IN(GPIO47, AF0)
#define GPIO48_GPIO	MFP_CFG_IN(GPIO48, AF0)
#define GPIO49_GPIO	MFP_CFG_IN(GPIO49, AF0)
#define GPIO50_GPIO	MFP_CFG_IN(GPIO50, AF0)
#define GPIO51_GPIO	MFP_CFG_IN(GPIO51, AF0)
#define GPIO52_GPIO	MFP_CFG_IN(GPIO52, AF0)
#define GPIO53_GPIO	MFP_CFG_IN(GPIO53, AF0)
#define GPIO54_GPIO	MFP_CFG_IN(GPIO54, AF0)
#define GPIO55_GPIO	MFP_CFG_IN(GPIO55, AF0)
#define GPIO56_GPIO	MFP_CFG_IN(GPIO56, AF0)
#define GPIO57_GPIO	MFP_CFG_IN(GPIO57, AF0)
#define GPIO58_GPIO	MFP_CFG_IN(GPIO58, AF0)
#define GPIO59_GPIO	MFP_CFG_IN(GPIO59, AF0)
#define GPIO60_GPIO	MFP_CFG_IN(GPIO60, AF0)
#define GPIO61_GPIO	MFP_CFG_IN(GPIO61, AF0)
#define GPIO62_GPIO	MFP_CFG_IN(GPIO62, AF0)
#define GPIO63_GPIO	MFP_CFG_IN(GPIO63, AF0)
#define GPIO64_GPIO	MFP_CFG_IN(GPIO64, AF0)
#define GPIO65_GPIO	MFP_CFG_IN(GPIO65, AF0)
#define GPIO66_GPIO	MFP_CFG_IN(GPIO66, AF0)
#define GPIO67_GPIO	MFP_CFG_IN(GPIO67, AF0)
#define GPIO68_GPIO	MFP_CFG_IN(GPIO68, AF0)
#define GPIO69_GPIO	MFP_CFG_IN(GPIO69, AF0)
#define GPIO70_GPIO	MFP_CFG_IN(GPIO70, AF0)
#define GPIO71_GPIO	MFP_CFG_IN(GPIO71, AF0)
#define GPIO72_GPIO	MFP_CFG_IN(GPIO72, AF0)
#define GPIO73_GPIO	MFP_CFG_IN(GPIO73, AF0)
#define GPIO74_GPIO	MFP_CFG_IN(GPIO74, AF0)
#define GPIO75_GPIO	MFP_CFG_IN(GPIO75, AF0)
#define GPIO76_GPIO	MFP_CFG_IN(GPIO76, AF0)
#define GPIO77_GPIO	MFP_CFG_IN(GPIO77, AF0)
#define GPIO78_GPIO	MFP_CFG_IN(GPIO78, AF0)
#define GPIO79_GPIO	MFP_CFG_IN(GPIO79, AF0)
#define GPIO80_GPIO	MFP_CFG_IN(GPIO80, AF0)
#define GPIO81_GPIO	MFP_CFG_IN(GPIO81, AF0)
#define GPIO82_GPIO	MFP_CFG_IN(GPIO82, AF0)
#define GPIO83_GPIO	MFP_CFG_IN(GPIO83, AF0)
#define GPIO84_GPIO	MFP_CFG_IN(GPIO84, AF0)

extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num);
#endif /* __ASM_ARCH_MFP_PXA2XX_H */