[ar71xx] make all AR913x GPIO lines usable
[15.05/openwrt.git] / target / linux / ar71xx / files / arch / mips / ar71xx / gpio.c
1 /*
2  *  Atheros AR71xx SoC GPIO API support
3  *
4  *  Copyright (C) 2008 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         unsigned long flags;
31
32         spin_lock_irqsave(&ar71xx_gpio_lock, flags);
33
34         if (value)
35                 ar71xx_gpio_wr(GPIO_REG_SET, (1 << gpio));
36         else
37                 ar71xx_gpio_wr(GPIO_REG_CLEAR, (1 << gpio));
38
39         spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
40 }
41 EXPORT_SYMBOL(__ar71xx_gpio_set_value);
42
43 int __ar71xx_gpio_get_value(unsigned gpio)
44 {
45         return (ar71xx_gpio_rr(GPIO_REG_IN) & (1 << gpio)) ? 1 : 0;
46 }
47 EXPORT_SYMBOL(__ar71xx_gpio_get_value);
48
49 static int ar71xx_gpio_get_value(struct gpio_chip *chip, unsigned offset)
50 {
51         return __ar71xx_gpio_get_value(offset);
52 }
53
54 static void ar71xx_gpio_set_value(struct gpio_chip *chip,
55                                   unsigned offset, int value)
56 {
57         __ar71xx_gpio_set_value(offset, value);
58 }
59
60 static int ar71xx_gpio_direction_input(struct gpio_chip *chip,
61                                        unsigned offset)
62 {
63         unsigned long flags;
64
65         spin_lock_irqsave(&ar71xx_gpio_lock, flags);
66
67         ar71xx_gpio_wr(GPIO_REG_OE,
68                         ar71xx_gpio_rr(GPIO_REG_OE) & ~(1 << offset));
69
70         spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
71
72         return 0;
73 }
74
75 static int ar71xx_gpio_direction_output(struct gpio_chip *chip,
76                                         unsigned offset, int value)
77 {
78         unsigned long flags;
79
80         spin_lock_irqsave(&ar71xx_gpio_lock, flags);
81
82         if (value)
83                 ar71xx_gpio_wr(GPIO_REG_SET, (1 << offset));
84         else
85                 ar71xx_gpio_wr(GPIO_REG_CLEAR, (1 << offset));
86
87         ar71xx_gpio_wr(GPIO_REG_OE,
88                         ar71xx_gpio_rr(GPIO_REG_OE) | (1 << offset));
89
90         spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
91
92         return 0;
93 }
94
95 static struct gpio_chip ar71xx_gpio_chip = {
96         .label                  = "ar71xx",
97         .get                    = ar71xx_gpio_get_value,
98         .set                    = ar71xx_gpio_set_value,
99         .direction_input        = ar71xx_gpio_direction_input,
100         .direction_output       = ar71xx_gpio_direction_output,
101         .base                   = 0,
102         .ngpio                  = AR71XX_GPIO_COUNT,
103 };
104
105 void ar71xx_gpio_function_enable(u32 mask)
106 {
107         unsigned long flags;
108
109         spin_lock_irqsave(&ar71xx_gpio_lock, flags);
110
111         ar71xx_gpio_wr(GPIO_REG_FUNC, ar71xx_gpio_rr(GPIO_REG_FUNC) | mask);
112
113         spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
114 }
115
116 void ar71xx_gpio_function_disable(u32 mask)
117 {
118         unsigned long flags;
119
120         spin_lock_irqsave(&ar71xx_gpio_lock, flags);
121
122         ar71xx_gpio_wr(GPIO_REG_FUNC, ar71xx_gpio_rr(GPIO_REG_FUNC) & ~mask);
123
124         spin_unlock_irqrestore(&ar71xx_gpio_lock, flags);
125 }
126
127 void __init ar71xx_gpio_init(void)
128 {
129         int err;
130
131         if (!request_mem_region(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
132                                 "AR71xx GPIO controller"))
133                 panic("cannot allocate AR71xx GPIO registers page");
134
135         switch (ar71xx_soc) {
136         case AR71XX_SOC_AR7130:
137         case AR71XX_SOC_AR7141:
138         case AR71XX_SOC_AR7161:
139                 ar71xx_gpio_chip.ngpio = AR71XX_GPIO_COUNT;
140                 break;
141
142         case AR71XX_SOC_AR9130:
143         case AR71XX_SOC_AR9132:
144                 ar71xx_gpio_chip.ngpio = AR91XX_GPIO_COUNT;
145                 break;
146
147         default:
148                 BUG();
149         }
150
151         err = gpiochip_add(&ar71xx_gpio_chip);
152         if (err)
153                 panic("cannot add AR71xx GPIO chip, error=%d", err);
154 }