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