]>
Commit | Line | Data |
---|---|---|
ea8fbba7 | 1 | /* |
39b787ec | 2 | * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com> |
ea8fbba7 JS |
3 | * |
4 | * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de) | |
5 | * | |
6 | * Copyright (C) 2005 HP Labs | |
7 | * | |
1a459660 | 8 | * SPDX-License-Identifier: GPL-2.0+ |
ea8fbba7 JS |
9 | */ |
10 | ||
11 | #include <config.h> | |
12 | #include <common.h> | |
918354b1 | 13 | #include <dm.h> |
86592f60 | 14 | #include <asm/io.h> |
1ace4022 | 15 | #include <linux/sizes.h> |
918354b1 | 16 | #include <asm/gpio.h> |
ea8fbba7 | 17 | #include <asm/arch/hardware.h> |
ea8fbba7 | 18 | #include <asm/arch/at91_pio.h> |
918354b1 SG |
19 | |
20 | #define GPIO_PER_BANK 32 | |
ea8fbba7 | 21 | |
4bc9b7a5 BS |
22 | static struct at91_port *at91_pio_get_port(unsigned port) |
23 | { | |
24 | switch (port) { | |
25 | case AT91_PIO_PORTA: | |
26 | return (struct at91_port *)ATMEL_BASE_PIOA; | |
27 | case AT91_PIO_PORTB: | |
28 | return (struct at91_port *)ATMEL_BASE_PIOB; | |
29 | case AT91_PIO_PORTC: | |
30 | return (struct at91_port *)ATMEL_BASE_PIOC; | |
31 | #if (ATMEL_PIO_PORTS > 3) | |
32 | case AT91_PIO_PORTD: | |
33 | return (struct at91_port *)ATMEL_BASE_PIOD; | |
34 | #if (ATMEL_PIO_PORTS > 4) | |
35 | case AT91_PIO_PORTE: | |
36 | return (struct at91_port *)ATMEL_BASE_PIOE; | |
37 | #endif | |
38 | #endif | |
39 | default: | |
7d82d897 | 40 | printf("Error: at91_gpio: Fail to get PIO base!\n"); |
4bc9b7a5 BS |
41 | return NULL; |
42 | } | |
43 | } | |
44 | ||
918354b1 SG |
45 | static void at91_set_port_pullup(struct at91_port *at91_port, unsigned offset, |
46 | int use_pullup) | |
47 | { | |
48 | u32 mask; | |
49 | ||
50 | mask = 1 << offset; | |
51 | if (use_pullup) | |
52 | writel(mask, &at91_port->puer); | |
53 | else | |
54 | writel(mask, &at91_port->pudr); | |
55 | writel(mask, &at91_port->per); | |
56 | } | |
57 | ||
ea8fbba7 JS |
58 | int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup) |
59 | { | |
4bc9b7a5 | 60 | struct at91_port *at91_port = at91_pio_get_port(port); |
ea8fbba7 | 61 | |
918354b1 SG |
62 | if (at91_port && (pin < GPIO_PER_BANK)) |
63 | at91_set_port_pullup(at91_port, pin, use_pullup); | |
4bc9b7a5 | 64 | |
ea8fbba7 JS |
65 | return 0; |
66 | } | |
67 | ||
68 | /* | |
69 | * mux the pin to the "GPIO" peripheral role. | |
70 | */ | |
71 | int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup) | |
72 | { | |
4bc9b7a5 BS |
73 | struct at91_port *at91_port = at91_pio_get_port(port); |
74 | u32 mask; | |
ea8fbba7 | 75 | |
918354b1 | 76 | if (at91_port && (pin < GPIO_PER_BANK)) { |
ea8fbba7 | 77 | mask = 1 << pin; |
4bc9b7a5 | 78 | writel(mask, &at91_port->idr); |
ea8fbba7 | 79 | at91_set_pio_pullup(port, pin, use_pullup); |
4bc9b7a5 | 80 | writel(mask, &at91_port->per); |
ea8fbba7 | 81 | } |
4bc9b7a5 | 82 | |
ea8fbba7 JS |
83 | return 0; |
84 | } | |
85 | ||
86 | /* | |
87 | * mux the pin to the "A" internal peripheral role. | |
88 | */ | |
89 | int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup) | |
90 | { | |
4bc9b7a5 BS |
91 | struct at91_port *at91_port = at91_pio_get_port(port); |
92 | u32 mask; | |
ea8fbba7 | 93 | |
918354b1 | 94 | if (at91_port && (pin < GPIO_PER_BANK)) { |
ea8fbba7 | 95 | mask = 1 << pin; |
4bc9b7a5 | 96 | writel(mask, &at91_port->idr); |
ea8fbba7 | 97 | at91_set_pio_pullup(port, pin, use_pullup); |
2b3b1c66 | 98 | #if defined(CPU_HAS_PIO3) |
4bc9b7a5 BS |
99 | writel(readl(&at91_port->abcdsr1) & ~mask, |
100 | &at91_port->abcdsr1); | |
101 | writel(readl(&at91_port->abcdsr2) & ~mask, | |
102 | &at91_port->abcdsr2); | |
2b3b1c66 | 103 | #else |
4bc9b7a5 | 104 | writel(mask, &at91_port->asr); |
2b3b1c66 | 105 | #endif |
4bc9b7a5 | 106 | writel(mask, &at91_port->pdr); |
ea8fbba7 | 107 | } |
4bc9b7a5 | 108 | |
ea8fbba7 JS |
109 | return 0; |
110 | } | |
111 | ||
112 | /* | |
113 | * mux the pin to the "B" internal peripheral role. | |
114 | */ | |
115 | int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup) | |
116 | { | |
4bc9b7a5 BS |
117 | struct at91_port *at91_port = at91_pio_get_port(port); |
118 | u32 mask; | |
ea8fbba7 | 119 | |
918354b1 | 120 | if (at91_port && (pin < GPIO_PER_BANK)) { |
ea8fbba7 | 121 | mask = 1 << pin; |
4bc9b7a5 | 122 | writel(mask, &at91_port->idr); |
ea8fbba7 | 123 | at91_set_pio_pullup(port, pin, use_pullup); |
2b3b1c66 | 124 | #if defined(CPU_HAS_PIO3) |
4bc9b7a5 BS |
125 | writel(readl(&at91_port->abcdsr1) | mask, |
126 | &at91_port->abcdsr1); | |
127 | writel(readl(&at91_port->abcdsr2) & ~mask, | |
128 | &at91_port->abcdsr2); | |
2b3b1c66 | 129 | #else |
4bc9b7a5 | 130 | writel(mask, &at91_port->bsr); |
2b3b1c66 | 131 | #endif |
4bc9b7a5 | 132 | writel(mask, &at91_port->pdr); |
ea8fbba7 | 133 | } |
4bc9b7a5 | 134 | |
ea8fbba7 JS |
135 | return 0; |
136 | } | |
137 | ||
2b3b1c66 BS |
138 | #if defined(CPU_HAS_PIO3) |
139 | /* | |
140 | * mux the pin to the "C" internal peripheral role. | |
141 | */ | |
142 | int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup) | |
143 | { | |
4bc9b7a5 BS |
144 | struct at91_port *at91_port = at91_pio_get_port(port); |
145 | u32 mask; | |
2b3b1c66 | 146 | |
918354b1 | 147 | if (at91_port && (pin < GPIO_PER_BANK)) { |
2b3b1c66 | 148 | mask = 1 << pin; |
4bc9b7a5 | 149 | writel(mask, &at91_port->idr); |
2b3b1c66 | 150 | at91_set_pio_pullup(port, pin, use_pullup); |
4bc9b7a5 BS |
151 | writel(readl(&at91_port->abcdsr1) & ~mask, |
152 | &at91_port->abcdsr1); | |
153 | writel(readl(&at91_port->abcdsr2) | mask, | |
154 | &at91_port->abcdsr2); | |
155 | writel(mask, &at91_port->pdr); | |
2b3b1c66 | 156 | } |
4bc9b7a5 | 157 | |
2b3b1c66 BS |
158 | return 0; |
159 | } | |
160 | ||
161 | /* | |
162 | * mux the pin to the "D" internal peripheral role. | |
163 | */ | |
164 | int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup) | |
165 | { | |
4bc9b7a5 BS |
166 | struct at91_port *at91_port = at91_pio_get_port(port); |
167 | u32 mask; | |
2b3b1c66 | 168 | |
918354b1 | 169 | if (at91_port && (pin < GPIO_PER_BANK)) { |
2b3b1c66 | 170 | mask = 1 << pin; |
4bc9b7a5 | 171 | writel(mask, &at91_port->idr); |
2b3b1c66 | 172 | at91_set_pio_pullup(port, pin, use_pullup); |
4bc9b7a5 BS |
173 | writel(readl(&at91_port->abcdsr1) | mask, |
174 | &at91_port->abcdsr1); | |
175 | writel(readl(&at91_port->abcdsr2) | mask, | |
176 | &at91_port->abcdsr2); | |
177 | writel(mask, &at91_port->pdr); | |
2b3b1c66 | 178 | } |
4bc9b7a5 | 179 | |
2b3b1c66 BS |
180 | return 0; |
181 | } | |
182 | #endif | |
183 | ||
918354b1 SG |
184 | #ifdef CONFIG_DM_GPIO |
185 | static bool at91_get_port_output(struct at91_port *at91_port, int offset) | |
186 | { | |
187 | u32 mask, val; | |
188 | ||
189 | mask = 1 << offset; | |
190 | val = readl(&at91_port->osr); | |
191 | return val & mask; | |
192 | } | |
193 | #endif | |
194 | ||
195 | static void at91_set_port_input(struct at91_port *at91_port, int offset, | |
196 | int use_pullup) | |
197 | { | |
198 | u32 mask; | |
199 | ||
200 | mask = 1 << offset; | |
201 | writel(mask, &at91_port->idr); | |
202 | at91_set_port_pullup(at91_port, offset, use_pullup); | |
203 | writel(mask, &at91_port->odr); | |
204 | writel(mask, &at91_port->per); | |
205 | } | |
206 | ||
ea8fbba7 JS |
207 | /* |
208 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and | |
209 | * configure it for an input. | |
210 | */ | |
211 | int at91_set_pio_input(unsigned port, u32 pin, int use_pullup) | |
212 | { | |
4bc9b7a5 | 213 | struct at91_port *at91_port = at91_pio_get_port(port); |
ea8fbba7 | 214 | |
918354b1 SG |
215 | if (at91_port && (pin < GPIO_PER_BANK)) |
216 | at91_set_port_input(at91_port, pin, use_pullup); | |
4bc9b7a5 | 217 | |
ea8fbba7 JS |
218 | return 0; |
219 | } | |
220 | ||
918354b1 SG |
221 | static void at91_set_port_output(struct at91_port *at91_port, int offset, |
222 | int value) | |
223 | { | |
224 | u32 mask; | |
225 | ||
226 | mask = 1 << offset; | |
227 | writel(mask, &at91_port->idr); | |
228 | writel(mask, &at91_port->pudr); | |
229 | if (value) | |
230 | writel(mask, &at91_port->sodr); | |
231 | else | |
232 | writel(mask, &at91_port->codr); | |
233 | writel(mask, &at91_port->oer); | |
234 | writel(mask, &at91_port->per); | |
235 | } | |
236 | ||
ea8fbba7 JS |
237 | /* |
238 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), | |
239 | * and configure it for an output. | |
240 | */ | |
241 | int at91_set_pio_output(unsigned port, u32 pin, int value) | |
242 | { | |
4bc9b7a5 | 243 | struct at91_port *at91_port = at91_pio_get_port(port); |
ea8fbba7 | 244 | |
918354b1 SG |
245 | if (at91_port && (pin < GPIO_PER_BANK)) |
246 | at91_set_port_output(at91_port, pin, value); | |
4bc9b7a5 | 247 | |
ea8fbba7 JS |
248 | return 0; |
249 | } | |
250 | ||
251 | /* | |
252 | * enable/disable the glitch filter. mostly used with IRQ handling. | |
253 | */ | |
254 | int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on) | |
255 | { | |
4bc9b7a5 BS |
256 | struct at91_port *at91_port = at91_pio_get_port(port); |
257 | u32 mask; | |
ea8fbba7 | 258 | |
918354b1 | 259 | if (at91_port && (pin < GPIO_PER_BANK)) { |
ea8fbba7 | 260 | mask = 1 << pin; |
2b3b1c66 BS |
261 | if (is_on) { |
262 | #if defined(CPU_HAS_PIO3) | |
4bc9b7a5 | 263 | writel(mask, &at91_port->ifscdr); |
2b3b1c66 | 264 | #endif |
4bc9b7a5 | 265 | writel(mask, &at91_port->ifer); |
2b3b1c66 | 266 | } else { |
4bc9b7a5 | 267 | writel(mask, &at91_port->ifdr); |
2b3b1c66 BS |
268 | } |
269 | } | |
4bc9b7a5 | 270 | |
2b3b1c66 BS |
271 | return 0; |
272 | } | |
273 | ||
274 | #if defined(CPU_HAS_PIO3) | |
275 | /* | |
276 | * enable/disable the debounce filter. | |
277 | */ | |
278 | int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div) | |
279 | { | |
4bc9b7a5 BS |
280 | struct at91_port *at91_port = at91_pio_get_port(port); |
281 | u32 mask; | |
2b3b1c66 | 282 | |
918354b1 | 283 | if (at91_port && (pin < GPIO_PER_BANK)) { |
2b3b1c66 BS |
284 | mask = 1 << pin; |
285 | if (is_on) { | |
4bc9b7a5 BS |
286 | writel(mask, &at91_port->ifscer); |
287 | writel(div & PIO_SCDR_DIV, &at91_port->scdr); | |
288 | writel(mask, &at91_port->ifer); | |
2b3b1c66 | 289 | } else { |
4bc9b7a5 | 290 | writel(mask, &at91_port->ifdr); |
2b3b1c66 BS |
291 | } |
292 | } | |
4bc9b7a5 | 293 | |
2b3b1c66 BS |
294 | return 0; |
295 | } | |
296 | ||
297 | /* | |
298 | * enable/disable the pull-down. | |
299 | * If pull-up already enabled while calling the function, we disable it. | |
300 | */ | |
301 | int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on) | |
302 | { | |
4bc9b7a5 BS |
303 | struct at91_port *at91_port = at91_pio_get_port(port); |
304 | u32 mask; | |
2b3b1c66 | 305 | |
918354b1 | 306 | if (at91_port && (pin < GPIO_PER_BANK)) { |
2b3b1c66 | 307 | mask = 1 << pin; |
4bc9b7a5 | 308 | writel(mask, &at91_port->pudr); |
2b3b1c66 | 309 | if (is_on) |
4bc9b7a5 | 310 | writel(mask, &at91_port->ppder); |
2b3b1c66 | 311 | else |
4bc9b7a5 | 312 | writel(mask, &at91_port->ppddr); |
2b3b1c66 | 313 | } |
4bc9b7a5 | 314 | |
2b3b1c66 BS |
315 | return 0; |
316 | } | |
317 | ||
318 | /* | |
319 | * disable Schmitt trigger | |
320 | */ | |
321 | int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin) | |
322 | { | |
4bc9b7a5 BS |
323 | struct at91_port *at91_port = at91_pio_get_port(port); |
324 | u32 mask; | |
2b3b1c66 | 325 | |
918354b1 | 326 | if (at91_port && (pin < GPIO_PER_BANK)) { |
2b3b1c66 | 327 | mask = 1 << pin; |
4bc9b7a5 BS |
328 | writel(readl(&at91_port->schmitt) | mask, |
329 | &at91_port->schmitt); | |
ea8fbba7 | 330 | } |
4bc9b7a5 | 331 | |
ea8fbba7 JS |
332 | return 0; |
333 | } | |
2b3b1c66 | 334 | #endif |
ea8fbba7 JS |
335 | |
336 | /* | |
337 | * enable/disable the multi-driver. This is only valid for output and | |
338 | * allows the output pin to run as an open collector output. | |
339 | */ | |
340 | int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on) | |
341 | { | |
4bc9b7a5 BS |
342 | struct at91_port *at91_port = at91_pio_get_port(port); |
343 | u32 mask; | |
ea8fbba7 | 344 | |
918354b1 | 345 | if (at91_port && (pin < GPIO_PER_BANK)) { |
ea8fbba7 JS |
346 | mask = 1 << pin; |
347 | if (is_on) | |
4bc9b7a5 | 348 | writel(mask, &at91_port->mder); |
ea8fbba7 | 349 | else |
4bc9b7a5 | 350 | writel(mask, &at91_port->mddr); |
ea8fbba7 | 351 | } |
4bc9b7a5 | 352 | |
ea8fbba7 JS |
353 | return 0; |
354 | } | |
355 | ||
918354b1 SG |
356 | static void at91_set_port_value(struct at91_port *at91_port, int offset, |
357 | int value) | |
358 | { | |
359 | u32 mask; | |
360 | ||
361 | mask = 1 << offset; | |
362 | if (value) | |
363 | writel(mask, &at91_port->sodr); | |
364 | else | |
365 | writel(mask, &at91_port->codr); | |
366 | } | |
367 | ||
ea8fbba7 JS |
368 | /* |
369 | * assuming the pin is muxed as a gpio output, set its value. | |
370 | */ | |
371 | int at91_set_pio_value(unsigned port, unsigned pin, int value) | |
372 | { | |
4bc9b7a5 | 373 | struct at91_port *at91_port = at91_pio_get_port(port); |
ea8fbba7 | 374 | |
918354b1 SG |
375 | if (at91_port && (pin < GPIO_PER_BANK)) |
376 | at91_set_port_value(at91_port, pin, value); | |
4bc9b7a5 | 377 | |
ea8fbba7 JS |
378 | return 0; |
379 | } | |
380 | ||
918354b1 SG |
381 | static int at91_get_port_value(struct at91_port *at91_port, int offset) |
382 | { | |
383 | u32 pdsr = 0, mask; | |
384 | ||
385 | mask = 1 << offset; | |
386 | pdsr = readl(&at91_port->pdsr) & mask; | |
387 | ||
388 | return pdsr != 0; | |
389 | } | |
ea8fbba7 JS |
390 | /* |
391 | * read the pin's value (works even if it's not muxed as a gpio). | |
392 | */ | |
393 | int at91_get_pio_value(unsigned port, unsigned pin) | |
394 | { | |
4bc9b7a5 | 395 | struct at91_port *at91_port = at91_pio_get_port(port); |
ea8fbba7 | 396 | |
918354b1 SG |
397 | if (at91_port && (pin < GPIO_PER_BANK)) |
398 | return at91_get_port_value(at91_port, pin); | |
4bc9b7a5 | 399 | |
918354b1 | 400 | return 0; |
ea8fbba7 | 401 | } |
6edaea87 | 402 | |
918354b1 | 403 | #ifndef CONFIG_DM_GPIO |
6edaea87 BS |
404 | /* Common GPIO API */ |
405 | ||
6edaea87 BS |
406 | int gpio_request(unsigned gpio, const char *label) |
407 | { | |
408 | return 0; | |
409 | } | |
410 | ||
411 | int gpio_free(unsigned gpio) | |
412 | { | |
413 | return 0; | |
414 | } | |
415 | ||
416 | int gpio_direction_input(unsigned gpio) | |
417 | { | |
418 | at91_set_pio_input(at91_gpio_to_port(gpio), | |
419 | at91_gpio_to_pin(gpio), 0); | |
420 | return 0; | |
421 | } | |
422 | ||
423 | int gpio_direction_output(unsigned gpio, int value) | |
424 | { | |
425 | at91_set_pio_output(at91_gpio_to_port(gpio), | |
426 | at91_gpio_to_pin(gpio), value); | |
427 | return 0; | |
428 | } | |
429 | ||
430 | int gpio_get_value(unsigned gpio) | |
431 | { | |
432 | return at91_get_pio_value(at91_gpio_to_port(gpio), | |
433 | at91_gpio_to_pin(gpio)); | |
434 | } | |
435 | ||
436 | int gpio_set_value(unsigned gpio, int value) | |
437 | { | |
438 | at91_set_pio_value(at91_gpio_to_port(gpio), | |
439 | at91_gpio_to_pin(gpio), value); | |
440 | ||
441 | return 0; | |
442 | } | |
918354b1 SG |
443 | #endif |
444 | ||
445 | #ifdef CONFIG_DM_GPIO | |
446 | ||
447 | struct at91_port_priv { | |
448 | struct at91_port *regs; | |
449 | }; | |
450 | ||
451 | /* set GPIO pin 'gpio' as an input */ | |
452 | static int at91_gpio_direction_input(struct udevice *dev, unsigned offset) | |
453 | { | |
d895821f | 454 | struct at91_port_priv *port = dev_get_priv(dev); |
918354b1 SG |
455 | |
456 | at91_set_port_input(port->regs, offset, 0); | |
457 | ||
458 | return 0; | |
459 | } | |
460 | ||
461 | /* set GPIO pin 'gpio' as an output, with polarity 'value' */ | |
462 | static int at91_gpio_direction_output(struct udevice *dev, unsigned offset, | |
463 | int value) | |
464 | { | |
d895821f | 465 | struct at91_port_priv *port = dev_get_priv(dev); |
918354b1 SG |
466 | |
467 | at91_set_port_output(port->regs, offset, value); | |
468 | ||
469 | return 0; | |
470 | } | |
471 | ||
472 | /* read GPIO IN value of pin 'gpio' */ | |
473 | static int at91_gpio_get_value(struct udevice *dev, unsigned offset) | |
474 | { | |
d895821f | 475 | struct at91_port_priv *port = dev_get_priv(dev); |
918354b1 SG |
476 | |
477 | return at91_get_port_value(port->regs, offset); | |
478 | } | |
479 | ||
480 | /* write GPIO OUT value to pin 'gpio' */ | |
481 | static int at91_gpio_set_value(struct udevice *dev, unsigned offset, | |
482 | int value) | |
483 | { | |
d895821f | 484 | struct at91_port_priv *port = dev_get_priv(dev); |
918354b1 SG |
485 | |
486 | at91_set_port_value(port->regs, offset, value); | |
487 | ||
488 | return 0; | |
489 | } | |
490 | ||
491 | static int at91_gpio_get_function(struct udevice *dev, unsigned offset) | |
492 | { | |
d895821f | 493 | struct at91_port_priv *port = dev_get_priv(dev); |
918354b1 SG |
494 | |
495 | /* GPIOF_FUNC is not implemented yet */ | |
496 | if (at91_get_port_output(port->regs, offset)) | |
497 | return GPIOF_OUTPUT; | |
498 | else | |
499 | return GPIOF_INPUT; | |
500 | } | |
501 | ||
502 | static const struct dm_gpio_ops gpio_at91_ops = { | |
503 | .direction_input = at91_gpio_direction_input, | |
504 | .direction_output = at91_gpio_direction_output, | |
505 | .get_value = at91_gpio_get_value, | |
506 | .set_value = at91_gpio_set_value, | |
507 | .get_function = at91_gpio_get_function, | |
508 | }; | |
509 | ||
510 | static int at91_gpio_probe(struct udevice *dev) | |
511 | { | |
512 | struct at91_port_priv *port = dev_get_priv(dev); | |
513 | struct at91_port_platdata *plat = dev_get_platdata(dev); | |
e564f054 | 514 | struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); |
918354b1 SG |
515 | |
516 | uc_priv->bank_name = plat->bank_name; | |
517 | uc_priv->gpio_count = GPIO_PER_BANK; | |
518 | port->regs = (struct at91_port *)plat->base_addr; | |
519 | ||
520 | return 0; | |
521 | } | |
522 | ||
523 | U_BOOT_DRIVER(gpio_at91) = { | |
524 | .name = "gpio_at91", | |
525 | .id = UCLASS_GPIO, | |
526 | .ops = &gpio_at91_ops, | |
527 | .probe = at91_gpio_probe, | |
528 | .priv_auto_alloc_size = sizeof(struct at91_port_priv), | |
529 | }; | |
530 | #endif |