ar71xx: switch to 3.2.5
[openwrt.git] / target / linux / ar71xx / files-2.6.39 / 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);