blob: 6517af162815ea8e5715dabb390ed46de12f4617 [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>
Alexey Brodkin1ace4022014-02-26 17:47:58 +040014#include <linux/sizes.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010015#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:
Wu, Josh7d82d892014-05-07 16:50:45 +080037 printf("Error: at91_gpio: Fail to get PIO base!\n");
Bo Shen4bc9b7a2013-08-22 15:24:40 +080038 return NULL;
39 }
40}
41
Jens Scharsigea8fbba2010-02-03 22:46:16 +010042int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
43{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080044 struct at91_port *at91_port = at91_pio_get_port(port);
45 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010046
Bo Shen4bc9b7a2013-08-22 15:24:40 +080047 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010048 mask = 1 << pin;
49 if (use_pullup)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080050 writel(1 << pin, &at91_port->puer);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010051 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +080052 writel(1 << pin, &at91_port->pudr);
53 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010054 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080055
Jens Scharsigea8fbba2010-02-03 22:46:16 +010056 return 0;
57}
58
59/*
60 * mux the pin to the "GPIO" peripheral role.
61 */
62int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
63{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080064 struct at91_port *at91_port = at91_pio_get_port(port);
65 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010066
Bo Shen4bc9b7a2013-08-22 15:24:40 +080067 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010068 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080069 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010070 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +080071 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010072 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080073
Jens Scharsigea8fbba2010-02-03 22:46:16 +010074 return 0;
75}
76
77/*
78 * mux the pin to the "A" internal peripheral role.
79 */
80int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
81{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080082 struct at91_port *at91_port = at91_pio_get_port(port);
83 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010084
Bo Shen4bc9b7a2013-08-22 15:24:40 +080085 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010086 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080087 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010088 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +000089#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080090 writel(readl(&at91_port->abcdsr1) & ~mask,
91 &at91_port->abcdsr1);
92 writel(readl(&at91_port->abcdsr2) & ~mask,
93 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +000094#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +080095 writel(mask, &at91_port->asr);
Bo Shen2b3b1c62012-05-20 15:50:00 +000096#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +080097 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010098 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080099
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100100 return 0;
101}
102
103/*
104 * mux the pin to the "B" internal peripheral role.
105 */
106int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
107{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800108 struct at91_port *at91_port = at91_pio_get_port(port);
109 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100110
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800111 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100112 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800113 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100114 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000115#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800116 writel(readl(&at91_port->abcdsr1) | mask,
117 &at91_port->abcdsr1);
118 writel(readl(&at91_port->abcdsr2) & ~mask,
119 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000120#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800121 writel(mask, &at91_port->bsr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000122#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800123 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100124 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800125
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100126 return 0;
127}
128
Bo Shen2b3b1c62012-05-20 15:50:00 +0000129#if defined(CPU_HAS_PIO3)
130/*
131 * mux the pin to the "C" internal peripheral role.
132 */
133int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
134{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800135 struct at91_port *at91_port = at91_pio_get_port(port);
136 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000137
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800138 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000139 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800140 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000141 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800142 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);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000147 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800148
Bo Shen2b3b1c62012-05-20 15:50:00 +0000149 return 0;
150}
151
152/*
153 * mux the pin to the "D" internal peripheral role.
154 */
155int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
156{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800157 struct at91_port *at91_port = at91_pio_get_port(port);
158 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000159
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800160 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000161 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800162 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000163 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800164 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);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000169 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800170
Bo Shen2b3b1c62012-05-20 15:50:00 +0000171 return 0;
172}
173#endif
174
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100175/*
176 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
177 * configure it for an input.
178 */
179int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
180{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800181 struct at91_port *at91_port = at91_pio_get_port(port);
182 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100183
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800184 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100185 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800186 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100187 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800188 writel(mask, &at91_port->odr);
189 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100190 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800191
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100192 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 */
199int at91_set_pio_output(unsigned port, u32 pin, int value)
200{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800201 struct at91_port *at91_port = at91_pio_get_port(port);
202 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100203
Wu, Josh7d82d892014-05-07 16:50:45 +0800204 if (at91_port && (port < ATMEL_PIO_PORTS) && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100205 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800206 writel(mask, &at91_port->idr);
207 writel(mask, &at91_port->pudr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100208 if (value)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800209 writel(mask, &at91_port->sodr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100210 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800211 writel(mask, &at91_port->codr);
212 writel(mask, &at91_port->oer);
213 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100214 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800215
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100216 return 0;
217}
218
219/*
220 * enable/disable the glitch filter. mostly used with IRQ handling.
221 */
222int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
223{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800224 struct at91_port *at91_port = at91_pio_get_port(port);
225 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100226
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800227 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100228 mask = 1 << pin;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000229 if (is_on) {
230#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800231 writel(mask, &at91_port->ifscdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000232#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800233 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000234 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800235 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000236 }
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100237 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800238
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100239 return 0;
240}
241
Bo Shen2b3b1c62012-05-20 15:50:00 +0000242#if defined(CPU_HAS_PIO3)
243/*
244 * enable/disable the debounce filter.
245 */
246int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
247{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800248 struct at91_port *at91_port = at91_pio_get_port(port);
249 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000250
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800251 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000252 mask = 1 << pin;
253 if (is_on) {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800254 writel(mask, &at91_port->ifscer);
255 writel(div & PIO_SCDR_DIV, &at91_port->scdr);
256 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000257 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800258 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000259 }
260 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800261
Bo Shen2b3b1c62012-05-20 15:50:00 +0000262 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 */
269int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
270{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800271 struct at91_port *at91_port = at91_pio_get_port(port);
272 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000273
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800274 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000275 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800276 writel(mask, &at91_port->pudr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000277 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800278 writel(mask, &at91_port->ppder);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000279 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800280 writel(mask, &at91_port->ppddr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000281 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800282
Bo Shen2b3b1c62012-05-20 15:50:00 +0000283 return 0;
284}
285
286/*
287 * disable Schmitt trigger
288 */
289int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
290{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800291 struct at91_port *at91_port = at91_pio_get_port(port);
292 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000293
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800294 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000295 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800296 writel(readl(&at91_port->schmitt) | mask,
297 &at91_port->schmitt);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000298 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800299
Bo Shen2b3b1c62012-05-20 15:50:00 +0000300 return 0;
301}
302#endif
303
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100304/*
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 */
308int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
309{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800310 struct at91_port *at91_port = at91_pio_get_port(port);
311 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100312
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800313 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100314 mask = 1 << pin;
315 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800316 writel(mask, &at91_port->mder);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100317 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800318 writel(mask, &at91_port->mddr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100319 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800320
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100321 return 0;
322}
323
324/*
325 * assuming the pin is muxed as a gpio output, set its value.
326 */
327int at91_set_pio_value(unsigned port, unsigned pin, int value)
328{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800329 struct at91_port *at91_port = at91_pio_get_port(port);
330 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100331
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800332 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100333 mask = 1 << pin;
334 if (value)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800335 writel(mask, &at91_port->sodr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100336 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800337 writel(mask, &at91_port->codr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100338 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800339
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100340 return 0;
341}
342
343/*
344 * read the pin's value (works even if it's not muxed as a gpio).
345 */
346int at91_get_pio_value(unsigned port, unsigned pin)
347{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800348 struct at91_port *at91_port = at91_pio_get_port(port);
349 u32 pdsr = 0, mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100350
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800351 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100352 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800353 pdsr = readl(&at91_port->pdsr) & mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100354 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800355
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100356 return pdsr != 0;
357}
Bo Shen6edaea82013-08-13 14:38:31 +0800358
359/* Common GPIO API */
360
Bo Shen6edaea82013-08-13 14:38:31 +0800361int gpio_request(unsigned gpio, const char *label)
362{
363 return 0;
364}
365
366int gpio_free(unsigned gpio)
367{
368 return 0;
369}
370
371int 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
378int 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
385int 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
391int 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}