]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/at91_gpio.c
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / gpio / at91_gpio.c
1 /*
2  * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
3  *
4  * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
5  *
6  *  Copyright (C) 2005 HP Labs
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <config.h>
12 #include <common.h>
13 #include <asm/io.h>
14 #include <linux/sizes.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/arch/at91_pio.h>
17 #include <asm/arch/gpio.h>
18
19 static struct at91_port *at91_pio_get_port(unsigned port)
20 {
21         switch (port) {
22         case AT91_PIO_PORTA:
23                 return (struct at91_port *)ATMEL_BASE_PIOA;
24         case AT91_PIO_PORTB:
25                 return (struct at91_port *)ATMEL_BASE_PIOB;
26         case AT91_PIO_PORTC:
27                 return (struct at91_port *)ATMEL_BASE_PIOC;
28 #if (ATMEL_PIO_PORTS > 3)
29         case AT91_PIO_PORTD:
30                 return (struct at91_port *)ATMEL_BASE_PIOD;
31 #if (ATMEL_PIO_PORTS > 4)
32         case AT91_PIO_PORTE:
33                 return (struct at91_port *)ATMEL_BASE_PIOE;
34 #endif
35 #endif
36         default:
37                 printf("Error: at91_gpio: Fail to get PIO base!\n");
38                 return NULL;
39         }
40 }
41
42 int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
43 {
44         struct at91_port *at91_port = at91_pio_get_port(port);
45         u32 mask;
46
47         if (at91_port && (pin < 32)) {
48                 mask = 1 << pin;
49                 if (use_pullup)
50                         writel(1 << pin, &at91_port->puer);
51                 else
52                         writel(1 << pin, &at91_port->pudr);
53                 writel(mask, &at91_port->per);
54         }
55
56         return 0;
57 }
58
59 /*
60  * mux the pin to the "GPIO" peripheral role.
61  */
62 int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
63 {
64         struct at91_port *at91_port = at91_pio_get_port(port);
65         u32 mask;
66
67         if (at91_port && (pin < 32)) {
68                 mask = 1 << pin;
69                 writel(mask, &at91_port->idr);
70                 at91_set_pio_pullup(port, pin, use_pullup);
71                 writel(mask, &at91_port->per);
72         }
73
74         return 0;
75 }
76
77 /*
78  * mux the pin to the "A" internal peripheral role.
79  */
80 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
81 {
82         struct at91_port *at91_port = at91_pio_get_port(port);
83         u32 mask;
84
85         if (at91_port && (pin < 32)) {
86                 mask = 1 << pin;
87                 writel(mask, &at91_port->idr);
88                 at91_set_pio_pullup(port, pin, use_pullup);
89 #if defined(CPU_HAS_PIO3)
90                 writel(readl(&at91_port->abcdsr1) & ~mask,
91                        &at91_port->abcdsr1);
92                 writel(readl(&at91_port->abcdsr2) & ~mask,
93                        &at91_port->abcdsr2);
94 #else
95                 writel(mask, &at91_port->asr);
96 #endif
97                 writel(mask, &at91_port->pdr);
98         }
99
100         return 0;
101 }
102
103 /*
104  * mux the pin to the "B" internal peripheral role.
105  */
106 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
107 {
108         struct at91_port *at91_port = at91_pio_get_port(port);
109         u32 mask;
110
111         if (at91_port && (pin < 32)) {
112                 mask = 1 << pin;
113                 writel(mask, &at91_port->idr);
114                 at91_set_pio_pullup(port, pin, use_pullup);
115 #if defined(CPU_HAS_PIO3)
116                 writel(readl(&at91_port->abcdsr1) | mask,
117                        &at91_port->abcdsr1);
118                 writel(readl(&at91_port->abcdsr2) & ~mask,
119                        &at91_port->abcdsr2);
120 #else
121                 writel(mask, &at91_port->bsr);
122 #endif
123                 writel(mask, &at91_port->pdr);
124         }
125
126         return 0;
127 }
128
129 #if defined(CPU_HAS_PIO3)
130 /*
131  * mux the pin to the "C" internal peripheral role.
132  */
133 int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
134 {
135         struct at91_port *at91_port = at91_pio_get_port(port);
136         u32 mask;
137
138         if (at91_port && (pin < 32)) {
139                 mask = 1 << pin;
140                 writel(mask, &at91_port->idr);
141                 at91_set_pio_pullup(port, pin, use_pullup);
142                 writel(readl(&at91_port->abcdsr1) & ~mask,
143                        &at91_port->abcdsr1);
144                 writel(readl(&at91_port->abcdsr2) | mask,
145                        &at91_port->abcdsr2);
146                 writel(mask, &at91_port->pdr);
147         }
148
149         return 0;
150 }
151
152 /*
153  * mux the pin to the "D" internal peripheral role.
154  */
155 int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
156 {
157         struct at91_port *at91_port = at91_pio_get_port(port);
158         u32 mask;
159
160         if (at91_port && (pin < 32)) {
161                 mask = 1 << pin;
162                 writel(mask, &at91_port->idr);
163                 at91_set_pio_pullup(port, pin, use_pullup);
164                 writel(readl(&at91_port->abcdsr1) | mask,
165                        &at91_port->abcdsr1);
166                 writel(readl(&at91_port->abcdsr2) | mask,
167                        &at91_port->abcdsr2);
168                 writel(mask, &at91_port->pdr);
169         }
170
171         return 0;
172 }
173 #endif
174
175 /*
176  * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
177  * configure it for an input.
178  */
179 int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
180 {
181         struct at91_port *at91_port = at91_pio_get_port(port);
182         u32 mask;
183
184         if (at91_port && (pin < 32)) {
185                 mask = 1 << pin;
186                 writel(mask, &at91_port->idr);
187                 at91_set_pio_pullup(port, pin, use_pullup);
188                 writel(mask, &at91_port->odr);
189                 writel(mask, &at91_port->per);
190         }
191
192         return 0;
193 }
194
195 /*
196  * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
197  * and configure it for an output.
198  */
199 int at91_set_pio_output(unsigned port, u32 pin, int value)
200 {
201         struct at91_port *at91_port = at91_pio_get_port(port);
202         u32 mask;
203
204         if (at91_port && (port < ATMEL_PIO_PORTS) && (pin < 32)) {
205                 mask = 1 << pin;
206                 writel(mask, &at91_port->idr);
207                 writel(mask, &at91_port->pudr);
208                 if (value)
209                         writel(mask, &at91_port->sodr);
210                 else
211                         writel(mask, &at91_port->codr);
212                 writel(mask, &at91_port->oer);
213                 writel(mask, &at91_port->per);
214         }
215
216         return 0;
217 }
218
219 /*
220  * enable/disable the glitch filter. mostly used with IRQ handling.
221  */
222 int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
223 {
224         struct at91_port *at91_port = at91_pio_get_port(port);
225         u32 mask;
226
227         if (at91_port && (pin < 32)) {
228                 mask = 1 << pin;
229                 if (is_on) {
230 #if defined(CPU_HAS_PIO3)
231                         writel(mask, &at91_port->ifscdr);
232 #endif
233                         writel(mask, &at91_port->ifer);
234                 } else {
235                         writel(mask, &at91_port->ifdr);
236                 }
237         }
238
239         return 0;
240 }
241
242 #if defined(CPU_HAS_PIO3)
243 /*
244  * enable/disable the debounce filter.
245  */
246 int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
247 {
248         struct at91_port *at91_port = at91_pio_get_port(port);
249         u32 mask;
250
251         if (at91_port && (pin < 32)) {
252                 mask = 1 << pin;
253                 if (is_on) {
254                         writel(mask, &at91_port->ifscer);
255                         writel(div & PIO_SCDR_DIV, &at91_port->scdr);
256                         writel(mask, &at91_port->ifer);
257                 } else {
258                         writel(mask, &at91_port->ifdr);
259                 }
260         }
261
262         return 0;
263 }
264
265 /*
266  * enable/disable the pull-down.
267  * If pull-up already enabled while calling the function, we disable it.
268  */
269 int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
270 {
271         struct at91_port *at91_port = at91_pio_get_port(port);
272         u32 mask;
273
274         if (at91_port && (pin < 32)) {
275                 mask = 1 << pin;
276                 writel(mask, &at91_port->pudr);
277                 if (is_on)
278                         writel(mask, &at91_port->ppder);
279                 else
280                         writel(mask, &at91_port->ppddr);
281         }
282
283         return 0;
284 }
285
286 /*
287  * disable Schmitt trigger
288  */
289 int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
290 {
291         struct at91_port *at91_port = at91_pio_get_port(port);
292         u32 mask;
293
294         if (at91_port && (pin < 32)) {
295                 mask = 1 << pin;
296                 writel(readl(&at91_port->schmitt) | mask,
297                        &at91_port->schmitt);
298         }
299
300         return 0;
301 }
302 #endif
303
304 /*
305  * enable/disable the multi-driver. This is only valid for output and
306  * allows the output pin to run as an open collector output.
307  */
308 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
309 {
310         struct at91_port *at91_port = at91_pio_get_port(port);
311         u32 mask;
312
313         if (at91_port && (pin < 32)) {
314                 mask = 1 << pin;
315                 if (is_on)
316                         writel(mask, &at91_port->mder);
317                 else
318                         writel(mask, &at91_port->mddr);
319         }
320
321         return 0;
322 }
323
324 /*
325  * assuming the pin is muxed as a gpio output, set its value.
326  */
327 int at91_set_pio_value(unsigned port, unsigned pin, int value)
328 {
329         struct at91_port *at91_port = at91_pio_get_port(port);
330         u32 mask;
331
332         if (at91_port && (pin < 32)) {
333                 mask = 1 << pin;
334                 if (value)
335                         writel(mask, &at91_port->sodr);
336                 else
337                         writel(mask, &at91_port->codr);
338         }
339
340         return 0;
341 }
342
343 /*
344  * read the pin's value (works even if it's not muxed as a gpio).
345  */
346 int at91_get_pio_value(unsigned port, unsigned pin)
347 {
348         struct at91_port *at91_port = at91_pio_get_port(port);
349         u32 pdsr = 0, mask;
350
351         if (at91_port && (pin < 32)) {
352                 mask = 1 << pin;
353                 pdsr = readl(&at91_port->pdsr) & mask;
354         }
355
356         return pdsr != 0;
357 }
358
359 /* Common GPIO API */
360
361 int gpio_request(unsigned gpio, const char *label)
362 {
363         return 0;
364 }
365
366 int gpio_free(unsigned gpio)
367 {
368         return 0;
369 }
370
371 int gpio_direction_input(unsigned gpio)
372 {
373         at91_set_pio_input(at91_gpio_to_port(gpio),
374                            at91_gpio_to_pin(gpio), 0);
375         return 0;
376 }
377
378 int gpio_direction_output(unsigned gpio, int value)
379 {
380         at91_set_pio_output(at91_gpio_to_port(gpio),
381                             at91_gpio_to_pin(gpio), value);
382         return 0;
383 }
384
385 int gpio_get_value(unsigned gpio)
386 {
387         return at91_get_pio_value(at91_gpio_to_port(gpio),
388                                   at91_gpio_to_pin(gpio));
389 }
390
391 int gpio_set_value(unsigned gpio, int value)
392 {
393         at91_set_pio_value(at91_gpio_to_port(gpio),
394                            at91_gpio_to_pin(gpio), value);
395
396         return 0;
397 }