blob: 8b766665c689727081eea1e4311498726c2287df [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>
Reinhard Meyer86592f62010-11-07 13:26:14 +010013#include <asm/io.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010014#include <asm/sizes.h>
15#include <asm/arch/hardware.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010016#include <asm/arch/at91_pio.h>
Andreas Bießmann9ecc9222013-11-29 12:13:43 +010017#include <asm/arch/gpio.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010018
Bo Shen4bc9b7a2013-08-22 15:24:40 +080019static 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
Jens Scharsigea8fbba2010-02-03 22:46:16 +010041int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
42{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080043 struct at91_port *at91_port = at91_pio_get_port(port);
44 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010045
Bo Shen4bc9b7a2013-08-22 15:24:40 +080046 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010047 mask = 1 << pin;
48 if (use_pullup)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080049 writel(1 << pin, &at91_port->puer);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010050 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +080051 writel(1 << pin, &at91_port->pudr);
52 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010053 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080054
Jens Scharsigea8fbba2010-02-03 22:46:16 +010055 return 0;
56}
57
58/*
59 * mux the pin to the "GPIO" peripheral role.
60 */
61int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
62{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080063 struct at91_port *at91_port = at91_pio_get_port(port);
64 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010065
Bo Shen4bc9b7a2013-08-22 15:24:40 +080066 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010067 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080068 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010069 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +080070 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010071 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080072
Jens Scharsigea8fbba2010-02-03 22:46:16 +010073 return 0;
74}
75
76/*
77 * mux the pin to the "A" internal peripheral role.
78 */
79int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
80{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080081 struct at91_port *at91_port = at91_pio_get_port(port);
82 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010083
Bo Shen4bc9b7a2013-08-22 15:24:40 +080084 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010085 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080086 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010087 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +000088#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080089 writel(readl(&at91_port->abcdsr1) & ~mask,
90 &at91_port->abcdsr1);
91 writel(readl(&at91_port->abcdsr2) & ~mask,
92 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +000093#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +080094 writel(mask, &at91_port->asr);
Bo Shen2b3b1c62012-05-20 15:50:00 +000095#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +080096 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010097 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080098
Jens Scharsigea8fbba2010-02-03 22:46:16 +010099 return 0;
100}
101
102/*
103 * mux the pin to the "B" internal peripheral role.
104 */
105int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
106{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800107 struct at91_port *at91_port = at91_pio_get_port(port);
108 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100109
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800110 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100111 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800112 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100113 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000114#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800115 writel(readl(&at91_port->abcdsr1) | mask,
116 &at91_port->abcdsr1);
117 writel(readl(&at91_port->abcdsr2) & ~mask,
118 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000119#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800120 writel(mask, &at91_port->bsr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000121#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800122 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100123 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800124
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100125 return 0;
126}
127
Bo Shen2b3b1c62012-05-20 15:50:00 +0000128#if defined(CPU_HAS_PIO3)
129/*
130 * mux the pin to the "C" internal peripheral role.
131 */
132int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
133{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800134 struct at91_port *at91_port = at91_pio_get_port(port);
135 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000136
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800137 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000138 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800139 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000140 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800141 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);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000146 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800147
Bo Shen2b3b1c62012-05-20 15:50:00 +0000148 return 0;
149}
150
151/*
152 * mux the pin to the "D" internal peripheral role.
153 */
154int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
155{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800156 struct at91_port *at91_port = at91_pio_get_port(port);
157 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000158
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800159 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000160 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800161 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000162 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800163 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);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000168 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800169
Bo Shen2b3b1c62012-05-20 15:50:00 +0000170 return 0;
171}
172#endif
173
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100174/*
175 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
176 * configure it for an input.
177 */
178int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
179{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800180 struct at91_port *at91_port = at91_pio_get_port(port);
181 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100182
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800183 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100184 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800185 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100186 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800187 writel(mask, &at91_port->odr);
188 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100189 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800190
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100191 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 */
198int at91_set_pio_output(unsigned port, u32 pin, int value)
199{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800200 struct at91_port *at91_port = at91_pio_get_port(port);
201 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100202
Reinhard Meyer372f2782010-11-03 15:47:20 +0100203 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100204 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800205 writel(mask, &at91_port->idr);
206 writel(mask, &at91_port->pudr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100207 if (value)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800208 writel(mask, &at91_port->sodr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100209 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800210 writel(mask, &at91_port->codr);
211 writel(mask, &at91_port->oer);
212 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100213 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800214
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100215 return 0;
216}
217
218/*
219 * enable/disable the glitch filter. mostly used with IRQ handling.
220 */
221int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
222{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800223 struct at91_port *at91_port = at91_pio_get_port(port);
224 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100225
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800226 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100227 mask = 1 << pin;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000228 if (is_on) {
229#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800230 writel(mask, &at91_port->ifscdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000231#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800232 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000233 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800234 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000235 }
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100236 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800237
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100238 return 0;
239}
240
Bo Shen2b3b1c62012-05-20 15:50:00 +0000241#if defined(CPU_HAS_PIO3)
242/*
243 * enable/disable the debounce filter.
244 */
245int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
246{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800247 struct at91_port *at91_port = at91_pio_get_port(port);
248 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000249
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800250 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000251 mask = 1 << pin;
252 if (is_on) {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800253 writel(mask, &at91_port->ifscer);
254 writel(div & PIO_SCDR_DIV, &at91_port->scdr);
255 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000256 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800257 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000258 }
259 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800260
Bo Shen2b3b1c62012-05-20 15:50:00 +0000261 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 */
268int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
269{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800270 struct at91_port *at91_port = at91_pio_get_port(port);
271 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000272
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800273 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000274 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800275 writel(mask, &at91_port->pudr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000276 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800277 writel(mask, &at91_port->ppder);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000278 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800279 writel(mask, &at91_port->ppddr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000280 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800281
Bo Shen2b3b1c62012-05-20 15:50:00 +0000282 return 0;
283}
284
285/*
286 * disable Schmitt trigger
287 */
288int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
289{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800290 struct at91_port *at91_port = at91_pio_get_port(port);
291 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000292
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800293 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000294 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800295 writel(readl(&at91_port->schmitt) | mask,
296 &at91_port->schmitt);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000297 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800298
Bo Shen2b3b1c62012-05-20 15:50:00 +0000299 return 0;
300}
301#endif
302
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100303/*
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 */
307int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
308{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800309 struct at91_port *at91_port = at91_pio_get_port(port);
310 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100311
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800312 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100313 mask = 1 << pin;
314 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800315 writel(mask, &at91_port->mder);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100316 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800317 writel(mask, &at91_port->mddr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100318 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800319
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100320 return 0;
321}
322
323/*
324 * assuming the pin is muxed as a gpio output, set its value.
325 */
326int at91_set_pio_value(unsigned port, unsigned pin, int value)
327{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800328 struct at91_port *at91_port = at91_pio_get_port(port);
329 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100330
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800331 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100332 mask = 1 << pin;
333 if (value)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800334 writel(mask, &at91_port->sodr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100335 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800336 writel(mask, &at91_port->codr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100337 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800338
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100339 return 0;
340}
341
342/*
343 * read the pin's value (works even if it's not muxed as a gpio).
344 */
345int at91_get_pio_value(unsigned port, unsigned pin)
346{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800347 struct at91_port *at91_port = at91_pio_get_port(port);
348 u32 pdsr = 0, mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100349
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800350 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100351 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800352 pdsr = readl(&at91_port->pdsr) & mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100353 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800354
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100355 return pdsr != 0;
356}
Bo Shen6edaea82013-08-13 14:38:31 +0800357
358/* Common GPIO API */
359
Bo Shen6edaea82013-08-13 14:38:31 +0800360int gpio_request(unsigned gpio, const char *label)
361{
362 return 0;
363}
364
365int gpio_free(unsigned gpio)
366{
367 return 0;
368}
369
370int 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
377int 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
384int 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
390int 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}