Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / arch / arm / mach-pxa / gpio.c
blob8638dd7dd076ffd4b8c457571505508e63eb2238
1 /*
2 * linux/arch/arm/mach-pxa/gpio.c
4 * Generic PXA GPIO handling
6 * Author: Nicolas Pitre
7 * Created: Jun 15, 2001
8 * Copyright: MontaVista Software Inc.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/init.h>
16 #include <linux/module.h>
18 #include <asm/gpio.h>
19 #include <asm/hardware.h>
20 #include <asm/io.h>
21 #include <asm/arch/pxa-regs.h>
23 #include "generic.h"
26 struct pxa_gpio_chip {
27 struct gpio_chip chip;
28 void __iomem *regbase;
31 int pxa_last_gpio;
34 * Configure pins for GPIO or other functions
36 int pxa_gpio_mode(int gpio_mode)
38 unsigned long flags;
39 int gpio = gpio_mode & GPIO_MD_MASK_NR;
40 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
41 int gafr;
43 if (gpio > pxa_last_gpio)
44 return -EINVAL;
46 local_irq_save(flags);
47 if (gpio_mode & GPIO_DFLT_LOW)
48 GPCR(gpio) = GPIO_bit(gpio);
49 else if (gpio_mode & GPIO_DFLT_HIGH)
50 GPSR(gpio) = GPIO_bit(gpio);
51 if (gpio_mode & GPIO_MD_MASK_DIR)
52 GPDR(gpio) |= GPIO_bit(gpio);
53 else
54 GPDR(gpio) &= ~GPIO_bit(gpio);
55 gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
56 GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
57 local_irq_restore(flags);
59 return 0;
61 EXPORT_SYMBOL(pxa_gpio_mode);
63 static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
65 unsigned long flags;
66 u32 mask = 1 << offset;
67 u32 value;
68 struct pxa_gpio_chip *pxa;
69 void __iomem *gpdr;
71 pxa = container_of(chip, struct pxa_gpio_chip, chip);
72 gpdr = pxa->regbase + GPDR_OFFSET;
73 local_irq_save(flags);
74 value = __raw_readl(gpdr);
75 value &= ~mask;
76 __raw_writel(value, gpdr);
77 local_irq_restore(flags);
79 return 0;
82 static int pxa_gpio_direction_output(struct gpio_chip *chip,
83 unsigned offset, int value)
85 unsigned long flags;
86 u32 mask = 1 << offset;
87 u32 tmp;
88 struct pxa_gpio_chip *pxa;
89 void __iomem *gpdr;
91 pxa = container_of(chip, struct pxa_gpio_chip, chip);
92 __raw_writel(mask,
93 pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
94 gpdr = pxa->regbase + GPDR_OFFSET;
95 local_irq_save(flags);
96 tmp = __raw_readl(gpdr);
97 tmp |= mask;
98 __raw_writel(tmp, gpdr);
99 local_irq_restore(flags);
101 return 0;
105 * Return GPIO level
107 static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
109 u32 mask = 1 << offset;
110 struct pxa_gpio_chip *pxa;
112 pxa = container_of(chip, struct pxa_gpio_chip, chip);
113 return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
117 * Set output GPIO level
119 static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
121 u32 mask = 1 << offset;
122 struct pxa_gpio_chip *pxa;
124 pxa = container_of(chip, struct pxa_gpio_chip, chip);
126 if (value)
127 __raw_writel(mask, pxa->regbase + GPSR_OFFSET);
128 else
129 __raw_writel(mask, pxa->regbase + GPCR_OFFSET);
132 static struct pxa_gpio_chip pxa_gpio_chip[] = {
133 [0] = {
134 .regbase = GPIO0_BASE,
135 .chip = {
136 .label = "gpio-0",
137 .direction_input = pxa_gpio_direction_input,
138 .direction_output = pxa_gpio_direction_output,
139 .get = pxa_gpio_get,
140 .set = pxa_gpio_set,
141 .base = 0,
142 .ngpio = 32,
145 [1] = {
146 .regbase = GPIO1_BASE,
147 .chip = {
148 .label = "gpio-1",
149 .direction_input = pxa_gpio_direction_input,
150 .direction_output = pxa_gpio_direction_output,
151 .get = pxa_gpio_get,
152 .set = pxa_gpio_set,
153 .base = 32,
154 .ngpio = 32,
157 [2] = {
158 .regbase = GPIO2_BASE,
159 .chip = {
160 .label = "gpio-2",
161 .direction_input = pxa_gpio_direction_input,
162 .direction_output = pxa_gpio_direction_output,
163 .get = pxa_gpio_get,
164 .set = pxa_gpio_set,
165 .base = 64,
166 .ngpio = 32, /* 21 for PXA25x */
169 #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
170 [3] = {
171 .regbase = GPIO3_BASE,
172 .chip = {
173 .label = "gpio-3",
174 .direction_input = pxa_gpio_direction_input,
175 .direction_output = pxa_gpio_direction_output,
176 .get = pxa_gpio_get,
177 .set = pxa_gpio_set,
178 .base = 96,
179 .ngpio = 32,
182 #endif
185 void __init pxa_init_gpio(int gpio_nr)
187 int i;
189 /* add a GPIO chip for each register bank.
190 * the last PXA25x register only contains 21 GPIOs
192 for (i = 0; i < gpio_nr; i += 32) {
193 if (i+32 > gpio_nr)
194 pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i;
195 gpiochip_add(&pxa_gpio_chip[i/32].chip);