diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2010-07-17 07:11:19 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-08-05 08:26:15 -0400 |
commit | a55f4506652cbdf23fa1b5fd509d4f3cc01e1843 (patch) | |
tree | 1b762c54723f9850cc2760a935deb288b98576d1 | |
parent | 713233fbaf8c859f71b246c81baf082c0e6b9625 (diff) |
MIPS: JZ4740: Add GPIO support
Add gpiolib support for JZ4740 SoCs.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/1467/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/include/asm/mach-jz4740/gpio.h | 398 | ||||
-rw-r--r-- | arch/mips/jz4740/gpio.c | 604 |
2 files changed, 1002 insertions, 0 deletions
diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h new file mode 100644 index 000000000000..7b74703745bb --- /dev/null +++ b/arch/mips/include/asm/mach-jz4740/gpio.h | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> | ||
3 | * JZ4740 GPIO pin definitions | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License along | ||
11 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
12 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef _JZ_GPIO_H | ||
17 | #define _JZ_GPIO_H | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | |||
21 | enum jz_gpio_function { | ||
22 | JZ_GPIO_FUNC_NONE, | ||
23 | JZ_GPIO_FUNC1, | ||
24 | JZ_GPIO_FUNC2, | ||
25 | JZ_GPIO_FUNC3, | ||
26 | }; | ||
27 | |||
28 | |||
29 | /* | ||
30 | Usually a driver for a SoC component has to request several gpio pins and | ||
31 | configure them as funcion pins. | ||
32 | jz_gpio_bulk_request can be used to ease this process. | ||
33 | Usually one would do something like: | ||
34 | |||
35 | const static struct jz_gpio_bulk_request i2c_pins[] = { | ||
36 | JZ_GPIO_BULK_PIN(I2C_SDA), | ||
37 | JZ_GPIO_BULK_PIN(I2C_SCK), | ||
38 | }; | ||
39 | |||
40 | inside the probe function: | ||
41 | |||
42 | ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins)); | ||
43 | if (ret) { | ||
44 | ... | ||
45 | |||
46 | inside the remove function: | ||
47 | |||
48 | jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins)); | ||
49 | |||
50 | |||
51 | */ | ||
52 | struct jz_gpio_bulk_request { | ||
53 | int gpio; | ||
54 | const char *name; | ||
55 | enum jz_gpio_function function; | ||
56 | }; | ||
57 | |||
58 | #define JZ_GPIO_BULK_PIN(pin) { \ | ||
59 | .gpio = JZ_GPIO_ ## pin, \ | ||
60 | .name = #pin, \ | ||
61 | .function = JZ_GPIO_FUNC_ ## pin \ | ||
62 | } | ||
63 | |||
64 | int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num); | ||
65 | void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num); | ||
66 | void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num); | ||
67 | void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num); | ||
68 | void jz_gpio_enable_pullup(unsigned gpio); | ||
69 | void jz_gpio_disable_pullup(unsigned gpio); | ||
70 | int jz_gpio_set_function(int gpio, enum jz_gpio_function function); | ||
71 | |||
72 | int jz_gpio_port_direction_input(int port, uint32_t mask); | ||
73 | int jz_gpio_port_direction_output(int port, uint32_t mask); | ||
74 | void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask); | ||
75 | uint32_t jz_gpio_port_get_value(int port, uint32_t mask); | ||
76 | |||
77 | #include <asm/mach-generic/gpio.h> | ||
78 | |||
79 | #define JZ_GPIO_PORTA(x) ((x) + 32 * 0) | ||
80 | #define JZ_GPIO_PORTB(x) ((x) + 32 * 1) | ||
81 | #define JZ_GPIO_PORTC(x) ((x) + 32 * 2) | ||
82 | #define JZ_GPIO_PORTD(x) ((x) + 32 * 3) | ||
83 | |||
84 | /* Port A function pins */ | ||
85 | #define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0) | ||
86 | #define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1) | ||
87 | #define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2) | ||
88 | #define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3) | ||
89 | #define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4) | ||
90 | #define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5) | ||
91 | #define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6) | ||
92 | #define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7) | ||
93 | #define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8) | ||
94 | #define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9) | ||
95 | #define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10) | ||
96 | #define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11) | ||
97 | #define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12) | ||
98 | #define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13) | ||
99 | #define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14) | ||
100 | #define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15) | ||
101 | #define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16) | ||
102 | #define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17) | ||
103 | #define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18) | ||
104 | #define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19) | ||
105 | #define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20) | ||
106 | #define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21) | ||
107 | #define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22) | ||
108 | #define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23) | ||
109 | #define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24) | ||
110 | #define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25) | ||
111 | #define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26) | ||
112 | #define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27) | ||
113 | #define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28) | ||
114 | #define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29) | ||
115 | #define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30) | ||
116 | #define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31) | ||
117 | |||
118 | #define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1 | ||
119 | #define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1 | ||
120 | #define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1 | ||
121 | #define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1 | ||
122 | #define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1 | ||
123 | #define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1 | ||
124 | #define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1 | ||
125 | #define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1 | ||
126 | #define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1 | ||
127 | #define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1 | ||
128 | #define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1 | ||
129 | #define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1 | ||
130 | #define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1 | ||
131 | #define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1 | ||
132 | #define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1 | ||
133 | #define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1 | ||
134 | #define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1 | ||
135 | #define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1 | ||
136 | #define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1 | ||
137 | #define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1 | ||
138 | #define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1 | ||
139 | #define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1 | ||
140 | #define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1 | ||
141 | #define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1 | ||
142 | #define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1 | ||
143 | #define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1 | ||
144 | #define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1 | ||
145 | #define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1 | ||
146 | #define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1 | ||
147 | #define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1 | ||
148 | #define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1 | ||
149 | #define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1 | ||
150 | |||
151 | /* Port B function pins */ | ||
152 | #define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0) | ||
153 | #define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1) | ||
154 | #define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2) | ||
155 | #define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3) | ||
156 | #define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4) | ||
157 | #define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5) | ||
158 | #define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6) | ||
159 | #define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7) | ||
160 | #define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8) | ||
161 | #define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9) | ||
162 | #define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10) | ||
163 | #define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11) | ||
164 | #define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12) | ||
165 | #define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13) | ||
166 | #define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14) | ||
167 | #define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15) | ||
168 | #define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16) | ||
169 | #define JZ_GPIO_LCD_CLS JZ_GPIO_PORTB(17) | ||
170 | #define JZ_GPIO_LCD_SPL JZ_GPIO_PORTB(18) | ||
171 | #define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19) | ||
172 | #define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20) | ||
173 | #define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21) | ||
174 | #define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22) | ||
175 | #define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23) | ||
176 | #define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24) | ||
177 | #define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25) | ||
178 | #define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26) | ||
179 | #define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27) | ||
180 | #define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28) | ||
181 | #define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29) | ||
182 | #define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30) | ||
183 | #define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31) | ||
184 | |||
185 | #define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1 | ||
186 | #define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1 | ||
187 | #define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1 | ||
188 | #define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1 | ||
189 | #define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1 | ||
190 | #define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1 | ||
191 | #define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1 | ||
192 | #define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1 | ||
193 | #define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1 | ||
194 | #define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1 | ||
195 | #define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1 | ||
196 | #define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1 | ||
197 | #define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1 | ||
198 | #define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1 | ||
199 | #define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1 | ||
200 | #define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1 | ||
201 | #define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1 | ||
202 | #define JZ_GPIO_FUNC_LCD_CLS JZ_GPIO_FUNC1 | ||
203 | #define JZ_GPIO_FUNC_LCD_SPL JZ_GPIO_FUNC1 | ||
204 | #define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1 | ||
205 | #define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1 | ||
206 | #define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1 | ||
207 | #define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1 | ||
208 | #define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1 | ||
209 | #define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1 | ||
210 | #define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1 | ||
211 | #define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1 | ||
212 | #define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1 | ||
213 | #define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1 | ||
214 | #define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1 | ||
215 | #define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1 | ||
216 | #define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1 | ||
217 | |||
218 | |||
219 | #define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17) | ||
220 | #define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18) | ||
221 | |||
222 | #define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2 | ||
223 | #define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2 | ||
224 | |||
225 | /* Port C function pins */ | ||
226 | #define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0) | ||
227 | #define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1) | ||
228 | #define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2) | ||
229 | #define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3) | ||
230 | #define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4) | ||
231 | #define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5) | ||
232 | #define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6) | ||
233 | #define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7) | ||
234 | #define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8) | ||
235 | #define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9) | ||
236 | #define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10) | ||
237 | #define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11) | ||
238 | #define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12) | ||
239 | #define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13) | ||
240 | #define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14) | ||
241 | #define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15) | ||
242 | #define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16) | ||
243 | #define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17) | ||
244 | #define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18) | ||
245 | #define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19) | ||
246 | #define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20) | ||
247 | #define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21) | ||
248 | #define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22) | ||
249 | #define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23) | ||
250 | #define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24) | ||
251 | #define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25) | ||
252 | #define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26) | ||
253 | #define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27) | ||
254 | #define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28) | ||
255 | #define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29) | ||
256 | |||
257 | #define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1 | ||
258 | #define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1 | ||
259 | #define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1 | ||
260 | #define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1 | ||
261 | #define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1 | ||
262 | #define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1 | ||
263 | #define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1 | ||
264 | #define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1 | ||
265 | #define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1 | ||
266 | #define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1 | ||
267 | #define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1 | ||
268 | #define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1 | ||
269 | #define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1 | ||
270 | #define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1 | ||
271 | #define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1 | ||
272 | #define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1 | ||
273 | #define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1 | ||
274 | #define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1 | ||
275 | #define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1 | ||
276 | #define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1 | ||
277 | #define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1 | ||
278 | #define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1 | ||
279 | #define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1 | ||
280 | #define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1 | ||
281 | #define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1 | ||
282 | #define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1 | ||
283 | #define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1 | ||
284 | #define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1 | ||
285 | #define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1 | ||
286 | #define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1 | ||
287 | |||
288 | |||
289 | #define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22) | ||
290 | #define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23) | ||
291 | |||
292 | #define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2 | ||
293 | #define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2 | ||
294 | |||
295 | /* Port D function pins */ | ||
296 | #define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0) | ||
297 | #define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1) | ||
298 | #define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2) | ||
299 | #define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3) | ||
300 | #define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4) | ||
301 | #define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5) | ||
302 | #define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6) | ||
303 | #define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7) | ||
304 | #define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8) | ||
305 | #define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9) | ||
306 | #define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10) | ||
307 | #define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11) | ||
308 | #define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12) | ||
309 | #define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13) | ||
310 | #define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14) | ||
311 | #define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15) | ||
312 | #define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16) | ||
313 | #define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17) | ||
314 | #define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18) | ||
315 | #define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19) | ||
316 | #define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20) | ||
317 | #define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21) | ||
318 | #define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22) | ||
319 | #define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23) | ||
320 | #define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24) | ||
321 | #define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25) | ||
322 | #define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26) | ||
323 | #define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27) | ||
324 | #define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28) | ||
325 | #define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30) | ||
326 | #define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31) | ||
327 | |||
328 | #define JZ_GPIO_FUNC_CIM_DATA JZ_GPIO_FUNC1 | ||
329 | #define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC_CIM_DATA | ||
330 | #define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC_CIM_DATA | ||
331 | #define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC_CIM_DATA | ||
332 | #define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC_CIM_DATA | ||
333 | #define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC_CIM_DATA | ||
334 | #define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC_CIM_DATA | ||
335 | #define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC_CIM_DATA | ||
336 | #define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC_CIM_DATA | ||
337 | #define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1 | ||
338 | #define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1 | ||
339 | #define JZ_GPIO_FUNC_MSC_DATA JZ_GPIO_FUNC1 | ||
340 | #define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC_MSC_DATA | ||
341 | #define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC_MSC_DATA | ||
342 | #define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC_MSC_DATA | ||
343 | #define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC_MSC_DATA | ||
344 | #define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1 | ||
345 | #define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1 | ||
346 | #define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1 | ||
347 | #define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1 | ||
348 | #define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1 | ||
349 | #define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1 | ||
350 | #define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1 | ||
351 | #define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1 | ||
352 | #define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1 | ||
353 | |||
354 | #define JZ_GPIO_FUNC_PWM JZ_GPIO_FUNC1 | ||
355 | #define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC_PWM | ||
356 | #define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC_PWM | ||
357 | #define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC_PWM | ||
358 | #define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC_PWM | ||
359 | #define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC_PWM | ||
360 | #define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC_PWM | ||
361 | #define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC_PWM | ||
362 | #define JZ_GPIO_FUNC_PWM7 JZ_GPIO_FUNC_PWM | ||
363 | |||
364 | #define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18) | ||
365 | #define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19) | ||
366 | #define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20) | ||
367 | #define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21) | ||
368 | #define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22) | ||
369 | #define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23) | ||
370 | #define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24) | ||
371 | #define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25) | ||
372 | #define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26) | ||
373 | #define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27) | ||
374 | #define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28) | ||
375 | #define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30) | ||
376 | #define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31) | ||
377 | |||
378 | #define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2 | ||
379 | #define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2 | ||
380 | #define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2 | ||
381 | #define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2 | ||
382 | #define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2 | ||
383 | #define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2 | ||
384 | #define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2 | ||
385 | #define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2 | ||
386 | #define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2 | ||
387 | #define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2 | ||
388 | #define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2 | ||
389 | #define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2 | ||
390 | #define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2 | ||
391 | |||
392 | #define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30) | ||
393 | #define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31) | ||
394 | |||
395 | #define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3 | ||
396 | #define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3 | ||
397 | |||
398 | #endif | ||
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c new file mode 100644 index 000000000000..38f60f35156c --- /dev/null +++ b/arch/mips/jz4740/gpio.c | |||
@@ -0,0 +1,604 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> | ||
3 | * JZ4740 platform GPIO support | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License along | ||
11 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
12 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/sysdev.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/bitops.h> | ||
27 | |||
28 | #include <linux/debugfs.h> | ||
29 | #include <linux/seq_file.h> | ||
30 | |||
31 | #include <asm/mach-jz4740/base.h> | ||
32 | |||
33 | #define JZ4740_GPIO_BASE_A (32*0) | ||
34 | #define JZ4740_GPIO_BASE_B (32*1) | ||
35 | #define JZ4740_GPIO_BASE_C (32*2) | ||
36 | #define JZ4740_GPIO_BASE_D (32*3) | ||
37 | |||
38 | #define JZ4740_GPIO_NUM_A 32 | ||
39 | #define JZ4740_GPIO_NUM_B 32 | ||
40 | #define JZ4740_GPIO_NUM_C 31 | ||
41 | #define JZ4740_GPIO_NUM_D 32 | ||
42 | |||
43 | #define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A) | ||
44 | #define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B) | ||
45 | #define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C) | ||
46 | #define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D) | ||
47 | |||
48 | #define JZ_REG_GPIO_PIN 0x00 | ||
49 | #define JZ_REG_GPIO_DATA 0x10 | ||
50 | #define JZ_REG_GPIO_DATA_SET 0x14 | ||
51 | #define JZ_REG_GPIO_DATA_CLEAR 0x18 | ||
52 | #define JZ_REG_GPIO_MASK 0x20 | ||
53 | #define JZ_REG_GPIO_MASK_SET 0x24 | ||
54 | #define JZ_REG_GPIO_MASK_CLEAR 0x28 | ||
55 | #define JZ_REG_GPIO_PULL 0x30 | ||
56 | #define JZ_REG_GPIO_PULL_SET 0x34 | ||
57 | #define JZ_REG_GPIO_PULL_CLEAR 0x38 | ||
58 | #define JZ_REG_GPIO_FUNC 0x40 | ||
59 | #define JZ_REG_GPIO_FUNC_SET 0x44 | ||
60 | #define JZ_REG_GPIO_FUNC_CLEAR 0x48 | ||
61 | #define JZ_REG_GPIO_SELECT 0x50 | ||
62 | #define JZ_REG_GPIO_SELECT_SET 0x54 | ||
63 | #define JZ_REG_GPIO_SELECT_CLEAR 0x58 | ||
64 | #define JZ_REG_GPIO_DIRECTION 0x60 | ||
65 | #define JZ_REG_GPIO_DIRECTION_SET 0x64 | ||
66 | #define JZ_REG_GPIO_DIRECTION_CLEAR 0x68 | ||
67 | #define JZ_REG_GPIO_TRIGGER 0x70 | ||
68 | #define JZ_REG_GPIO_TRIGGER_SET 0x74 | ||
69 | #define JZ_REG_GPIO_TRIGGER_CLEAR 0x78 | ||
70 | #define JZ_REG_GPIO_FLAG 0x80 | ||
71 | #define JZ_REG_GPIO_FLAG_CLEAR 0x14 | ||
72 | |||
73 | #define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f) | ||
74 | #define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg)) | ||
75 | #define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg)) | ||
76 | |||
77 | struct jz_gpio_chip { | ||
78 | unsigned int irq; | ||
79 | unsigned int irq_base; | ||
80 | uint32_t wakeup; | ||
81 | uint32_t suspend_mask; | ||
82 | uint32_t edge_trigger_both; | ||
83 | |||
84 | void __iomem *base; | ||
85 | |||
86 | spinlock_t lock; | ||
87 | |||
88 | struct gpio_chip gpio_chip; | ||
89 | struct irq_chip irq_chip; | ||
90 | struct sys_device sysdev; | ||
91 | }; | ||
92 | |||
93 | static struct jz_gpio_chip jz4740_gpio_chips[]; | ||
94 | |||
95 | static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio) | ||
96 | { | ||
97 | return &jz4740_gpio_chips[gpio >> 5]; | ||
98 | } | ||
99 | |||
100 | static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip) | ||
101 | { | ||
102 | return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip); | ||
103 | } | ||
104 | |||
105 | static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(unsigned int irq) | ||
106 | { | ||
107 | return get_irq_chip_data(irq); | ||
108 | } | ||
109 | |||
110 | static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) | ||
111 | { | ||
112 | writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg)); | ||
113 | } | ||
114 | |||
115 | int jz_gpio_set_function(int gpio, enum jz_gpio_function function) | ||
116 | { | ||
117 | if (function == JZ_GPIO_FUNC_NONE) { | ||
118 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR); | ||
119 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR); | ||
120 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR); | ||
121 | } else { | ||
122 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET); | ||
123 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR); | ||
124 | switch (function) { | ||
125 | case JZ_GPIO_FUNC1: | ||
126 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR); | ||
127 | break; | ||
128 | case JZ_GPIO_FUNC3: | ||
129 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET); | ||
130 | case JZ_GPIO_FUNC2: /* Falltrough */ | ||
131 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET); | ||
132 | break; | ||
133 | default: | ||
134 | BUG(); | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | EXPORT_SYMBOL_GPL(jz_gpio_set_function); | ||
142 | |||
143 | int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num) | ||
144 | { | ||
145 | size_t i; | ||
146 | int ret; | ||
147 | |||
148 | for (i = 0; i < num; ++i, ++request) { | ||
149 | ret = gpio_request(request->gpio, request->name); | ||
150 | if (ret) | ||
151 | goto err; | ||
152 | jz_gpio_set_function(request->gpio, request->function); | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | err: | ||
158 | for (--request; i > 0; --i, --request) { | ||
159 | gpio_free(request->gpio); | ||
160 | jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE); | ||
161 | } | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | EXPORT_SYMBOL_GPL(jz_gpio_bulk_request); | ||
166 | |||
167 | void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num) | ||
168 | { | ||
169 | size_t i; | ||
170 | |||
171 | for (i = 0; i < num; ++i, ++request) { | ||
172 | gpio_free(request->gpio); | ||
173 | jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE); | ||
174 | } | ||
175 | |||
176 | } | ||
177 | EXPORT_SYMBOL_GPL(jz_gpio_bulk_free); | ||
178 | |||
179 | void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num) | ||
180 | { | ||
181 | size_t i; | ||
182 | |||
183 | for (i = 0; i < num; ++i, ++request) { | ||
184 | jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE); | ||
185 | jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR); | ||
186 | jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET); | ||
187 | } | ||
188 | } | ||
189 | EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend); | ||
190 | |||
191 | void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num) | ||
192 | { | ||
193 | size_t i; | ||
194 | |||
195 | for (i = 0; i < num; ++i, ++request) | ||
196 | jz_gpio_set_function(request->gpio, request->function); | ||
197 | } | ||
198 | EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume); | ||
199 | |||
200 | void jz_gpio_enable_pullup(unsigned gpio) | ||
201 | { | ||
202 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR); | ||
203 | } | ||
204 | EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup); | ||
205 | |||
206 | void jz_gpio_disable_pullup(unsigned gpio) | ||
207 | { | ||
208 | jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET); | ||
209 | } | ||
210 | EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup); | ||
211 | |||
212 | static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio) | ||
213 | { | ||
214 | return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio)); | ||
215 | } | ||
216 | |||
217 | static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) | ||
218 | { | ||
219 | uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET); | ||
220 | reg += !value; | ||
221 | writel(BIT(gpio), reg); | ||
222 | } | ||
223 | |||
224 | static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, | ||
225 | int value) | ||
226 | { | ||
227 | writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET)); | ||
228 | jz_gpio_set_value(chip, gpio, value); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) | ||
234 | { | ||
235 | writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR)); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | int jz_gpio_port_direction_input(int port, uint32_t mask) | ||
241 | { | ||
242 | writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR)); | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | EXPORT_SYMBOL(jz_gpio_port_direction_input); | ||
247 | |||
248 | int jz_gpio_port_direction_output(int port, uint32_t mask) | ||
249 | { | ||
250 | writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET)); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | EXPORT_SYMBOL(jz_gpio_port_direction_output); | ||
255 | |||
256 | void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask) | ||
257 | { | ||
258 | writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR)); | ||
259 | writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET)); | ||
260 | } | ||
261 | EXPORT_SYMBOL(jz_gpio_port_set_value); | ||
262 | |||
263 | uint32_t jz_gpio_port_get_value(int port, uint32_t mask) | ||
264 | { | ||
265 | uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN)); | ||
266 | |||
267 | return value & mask; | ||
268 | } | ||
269 | EXPORT_SYMBOL(jz_gpio_port_get_value); | ||
270 | |||
271 | int gpio_to_irq(unsigned gpio) | ||
272 | { | ||
273 | return JZ4740_IRQ_GPIO(0) + gpio; | ||
274 | } | ||
275 | EXPORT_SYMBOL_GPL(gpio_to_irq); | ||
276 | |||
277 | int irq_to_gpio(unsigned irq) | ||
278 | { | ||
279 | return irq - JZ4740_IRQ_GPIO(0); | ||
280 | } | ||
281 | EXPORT_SYMBOL_GPL(irq_to_gpio); | ||
282 | |||
283 | #define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f) | ||
284 | |||
285 | static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq) | ||
286 | { | ||
287 | uint32_t value; | ||
288 | void __iomem *reg; | ||
289 | uint32_t mask = IRQ_TO_BIT(irq); | ||
290 | |||
291 | if (!(chip->edge_trigger_both & mask)) | ||
292 | return; | ||
293 | |||
294 | reg = chip->base; | ||
295 | |||
296 | value = readl(chip->base + JZ_REG_GPIO_PIN); | ||
297 | if (value & mask) | ||
298 | reg += JZ_REG_GPIO_DIRECTION_CLEAR; | ||
299 | else | ||
300 | reg += JZ_REG_GPIO_DIRECTION_SET; | ||
301 | |||
302 | writel(mask, reg); | ||
303 | } | ||
304 | |||
305 | static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc) | ||
306 | { | ||
307 | uint32_t flag; | ||
308 | unsigned int gpio_irq; | ||
309 | unsigned int gpio_bank; | ||
310 | struct jz_gpio_chip *chip = get_irq_desc_data(desc); | ||
311 | |||
312 | gpio_bank = JZ4740_IRQ_GPIO0 - irq; | ||
313 | |||
314 | flag = readl(chip->base + JZ_REG_GPIO_FLAG); | ||
315 | |||
316 | if (!flag) | ||
317 | return; | ||
318 | |||
319 | gpio_irq = __fls(flag); | ||
320 | |||
321 | jz_gpio_check_trigger_both(chip, irq); | ||
322 | |||
323 | gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0); | ||
324 | |||
325 | generic_handle_irq(gpio_irq); | ||
326 | }; | ||
327 | |||
328 | static inline void jz_gpio_set_irq_bit(unsigned int irq, unsigned int reg) | ||
329 | { | ||
330 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | ||
331 | writel(IRQ_TO_BIT(irq), chip->base + reg); | ||
332 | } | ||
333 | |||
334 | static void jz_gpio_irq_mask(unsigned int irq) | ||
335 | { | ||
336 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_SET); | ||
337 | }; | ||
338 | |||
339 | static void jz_gpio_irq_unmask(unsigned int irq) | ||
340 | { | ||
341 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | ||
342 | |||
343 | jz_gpio_check_trigger_both(chip, irq); | ||
344 | |||
345 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_MASK_CLEAR); | ||
346 | }; | ||
347 | |||
348 | /* TODO: Check if function is gpio */ | ||
349 | static unsigned int jz_gpio_irq_startup(unsigned int irq) | ||
350 | { | ||
351 | struct irq_desc *desc = irq_to_desc(irq); | ||
352 | |||
353 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_SET); | ||
354 | |||
355 | desc->status &= ~IRQ_MASKED; | ||
356 | jz_gpio_irq_unmask(irq); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static void jz_gpio_irq_shutdown(unsigned int irq) | ||
362 | { | ||
363 | struct irq_desc *desc = irq_to_desc(irq); | ||
364 | |||
365 | jz_gpio_irq_mask(irq); | ||
366 | desc->status |= IRQ_MASKED; | ||
367 | |||
368 | /* Set direction to input */ | ||
369 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); | ||
370 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_SELECT_CLEAR); | ||
371 | } | ||
372 | |||
373 | static void jz_gpio_irq_ack(unsigned int irq) | ||
374 | { | ||
375 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_FLAG_CLEAR); | ||
376 | }; | ||
377 | |||
378 | static int jz_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) | ||
379 | { | ||
380 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | ||
381 | struct irq_desc *desc = irq_to_desc(irq); | ||
382 | |||
383 | jz_gpio_irq_mask(irq); | ||
384 | |||
385 | if (flow_type == IRQ_TYPE_EDGE_BOTH) { | ||
386 | uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN); | ||
387 | if (value & IRQ_TO_BIT(irq)) | ||
388 | flow_type = IRQ_TYPE_EDGE_FALLING; | ||
389 | else | ||
390 | flow_type = IRQ_TYPE_EDGE_RISING; | ||
391 | chip->edge_trigger_both |= IRQ_TO_BIT(irq); | ||
392 | } else { | ||
393 | chip->edge_trigger_both &= ~IRQ_TO_BIT(irq); | ||
394 | } | ||
395 | |||
396 | switch (flow_type) { | ||
397 | case IRQ_TYPE_EDGE_RISING: | ||
398 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET); | ||
399 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET); | ||
400 | break; | ||
401 | case IRQ_TYPE_EDGE_FALLING: | ||
402 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); | ||
403 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_SET); | ||
404 | break; | ||
405 | case IRQ_TYPE_LEVEL_HIGH: | ||
406 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_SET); | ||
407 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR); | ||
408 | break; | ||
409 | case IRQ_TYPE_LEVEL_LOW: | ||
410 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_DIRECTION_CLEAR); | ||
411 | jz_gpio_set_irq_bit(irq, JZ_REG_GPIO_TRIGGER_CLEAR); | ||
412 | break; | ||
413 | default: | ||
414 | return -EINVAL; | ||
415 | } | ||
416 | |||
417 | if (!(desc->status & IRQ_MASKED)) | ||
418 | jz_gpio_irq_unmask(irq); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int jz_gpio_irq_set_wake(unsigned int irq, unsigned int on) | ||
424 | { | ||
425 | struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(irq); | ||
426 | spin_lock(&chip->lock); | ||
427 | if (on) | ||
428 | chip->wakeup |= IRQ_TO_BIT(irq); | ||
429 | else | ||
430 | chip->wakeup &= ~IRQ_TO_BIT(irq); | ||
431 | spin_unlock(&chip->lock); | ||
432 | |||
433 | set_irq_wake(chip->irq, on); | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * This lock class tells lockdep that GPIO irqs are in a different | ||
439 | * category than their parents, so it won't report false recursion. | ||
440 | */ | ||
441 | static struct lock_class_key gpio_lock_class; | ||
442 | |||
443 | #define JZ4740_GPIO_CHIP(_bank) { \ | ||
444 | .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \ | ||
445 | .gpio_chip = { \ | ||
446 | .label = "Bank " # _bank, \ | ||
447 | .owner = THIS_MODULE, \ | ||
448 | .set = jz_gpio_set_value, \ | ||
449 | .get = jz_gpio_get_value, \ | ||
450 | .direction_output = jz_gpio_direction_output, \ | ||
451 | .direction_input = jz_gpio_direction_input, \ | ||
452 | .base = JZ4740_GPIO_BASE_ ## _bank, \ | ||
453 | .ngpio = JZ4740_GPIO_NUM_ ## _bank, \ | ||
454 | }, \ | ||
455 | .irq_chip = { \ | ||
456 | .name = "GPIO Bank " # _bank, \ | ||
457 | .mask = jz_gpio_irq_mask, \ | ||
458 | .unmask = jz_gpio_irq_unmask, \ | ||
459 | .ack = jz_gpio_irq_ack, \ | ||
460 | .startup = jz_gpio_irq_startup, \ | ||
461 | .shutdown = jz_gpio_irq_shutdown, \ | ||
462 | .set_type = jz_gpio_irq_set_type, \ | ||
463 | .set_wake = jz_gpio_irq_set_wake, \ | ||
464 | }, \ | ||
465 | } | ||
466 | |||
467 | static struct jz_gpio_chip jz4740_gpio_chips[] = { | ||
468 | JZ4740_GPIO_CHIP(A), | ||
469 | JZ4740_GPIO_CHIP(B), | ||
470 | JZ4740_GPIO_CHIP(C), | ||
471 | JZ4740_GPIO_CHIP(D), | ||
472 | }; | ||
473 | |||
474 | static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev) | ||
475 | { | ||
476 | return container_of(dev, struct jz_gpio_chip, sysdev); | ||
477 | } | ||
478 | |||
479 | static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state) | ||
480 | { | ||
481 | struct jz_gpio_chip *chip = sysdev_to_chip(dev); | ||
482 | |||
483 | chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); | ||
484 | writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); | ||
485 | writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | static int jz4740_gpio_resume(struct sys_device *dev) | ||
491 | { | ||
492 | struct jz_gpio_chip *chip = sysdev_to_chip(dev); | ||
493 | uint32_t mask = chip->suspend_mask; | ||
494 | |||
495 | writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); | ||
496 | writel(mask, chip->base + JZ_REG_GPIO_MASK_SET); | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static struct sysdev_class jz4740_gpio_sysdev_class = { | ||
502 | .name = "gpio", | ||
503 | .suspend = jz4740_gpio_suspend, | ||
504 | .resume = jz4740_gpio_resume, | ||
505 | }; | ||
506 | |||
507 | static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) | ||
508 | { | ||
509 | int ret, irq; | ||
510 | |||
511 | chip->sysdev.id = id; | ||
512 | chip->sysdev.cls = &jz4740_gpio_sysdev_class; | ||
513 | ret = sysdev_register(&chip->sysdev); | ||
514 | |||
515 | if (ret) | ||
516 | return ret; | ||
517 | |||
518 | spin_lock_init(&chip->lock); | ||
519 | |||
520 | chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100); | ||
521 | |||
522 | gpiochip_add(&chip->gpio_chip); | ||
523 | |||
524 | chip->irq = JZ4740_IRQ_INTC_GPIO(id); | ||
525 | set_irq_data(chip->irq, chip); | ||
526 | set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler); | ||
527 | |||
528 | for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { | ||
529 | lockdep_set_class(&irq_desc[irq].lock, &gpio_lock_class); | ||
530 | set_irq_chip_data(irq, chip); | ||
531 | set_irq_chip_and_handler(irq, &chip->irq_chip, handle_level_irq); | ||
532 | } | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static int __init jz4740_gpio_init(void) | ||
538 | { | ||
539 | unsigned int i; | ||
540 | int ret; | ||
541 | |||
542 | ret = sysdev_class_register(&jz4740_gpio_sysdev_class); | ||
543 | if (ret) | ||
544 | return ret; | ||
545 | |||
546 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) | ||
547 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); | ||
548 | |||
549 | printk(KERN_INFO "JZ4740 GPIO initalized\n"); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | arch_initcall(jz4740_gpio_init); | ||
554 | |||
555 | #ifdef CONFIG_DEBUG_FS | ||
556 | |||
557 | static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip, | ||
558 | const char *name, unsigned int reg) | ||
559 | { | ||
560 | seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg)); | ||
561 | } | ||
562 | |||
563 | static int gpio_regs_show(struct seq_file *s, void *unused) | ||
564 | { | ||
565 | struct jz_gpio_chip *chip = jz4740_gpio_chips; | ||
566 | int i; | ||
567 | |||
568 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) { | ||
569 | seq_printf(s, "==GPIO %d==\n", i); | ||
570 | gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN); | ||
571 | gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA); | ||
572 | gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK); | ||
573 | gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL); | ||
574 | gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC); | ||
575 | gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT); | ||
576 | gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION); | ||
577 | gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER); | ||
578 | gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG); | ||
579 | } | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | static int gpio_regs_open(struct inode *inode, struct file *file) | ||
585 | { | ||
586 | return single_open(file, gpio_regs_show, NULL); | ||
587 | } | ||
588 | |||
589 | static const struct file_operations gpio_regs_operations = { | ||
590 | .open = gpio_regs_open, | ||
591 | .read = seq_read, | ||
592 | .llseek = seq_lseek, | ||
593 | .release = single_release, | ||
594 | }; | ||
595 | |||
596 | static int __init gpio_debugfs_init(void) | ||
597 | { | ||
598 | (void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO, | ||
599 | NULL, NULL, &gpio_regs_operations); | ||
600 | return 0; | ||
601 | } | ||
602 | subsys_initcall(gpio_debugfs_init); | ||
603 | |||
604 | #endif | ||