xref: /openbmc/u-boot/drivers/gpio/at91_gpio.c (revision bf1af3d8)
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 }
397