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