blob: 22fbd630987f96d9cd214e8833522c762f9eb16c [file] [log] [blame]
Jens Scharsigea8fbba2010-02-03 22:46:16 +01001/*
Bo Shen39b787e2013-08-13 14:38:32 +08002 * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
Jens Scharsigea8fbba2010-02-03 22:46:16 +01003 *
4 * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
5 *
6 * Copyright (C) 2005 HP Labs
7 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Jens Scharsigea8fbba2010-02-03 22:46:16 +01009 */
10
11#include <config.h>
12#include <common.h>
Simon Glass918354b2014-10-29 13:08:57 -060013#include <dm.h>
Reinhard Meyer86592f62010-11-07 13:26:14 +010014#include <asm/io.h>
Alexey Brodkin1ace4022014-02-26 17:47:58 +040015#include <linux/sizes.h>
Simon Glass918354b2014-10-29 13:08:57 -060016#include <asm/gpio.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010017#include <asm/arch/hardware.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010018#include <asm/arch/at91_pio.h>
Simon Glass918354b2014-10-29 13:08:57 -060019
20#define GPIO_PER_BANK 32
Jens Scharsigea8fbba2010-02-03 22:46:16 +010021
Bo Shen4bc9b7a2013-08-22 15:24:40 +080022static struct at91_port *at91_pio_get_port(unsigned port)
23{
24 switch (port) {
25 case AT91_PIO_PORTA:
26 return (struct at91_port *)ATMEL_BASE_PIOA;
27 case AT91_PIO_PORTB:
28 return (struct at91_port *)ATMEL_BASE_PIOB;
29 case AT91_PIO_PORTC:
30 return (struct at91_port *)ATMEL_BASE_PIOC;
31#if (ATMEL_PIO_PORTS > 3)
32 case AT91_PIO_PORTD:
33 return (struct at91_port *)ATMEL_BASE_PIOD;
34#if (ATMEL_PIO_PORTS > 4)
35 case AT91_PIO_PORTE:
36 return (struct at91_port *)ATMEL_BASE_PIOE;
37#endif
38#endif
39 default:
Wu, Josh7d82d892014-05-07 16:50:45 +080040 printf("Error: at91_gpio: Fail to get PIO base!\n");
Bo Shen4bc9b7a2013-08-22 15:24:40 +080041 return NULL;
42 }
43}
44
Simon Glass918354b2014-10-29 13:08:57 -060045static void at91_set_port_pullup(struct at91_port *at91_port, unsigned offset,
46 int use_pullup)
47{
48 u32 mask;
49
50 mask = 1 << offset;
51 if (use_pullup)
52 writel(mask, &at91_port->puer);
53 else
54 writel(mask, &at91_port->pudr);
55 writel(mask, &at91_port->per);
56}
57
Jens Scharsigea8fbba2010-02-03 22:46:16 +010058int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
59{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080060 struct at91_port *at91_port = at91_pio_get_port(port);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010061
Simon Glass918354b2014-10-29 13:08:57 -060062 if (at91_port && (pin < GPIO_PER_BANK))
63 at91_set_port_pullup(at91_port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +080064
Jens Scharsigea8fbba2010-02-03 22:46:16 +010065 return 0;
66}
67
68/*
69 * mux the pin to the "GPIO" peripheral role.
70 */
71int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
72{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080073 struct at91_port *at91_port = at91_pio_get_port(port);
74 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010075
Simon Glass918354b2014-10-29 13:08:57 -060076 if (at91_port && (pin < GPIO_PER_BANK)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010077 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080078 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010079 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +080080 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010081 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080082
Jens Scharsigea8fbba2010-02-03 22:46:16 +010083 return 0;
84}
85
86/*
87 * mux the pin to the "A" internal peripheral role.
88 */
89int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
90{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080091 struct at91_port *at91_port = at91_pio_get_port(port);
92 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010093
Simon Glass918354b2014-10-29 13:08:57 -060094 if (at91_port && (pin < GPIO_PER_BANK)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010095 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080096 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010097 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +000098#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080099 writel(readl(&at91_port->abcdsr1) & ~mask,
100 &at91_port->abcdsr1);
101 writel(readl(&at91_port->abcdsr2) & ~mask,
102 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000103#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800104 writel(mask, &at91_port->asr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000105#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800106 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100107 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800108
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100109 return 0;
110}
111
112/*
113 * mux the pin to the "B" internal peripheral role.
114 */
115int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
116{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800117 struct at91_port *at91_port = at91_pio_get_port(port);
118 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100119
Simon Glass918354b2014-10-29 13:08:57 -0600120 if (at91_port && (pin < GPIO_PER_BANK)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100121 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800122 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100123 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000124#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800125 writel(readl(&at91_port->abcdsr1) | mask,
126 &at91_port->abcdsr1);
127 writel(readl(&at91_port->abcdsr2) & ~mask,
128 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000129#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800130 writel(mask, &at91_port->bsr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000131#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800132 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100133 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800134
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100135 return 0;
136}
137
Bo Shen2b3b1c62012-05-20 15:50:00 +0000138#if defined(CPU_HAS_PIO3)
139/*
140 * mux the pin to the "C" internal peripheral role.
141 */
142int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
143{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800144 struct at91_port *at91_port = at91_pio_get_port(port);
145 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000146
Simon Glass918354b2014-10-29 13:08:57 -0600147 if (at91_port && (pin < GPIO_PER_BANK)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000148 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800149 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000150 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800151 writel(readl(&at91_port->abcdsr1) & ~mask,
152 &at91_port->abcdsr1);
153 writel(readl(&at91_port->abcdsr2) | mask,
154 &at91_port->abcdsr2);
155 writel(mask, &at91_port->pdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000156 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800157
Bo Shen2b3b1c62012-05-20 15:50:00 +0000158 return 0;
159}
160
161/*
162 * mux the pin to the "D" internal peripheral role.
163 */
164int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
165{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800166 struct at91_port *at91_port = at91_pio_get_port(port);
167 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000168
Simon Glass918354b2014-10-29 13:08:57 -0600169 if (at91_port && (pin < GPIO_PER_BANK)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000170 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800171 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000172 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800173 writel(readl(&at91_port->abcdsr1) | mask,
174 &at91_port->abcdsr1);
175 writel(readl(&at91_port->abcdsr2) | mask,
176 &at91_port->abcdsr2);
177 writel(mask, &at91_port->pdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000178 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800179
Bo Shen2b3b1c62012-05-20 15:50:00 +0000180 return 0;
181}
182#endif
183
Simon Glass918354b2014-10-29 13:08:57 -0600184#ifdef CONFIG_DM_GPIO
185static bool at91_get_port_output(struct at91_port *at91_port, int offset)
186{
187 u32 mask, val;
188
189 mask = 1 << offset;
190 val = readl(&at91_port->osr);
191 return val & mask;
192}
193#endif
194
195static void at91_set_port_input(struct at91_port *at91_port, int offset,
196 int use_pullup)
197{
198 u32 mask;
199
200 mask = 1 << offset;
201 writel(mask, &at91_port->idr);
202 at91_set_port_pullup(at91_port, offset, use_pullup);
203 writel(mask, &at91_port->odr);
204 writel(mask, &at91_port->per);
205}
206
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100207/*
208 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
209 * configure it for an input.
210 */
211int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
212{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800213 struct at91_port *at91_port = at91_pio_get_port(port);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100214
Simon Glass918354b2014-10-29 13:08:57 -0600215 if (at91_port && (pin < GPIO_PER_BANK))
216 at91_set_port_input(at91_port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800217
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100218 return 0;
219}
220
Simon Glass918354b2014-10-29 13:08:57 -0600221static void at91_set_port_output(struct at91_port *at91_port, int offset,
222 int value)
223{
224 u32 mask;
225
226 mask = 1 << offset;
227 writel(mask, &at91_port->idr);
228 writel(mask, &at91_port->pudr);
229 if (value)
230 writel(mask, &at91_port->sodr);
231 else
232 writel(mask, &at91_port->codr);
233 writel(mask, &at91_port->oer);
234 writel(mask, &at91_port->per);
235}
236
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100237/*
238 * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
239 * and configure it for an output.
240 */
241int at91_set_pio_output(unsigned port, u32 pin, int value)
242{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800243 struct at91_port *at91_port = at91_pio_get_port(port);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100244
Simon Glass918354b2014-10-29 13:08:57 -0600245 if (at91_port && (pin < GPIO_PER_BANK))
246 at91_set_port_output(at91_port, pin, value);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800247
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100248 return 0;
249}
250
251/*
252 * enable/disable the glitch filter. mostly used with IRQ handling.
253 */
254int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
255{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800256 struct at91_port *at91_port = at91_pio_get_port(port);
257 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100258
Simon Glass918354b2014-10-29 13:08:57 -0600259 if (at91_port && (pin < GPIO_PER_BANK)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100260 mask = 1 << pin;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000261 if (is_on) {
262#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800263 writel(mask, &at91_port->ifscdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000264#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800265 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000266 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800267 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000268 }
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100269 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800270
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100271 return 0;
272}
273
Bo Shen2b3b1c62012-05-20 15:50:00 +0000274#if defined(CPU_HAS_PIO3)
275/*
276 * enable/disable the debounce filter.
277 */
278int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
279{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800280 struct at91_port *at91_port = at91_pio_get_port(port);
281 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000282
Simon Glass918354b2014-10-29 13:08:57 -0600283 if (at91_port && (pin < GPIO_PER_BANK)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000284 mask = 1 << pin;
285 if (is_on) {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800286 writel(mask, &at91_port->ifscer);
287 writel(div & PIO_SCDR_DIV, &at91_port->scdr);
288 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000289 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800290 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000291 }
292 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800293
Bo Shen2b3b1c62012-05-20 15:50:00 +0000294 return 0;
295}
296
297/*
298 * enable/disable the pull-down.
299 * If pull-up already enabled while calling the function, we disable it.
300 */
301int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
302{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800303 struct at91_port *at91_port = at91_pio_get_port(port);
304 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000305
Simon Glass918354b2014-10-29 13:08:57 -0600306 if (at91_port && (pin < GPIO_PER_BANK)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000307 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800308 writel(mask, &at91_port->pudr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000309 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800310 writel(mask, &at91_port->ppder);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000311 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800312 writel(mask, &at91_port->ppddr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000313 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800314
Bo Shen2b3b1c62012-05-20 15:50:00 +0000315 return 0;
316}
317
318/*
319 * disable Schmitt trigger
320 */
321int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
322{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800323 struct at91_port *at91_port = at91_pio_get_port(port);
324 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000325
Simon Glass918354b2014-10-29 13:08:57 -0600326 if (at91_port && (pin < GPIO_PER_BANK)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000327 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800328 writel(readl(&at91_port->schmitt) | mask,
329 &at91_port->schmitt);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000330 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800331
Bo Shen2b3b1c62012-05-20 15:50:00 +0000332 return 0;
333}
334#endif
335
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100336/*
337 * enable/disable the multi-driver. This is only valid for output and
338 * allows the output pin to run as an open collector output.
339 */
340int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
341{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800342 struct at91_port *at91_port = at91_pio_get_port(port);
343 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100344
Simon Glass918354b2014-10-29 13:08:57 -0600345 if (at91_port && (pin < GPIO_PER_BANK)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100346 mask = 1 << pin;
347 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800348 writel(mask, &at91_port->mder);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100349 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800350 writel(mask, &at91_port->mddr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100351 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800352
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100353 return 0;
354}
355
Simon Glass918354b2014-10-29 13:08:57 -0600356static void at91_set_port_value(struct at91_port *at91_port, int offset,
357 int value)
358{
359 u32 mask;
360
361 mask = 1 << offset;
362 if (value)
363 writel(mask, &at91_port->sodr);
364 else
365 writel(mask, &at91_port->codr);
366}
367
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100368/*
369 * assuming the pin is muxed as a gpio output, set its value.
370 */
371int at91_set_pio_value(unsigned port, unsigned pin, int value)
372{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800373 struct at91_port *at91_port = at91_pio_get_port(port);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100374
Simon Glass918354b2014-10-29 13:08:57 -0600375 if (at91_port && (pin < GPIO_PER_BANK))
376 at91_set_port_value(at91_port, pin, value);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800377
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100378 return 0;
379}
380
Simon Glass918354b2014-10-29 13:08:57 -0600381static int at91_get_port_value(struct at91_port *at91_port, int offset)
382{
383 u32 pdsr = 0, mask;
384
385 mask = 1 << offset;
386 pdsr = readl(&at91_port->pdsr) & mask;
387
388 return pdsr != 0;
389}
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100390/*
391 * read the pin's value (works even if it's not muxed as a gpio).
392 */
393int at91_get_pio_value(unsigned port, unsigned pin)
394{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800395 struct at91_port *at91_port = at91_pio_get_port(port);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100396
Simon Glass918354b2014-10-29 13:08:57 -0600397 if (at91_port && (pin < GPIO_PER_BANK))
398 return at91_get_port_value(at91_port, pin);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800399
Simon Glass918354b2014-10-29 13:08:57 -0600400 return 0;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100401}
Bo Shen6edaea82013-08-13 14:38:31 +0800402
Simon Glass918354b2014-10-29 13:08:57 -0600403#ifndef CONFIG_DM_GPIO
Bo Shen6edaea82013-08-13 14:38:31 +0800404/* Common GPIO API */
405
Bo Shen6edaea82013-08-13 14:38:31 +0800406int gpio_request(unsigned gpio, const char *label)
407{
408 return 0;
409}
410
411int gpio_free(unsigned gpio)
412{
413 return 0;
414}
415
416int gpio_direction_input(unsigned gpio)
417{
418 at91_set_pio_input(at91_gpio_to_port(gpio),
419 at91_gpio_to_pin(gpio), 0);
420 return 0;
421}
422
423int gpio_direction_output(unsigned gpio, int value)
424{
425 at91_set_pio_output(at91_gpio_to_port(gpio),
426 at91_gpio_to_pin(gpio), value);
427 return 0;
428}
429
430int gpio_get_value(unsigned gpio)
431{
432 return at91_get_pio_value(at91_gpio_to_port(gpio),
433 at91_gpio_to_pin(gpio));
434}
435
436int gpio_set_value(unsigned gpio, int value)
437{
438 at91_set_pio_value(at91_gpio_to_port(gpio),
439 at91_gpio_to_pin(gpio), value);
440
441 return 0;
442}
Simon Glass918354b2014-10-29 13:08:57 -0600443#endif
444
445#ifdef CONFIG_DM_GPIO
446
447struct at91_port_priv {
448 struct at91_port *regs;
449};
450
451/* set GPIO pin 'gpio' as an input */
452static int at91_gpio_direction_input(struct udevice *dev, unsigned offset)
453{
Axel Lind8958212015-01-31 14:47:34 +0800454 struct at91_port_priv *port = dev_get_priv(dev);
Simon Glass918354b2014-10-29 13:08:57 -0600455
456 at91_set_port_input(port->regs, offset, 0);
457
458 return 0;
459}
460
461/* set GPIO pin 'gpio' as an output, with polarity 'value' */
462static int at91_gpio_direction_output(struct udevice *dev, unsigned offset,
463 int value)
464{
Axel Lind8958212015-01-31 14:47:34 +0800465 struct at91_port_priv *port = dev_get_priv(dev);
Simon Glass918354b2014-10-29 13:08:57 -0600466
467 at91_set_port_output(port->regs, offset, value);
468
469 return 0;
470}
471
472/* read GPIO IN value of pin 'gpio' */
473static int at91_gpio_get_value(struct udevice *dev, unsigned offset)
474{
Axel Lind8958212015-01-31 14:47:34 +0800475 struct at91_port_priv *port = dev_get_priv(dev);
Simon Glass918354b2014-10-29 13:08:57 -0600476
477 return at91_get_port_value(port->regs, offset);
478}
479
480/* write GPIO OUT value to pin 'gpio' */
481static int at91_gpio_set_value(struct udevice *dev, unsigned offset,
482 int value)
483{
Axel Lind8958212015-01-31 14:47:34 +0800484 struct at91_port_priv *port = dev_get_priv(dev);
Simon Glass918354b2014-10-29 13:08:57 -0600485
486 at91_set_port_value(port->regs, offset, value);
487
488 return 0;
489}
490
491static int at91_gpio_get_function(struct udevice *dev, unsigned offset)
492{
Axel Lind8958212015-01-31 14:47:34 +0800493 struct at91_port_priv *port = dev_get_priv(dev);
Simon Glass918354b2014-10-29 13:08:57 -0600494
495 /* GPIOF_FUNC is not implemented yet */
496 if (at91_get_port_output(port->regs, offset))
497 return GPIOF_OUTPUT;
498 else
499 return GPIOF_INPUT;
500}
501
502static const struct dm_gpio_ops gpio_at91_ops = {
503 .direction_input = at91_gpio_direction_input,
504 .direction_output = at91_gpio_direction_output,
505 .get_value = at91_gpio_get_value,
506 .set_value = at91_gpio_set_value,
507 .get_function = at91_gpio_get_function,
508};
509
510static int at91_gpio_probe(struct udevice *dev)
511{
512 struct at91_port_priv *port = dev_get_priv(dev);
513 struct at91_port_platdata *plat = dev_get_platdata(dev);
514 struct gpio_dev_priv *uc_priv = dev->uclass_priv;
515
516 uc_priv->bank_name = plat->bank_name;
517 uc_priv->gpio_count = GPIO_PER_BANK;
518 port->regs = (struct at91_port *)plat->base_addr;
519
520 return 0;
521}
522
523U_BOOT_DRIVER(gpio_at91) = {
524 .name = "gpio_at91",
525 .id = UCLASS_GPIO,
526 .ops = &gpio_at91_ops,
527 .probe = at91_gpio_probe,
528 .priv_auto_alloc_size = sizeof(struct at91_port_priv),
529};
530#endif