Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 123653
b: refs/heads/master
c: 067455a
h: refs/heads/master
i:
  123651: 8473975
v: v3
  • Loading branch information
Eric Miao committed Dec 2, 2008
1 parent bffdca7 commit 46b09a2
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e88db8b91f1f5de24ae6bb3241d92fecaae64abf
refs/heads/master: 067455aa53a55404ded85227e87436478c2acc63
6 changes: 6 additions & 0 deletions trunk/arch/arm/mach-pxa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,12 @@ config PXA27x
help
Select code specific to PXA27x variants

config CPU_PXA26x
bool
select PXA25x
help
Select code specific to PXA26x (codename Dalhart)

config PXA3xx
bool
help
Expand Down
47 changes: 37 additions & 10 deletions trunk/arch/arm/mach-pxa/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ struct pxa_gpio_chip {

int pxa_last_gpio;

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

/*
* Configure pins for GPIO or other functions
*/
Expand Down Expand Up @@ -75,7 +87,10 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
gpdr = pxa->regbase + GPDR_OFFSET;
local_irq_save(flags);
value = __raw_readl(gpdr);
value &= ~mask;
if (__gpio_is_inverted(chip->base + offset))
value |= mask;
else
value &= ~mask;
__raw_writel(value, gpdr);
local_irq_restore(flags);

Expand All @@ -97,7 +112,10 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip,
gpdr = pxa->regbase + GPDR_OFFSET;
local_irq_save(flags);
tmp = __raw_readl(gpdr);
tmp |= mask;
if (__gpio_is_inverted(chip->base + offset))
tmp &= ~mask;
else
tmp |= mask;
__raw_writel(tmp, gpdr);
local_irq_restore(flags);

Expand Down Expand Up @@ -173,10 +191,17 @@ static unsigned long GPIO_IRQ_mask[4];
*/
static int __gpio_is_occupied(unsigned gpio)
{
if (cpu_is_pxa25x() || cpu_is_pxa27x())
return GAFR(gpio) & (0x3 << (((gpio) & 0xf) * 2));
else
return 0;
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;
}

return 0;
}

static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
Expand All @@ -190,9 +215,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
/* Don't mess with enabled GPIOs using preconfigured edges or
* GPIOs set to alternate function or to output during probe
*/
if ((GPIO_IRQ_rising_edge[idx] |
GPIO_IRQ_falling_edge[idx] |
GPDR(gpio)) & GPIO_bit(gpio))
if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) ||
(GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio)))
return 0;

if (__gpio_is_occupied(gpio))
Expand All @@ -201,7 +225,10 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
}

GPDR(gpio) &= ~GPIO_bit(gpio);
if (__gpio_is_inverted(gpio))
GPDR(gpio) |= GPIO_bit(gpio);
else
GPDR(gpio) &= ~GPIO_bit(gpio);

if (type & IRQ_TYPE_EDGE_RISING)
__set_bit(gpio, GPIO_IRQ_rising_edge);
Expand Down
31 changes: 31 additions & 0 deletions trunk/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,35 @@
#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)

#ifdef CONFIG_CPU_PXA26x
/* GPIO */
#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0)
#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF1)
#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF1)
#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF1)
#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF1)

/* SDRAM */
#define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
#define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
#define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
#define GPIO89_nACRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)

/* USB */
#define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1)
#define GPIO32_USB_VP MFP_CFG_IN(GPIO32, AF2)
#define GPIO34_USB_VM MFP_CFG_IN(GPIO34, AF2)
#define GPIO39_USB_VPO MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
#define GPIO56_USB_VMO MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
#define GPIO57_USB_nOE MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)

/* ASSP */
#define GPIO28_ASSP_BITCLK_IN MFP_CFG_IN(GPIO28, AF3)
#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
#define GPIO29_ASSP_RXD MFP_CFG_IN(GPIO29, AF3)
#define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
#define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1)
#define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
#endif

#endif /* __ASM_ARCH_MFP_PXA25X_H */
19 changes: 13 additions & 6 deletions trunk/arch/arm/mach-pxa/mfp-pxa2xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct gpio_desc {
unsigned valid : 1;
unsigned can_wakeup : 1;
unsigned keypad_gpio : 1;
unsigned dir_inverted : 1;
unsigned int mask; /* bit mask in PWER or PKWR */
unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */
unsigned long config;
Expand All @@ -54,7 +55,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
int shft = (gpio & 0xf) << 1;
int fn = MFP_AF(c);
int dir = c & MFP_DIR_OUT;
int is_out = (c & MFP_DIR_OUT) ? 1 : 0;

if (fn > 3)
return -EINVAL;
Expand All @@ -68,7 +69,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
else
GAFR_U(bank) = gafr;

if (dir == MFP_DIR_OUT)
if (is_out ^ gpio_desc[gpio].dir_inverted)
GPDR(gpio) |= mask;
else
GPDR(gpio) &= ~mask;
Expand All @@ -77,11 +78,11 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
switch (c & MFP_LPM_STATE_MASK) {
case MFP_LPM_DRIVE_HIGH:
PGSR(bank) |= mask;
dir = MFP_DIR_OUT;
is_out = 1;
break;
case MFP_LPM_DRIVE_LOW:
PGSR(bank) &= ~mask;
dir = MFP_DIR_OUT;
is_out = 1;
break;
case MFP_LPM_DEFAULT:
break;
Expand All @@ -92,7 +93,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
break;
}

if (dir == MFP_DIR_OUT)
if (is_out ^ gpio_desc[gpio].dir_inverted)
gpdr_lpm[bank] |= mask;
else
gpdr_lpm[bank] &= ~mask;
Expand All @@ -106,7 +107,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
return -EINVAL;
}

if ((c & MFP_LPM_CAN_WAKEUP) && (dir == MFP_DIR_OUT)) {
if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
pr_warning("%s: output GPIO%d unable to wakeup\n",
__func__, gpio);
return -EINVAL;
Expand Down Expand Up @@ -221,6 +222,12 @@ static void __init pxa25x_mfp_init(void)
gpio_desc[i].can_wakeup = 1;
gpio_desc[i].mask = GPIO_bit(i);
}

/* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
* direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
*/
for (i = 86; i <= pxa_last_gpio; i++)
gpio_desc[i].dir_inverted = 1;
}
#else
static inline void pxa25x_mfp_init(void) {}
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/arm/mach-pxa/pxa25x.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,14 @@ void __init pxa25x_init_irq(void)
pxa_init_gpio(85, pxa25x_set_wake);
}

#ifdef CONFIG_CPU_PXA26x
void __init pxa26x_init_irq(void)
{
pxa_init_irq(32, pxa25x_set_wake);
pxa_init_gpio(90, pxa25x_set_wake);
}
#endif

static struct platform_device *pxa25x_devices[] __initdata = {
&pxa25x_device_udc,
&pxa_device_ffuart,
Expand Down

0 comments on commit 46b09a2

Please sign in to comment.