91c838345d2ae05a7965d05b121795d3fa364a52
[openwrt.git] / target / linux / ar71xx / files / arch / mips / ar71xx / gpio.c
1 /*
2 * Atheros AR7XXX/AR9XXX SoC GPIO API support
3 *
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation.
10 */
11
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/types.h>
16 #include <linux/spinlock.h>
17 #include <linux/io.h>
18 #include <linux/ioport.h>
19 #include <linux/gpio.h>
20
21 #include <asm/mach-ar71xx/ar71xx.h>
22
23 static DEFINE_SPINLOCK(ar71xx_gpio_lock);
24
25 unsigned long ar71xx_gpio_count;
26 EXPORT_SYMBOL(ar71xx_gpio_count);
27
28 void __ar71xx_gpio_set_value(unsigned gpio, int value)
29 {
30 void __iomem *base = ar71xx_gpio_base;
31
32 if (value)
33 __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
34 else
35 __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
36 }
37 EXPORT_SYMBOL(__ar71xx_gpio_set_value);
38
39 int __ar71xx_gpio_get_value(unsigned gpio)
40 {
41 return (__raw_readl(ar71xx_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
42 }
43 EXPORT_SYMBOL(__ar71xx_gpio_get_value);
44
45 static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
46 {
47 return __ar71xx_gpio_get_value(offset);
48 }
49
50 static void ar71xx_gpio_set_value(struct gpio_chip *chip,
51 unsigned offset, int value)
52 {
53 __ar71xx_gpio_set_value(offset, value);
54 }
55
56 static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
57 unsigned offset)
58 {
59 void __iomem *base = ar71xx_gpio_base;
60 unsigned long flags;
61
62 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
63
64 __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
65 base + AR71XX_GPIO_REG_OE);
66
67 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
68
69 return 0;
70 }
71
72 static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
73 unsigned offset, int value)
74 {
75 void __iomem *base = ar71xx_gpio_base;
76 unsigned long flags;
77
78 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
79
80 if (value)
81 __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
82 else
83 __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
84
85 __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
86 base + AR71XX_GPIO_REG_OE);
87
88 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
89
90 return 0;
91 }
92
93 static int ar934x_gpio_direction_input(struct gpio_chip *chip,
94 unsigned offset)
95 {
96 void __iomem *base = ar71xx_gpio_base;
97 unsigned long flags;
98
99 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
100
101 __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
102 base + AR71XX_GPIO_REG_OE);
103
104 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
105
106 return 0;
107 }
108
109 static int ar934x_gpio_direction_output(struct gpio_chip *chip,
110 unsigned offset, int value)
111 {
112 void __iomem *base = ar71xx_gpio_base;
113 unsigned long flags;
114
115 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
116
117 if (value)
118 __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
119 else
120 __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
121
122 __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
123 base + AR71XX_GPIO_REG_OE);
124
125 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
126
127 return 0;
128 }
129
130 static struct gpio_chip ar71xx_gpio_chip = {
131 .label = "ar71xx",
132 .get = ar71xx_gpio_get_value,
133 .set = ar71xx_gpio_set_value,
134 .direction_input = ar71xx_gpio_direction_input,
135 .direction_output = ar71xx_gpio_direction_output,
136 .base = 0,
137 .ngpio = AR71XX_GPIO_COUNT,
138 };
139
140 void ar71xx_gpio_function_enable(u32 mask)
141 {
142 void __iomem *base = ar71xx_gpio_base;
143 unsigned long flags;
144 unsigned int reg;
145
146 if (ar71xx_soc == AR71XX_SOC_AR9341 ||
147 ar71xx_soc == AR71XX_SOC_AR9342 ||
148 ar71xx_soc == AR71XX_SOC_AR9344) {
149 reg = AR934X_GPIO_REG_FUNC;
150 } else {
151 reg = AR71XX_GPIO_REG_FUNC;
152 }
153
154 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
155
156 __raw_writel(__raw_readl(base + reg) | mask, base + reg);
157 /* flush write */
158 (void) __raw_readl(base + reg);
159
160 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
161 }
162
163 void ar71xx_gpio_function_disable(u32 mask)
164 {
165 void __iomem *base = ar71xx_gpio_base;
166 unsigned long flags;
167 unsigned int reg;
168
169 if (ar71xx_soc == AR71XX_SOC_AR9341 ||
170 ar71xx_soc == AR71XX_SOC_AR9342 ||
171 ar71xx_soc == AR71XX_SOC_AR9344) {
172 reg = AR934X_GPIO_REG_FUNC;
173 } else {
174 reg = AR71XX_GPIO_REG_FUNC;
175 }
176
177 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
178
179 __raw_writel(__raw_readl(base + reg) & ~mask, base + reg);
180 /* flush write */
181 (void) __raw_readl(base + reg);
182
183 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
184 }
185
186 void ar71xx_gpio_function_setup(u32 set, u32 clear)
187 {
188 void __iomem *base = ar71xx_gpio_base;
189 unsigned long flags;
190 unsigned int reg;
191
192 if (ar71xx_soc == AR71XX_SOC_AR9341 ||
193 ar71xx_soc == AR71XX_SOC_AR9342 ||
194 ar71xx_soc == AR71XX_SOC_AR9344) {
195 reg = AR934X_GPIO_REG_FUNC;
196 } else {
197 reg = AR71XX_GPIO_REG_FUNC;
198 }
199
200 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
201
202 __raw_writel((__raw_readl(base + reg) & ~clear) | set, base + reg);
203 /* flush write */
204 (void) __raw_readl(base + reg);
205
206 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
207 }
208 EXPORT_SYMBOL(ar71xx_gpio_function_setup);
209
210 void __init ar71xx_gpio_output_select(unsigned gpio, u8 val)
211 {
212 void __iomem *base = ar71xx_gpio_base;
213 unsigned long flags;
214 unsigned int reg;
215 u32 t, s;
216
217 if (ar71xx_soc != AR71XX_SOC_AR9341 &&
218 ar71xx_soc != AR71XX_SOC_AR9342 &&
219 ar71xx_soc != AR71XX_SOC_AR9344)
220 return;
221
222 if (gpio >= AR934X_GPIO_COUNT)
223 return;
224
225 reg = AR934X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4);
226 s = 8 * (gpio % 4);
227
228 spin_lock_irqsave(&ar71xx_gpio_lock, flags);
229
230 t = __raw_readl(base + reg);
231 t &= ~(0xff << s);
232 t |= val << s;
233 __raw_writel(t, base + reg);
234
235 /* flush write */
236 (void) __raw_readl(base + reg);
237
238 spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
239 }
240
241 void __init ar71xx_gpio_init(void)
242 {
243 int err;
244
245 if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
246 "AR71xx GPIO controller"))
247 panic("cannot allocate AR71xx GPIO registers page");
248
249 switch (ar71xx_soc) {
250 case AR71XX_SOC_AR7130:
251 case AR71XX_SOC_AR7141:
252 case AR71XX_SOC_AR7161:
253 ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
254 break;
255
256 case AR71XX_SOC_AR7240:
257 ar71xx_gpio_chip.ngpio = AR7240_GPIO_COUNT;
258 break;
259
260 case AR71XX_SOC_AR7241:
261 case AR71XX_SOC_AR7242:
262 ar71xx_gpio_chip.ngpio = AR7241_GPIO_COUNT;
263 break;
264
265 case AR71XX_SOC_AR9130:
266 case AR71XX_SOC_AR9132:
267 ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
268 break;
269
270 case AR71XX_SOC_AR9330:
271 case AR71XX_SOC_AR9331:
272 ar71xx_gpio_chip.ngpio = AR933X_GPIO_COUNT;
273 break;
274
275 case AR71XX_SOC_AR9341:
276 case AR71XX_SOC_AR9342:
277 case AR71XX_SOC_AR9344:
278 ar71xx_gpio_chip.ngpio = AR934X_GPIO_COUNT;
279 ar71xx_gpio_chip.direction_input = ar934x_gpio_direction_input;
280 ar71xx_gpio_chip.direction_output = ar934x_gpio_direction_output;
281 break;
282
283 default:
284 BUG();
285 }
286
287 err = gpiochip_add(&ar71xx_gpio_chip);
288 if (err)
289 panic("cannot add AR71xx GPIO chip, error=%d", err);
290 }
291
292 int gpio_to_irq(unsigned gpio)
293 {
294 return AR71XX_GPIO_IRQ(gpio);
295 }
296 EXPORT_SYMBOL(gpio_to_irq);
297
298 int irq_to_gpio(unsigned irq)
299 {
300 return irq - AR71XX_GPIO_IRQ_BASE;
301 }
302 EXPORT_SYMBOL(irq_to_gpio);
This page took 0.064174 seconds and 3 git commands to generate.