blob: c0a97bc5dad7722fd4fb4e36e8a7d1108f3e7966 [file] [log] [blame]
Jens Scharsig8d065462010-02-03 22:46:16 +01001/*
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
34int 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 */
53int 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 */
70int 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 */
88int 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 */
107int 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 */
126int 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 */
148int 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 */
167int 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 */
185int 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 */
203int 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}