]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/at91_gpio.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / drivers / gpio / at91_gpio.c
1 /*
2  * Memory Setup stuff - taken from blob memsetup.S
3  *
4  * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
5  *
6  *  Copyright (C) 2005 HP Labs
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 #include <config.h>
28 #include <common.h>
29 #include <asm/sizes.h>
30 #include <asm/arch/hardware.h>
31 #include <asm/arch/io.h>
32 #include <asm/arch/at91_pio.h>
33
34 int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
35 {
36         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
37         u32             mask;
38
39         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
40                 mask = 1 << pin;
41                 if (use_pullup)
42                         writel(1 << pin, &pio->port[port].puer);
43                 else
44                         writel(1 << pin, &pio->port[port].pudr);
45                 writel(mask, &pio->port[port].per);
46         }
47         return 0;
48 }
49
50 /*
51  * mux the pin to the "GPIO" peripheral role.
52  */
53 int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
54 {
55         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
56         u32             mask;
57
58         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
59                 mask = 1 << pin;
60                 writel(mask, &pio->port[port].idr);
61                 at91_set_pio_pullup(port, pin, use_pullup);
62                 writel(mask, &pio->port[port].per);
63         }
64         return 0;
65 }
66
67 /*
68  * mux the pin to the "A" internal peripheral role.
69  */
70 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
71 {
72         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
73         u32             mask;
74
75         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
76                 mask = 1 << pin;
77                 writel(mask, &pio->port[port].idr);
78                 at91_set_pio_pullup(port, pin, use_pullup);
79                 writel(mask, &pio->port[port].asr);
80                 writel(mask, &pio->port[port].pdr);
81         }
82         return 0;
83 }
84
85 /*
86  * mux the pin to the "B" internal peripheral role.
87  */
88 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
89 {
90         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
91         u32             mask;
92
93         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
94                 mask = 1 << pin;
95                 writel(mask, &pio->port[port].idr);
96                 at91_set_pio_pullup(port, pin, use_pullup);
97                 writel(mask, &pio->port[port].bsr);
98                 writel(mask, &pio->port[port].pdr);
99         }
100         return 0;
101 }
102
103 /*
104  * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
105  * configure it for an input.
106  */
107 int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
108 {
109         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
110         u32             mask;
111
112         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
113                 mask = 1 << pin;
114                 writel(mask, &pio->port[port].idr);
115                 at91_set_pio_pullup(port, pin, use_pullup);
116                 writel(mask, &pio->port[port].odr);
117                 writel(mask, &pio->port[port].per);
118         }
119         return 0;
120 }
121
122 /*
123  * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
124  * and configure it for an output.
125  */
126 int at91_set_pio_output(unsigned port, u32 pin, int value)
127 {
128         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
129         u32             mask;
130
131         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
132                 mask = 1 << pin;
133                 writel(mask, &pio->port[port].idr);
134                 writel(mask, &pio->port[port].pudr);
135                 if (value)
136                         writel(mask, &pio->port[port].sodr);
137                 else
138                         writel(mask, &pio->port[port].codr);
139                 writel(mask, &pio->port[port].oer);
140                 writel(mask, &pio->port[port].per);
141         }
142         return 0;
143 }
144
145 /*
146  * enable/disable the glitch filter. mostly used with IRQ handling.
147  */
148 int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
149 {
150         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
151         u32             mask;
152
153         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
154                 mask = 1 << pin;
155                 if (is_on)
156                         writel(mask, &pio->port[port].ifer);
157                 else
158                         writel(mask, &pio->port[port].ifdr);
159         }
160         return 0;
161 }
162
163 /*
164  * enable/disable the multi-driver. This is only valid for output and
165  * allows the output pin to run as an open collector output.
166  */
167 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
168 {
169         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
170         u32             mask;
171
172         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
173                 mask = 1 << pin;
174                 if (is_on)
175                         writel(mask, &pio->port[port].mder);
176                 else
177                         writel(mask, &pio->port[port].mddr);
178         }
179         return 0;
180 }
181
182 /*
183  * assuming the pin is muxed as a gpio output, set its value.
184  */
185 int at91_set_pio_value(unsigned port, unsigned pin, int value)
186 {
187         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
188         u32             mask;
189
190         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
191                 mask = 1 << pin;
192                 if (value)
193                         writel(mask, &pio->port[port].sodr);
194                 else
195                         writel(mask, &pio->port[port].codr);
196         }
197         return 0;
198 }
199
200 /*
201  * read the pin's value (works even if it's not muxed as a gpio).
202  */
203 int at91_get_pio_value(unsigned port, unsigned pin)
204 {
205         u32             pdsr    = 0;
206         at91_pio_t      *pio    = (at91_pio_t *) AT91_PIO_BASE;
207         u32             mask;
208
209         if ((port < AT91_PIO_PORTS) && (pin < 32)) {
210                 mask = 1 << pin;
211                 pdsr = readl(&pio->port[port].pdsr) & mask;
212         }
213         return pdsr != 0;
214 }