1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2005 HP Labs
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <config.h>
12*4882a593Smuzhiyun #include <common.h>
13*4882a593Smuzhiyun #include <clk.h>
14*4882a593Smuzhiyun #include <dm.h>
15*4882a593Smuzhiyun #include <asm/io.h>
16*4882a593Smuzhiyun #include <linux/sizes.h>
17*4882a593Smuzhiyun #include <asm/gpio.h>
18*4882a593Smuzhiyun #include <asm/arch/hardware.h>
19*4882a593Smuzhiyun #include <asm/arch/at91_pio.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define GPIO_PER_BANK 32
22*4882a593Smuzhiyun
at91_pio_get_port(unsigned port)23*4882a593Smuzhiyun static struct at91_port *at91_pio_get_port(unsigned port)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun switch (port) {
26*4882a593Smuzhiyun case AT91_PIO_PORTA:
27*4882a593Smuzhiyun return (struct at91_port *)ATMEL_BASE_PIOA;
28*4882a593Smuzhiyun case AT91_PIO_PORTB:
29*4882a593Smuzhiyun return (struct at91_port *)ATMEL_BASE_PIOB;
30*4882a593Smuzhiyun case AT91_PIO_PORTC:
31*4882a593Smuzhiyun return (struct at91_port *)ATMEL_BASE_PIOC;
32*4882a593Smuzhiyun #if (ATMEL_PIO_PORTS > 3)
33*4882a593Smuzhiyun case AT91_PIO_PORTD:
34*4882a593Smuzhiyun return (struct at91_port *)ATMEL_BASE_PIOD;
35*4882a593Smuzhiyun #if (ATMEL_PIO_PORTS > 4)
36*4882a593Smuzhiyun case AT91_PIO_PORTE:
37*4882a593Smuzhiyun return (struct at91_port *)ATMEL_BASE_PIOE;
38*4882a593Smuzhiyun #endif
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun default:
41*4882a593Smuzhiyun printf("Error: at91_gpio: Fail to get PIO base!\n");
42*4882a593Smuzhiyun return NULL;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun
at91_set_port_pullup(struct at91_port * at91_port,unsigned offset,int use_pullup)46*4882a593Smuzhiyun static void at91_set_port_pullup(struct at91_port *at91_port, unsigned offset,
47*4882a593Smuzhiyun int use_pullup)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun u32 mask;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun mask = 1 << offset;
52*4882a593Smuzhiyun if (use_pullup)
53*4882a593Smuzhiyun writel(mask, &at91_port->puer);
54*4882a593Smuzhiyun else
55*4882a593Smuzhiyun writel(mask, &at91_port->pudr);
56*4882a593Smuzhiyun writel(mask, &at91_port->per);
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
at91_set_pio_pullup(unsigned port,unsigned pin,int use_pullup)59*4882a593Smuzhiyun int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK))
64*4882a593Smuzhiyun at91_set_port_pullup(at91_port, pin, use_pullup);
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun return 0;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /*
70*4882a593Smuzhiyun * mux the pin to the "GPIO" peripheral role.
71*4882a593Smuzhiyun */
at91_set_pio_periph(unsigned port,unsigned pin,int use_pullup)72*4882a593Smuzhiyun int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
75*4882a593Smuzhiyun u32 mask;
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
78*4882a593Smuzhiyun mask = 1 << pin;
79*4882a593Smuzhiyun writel(mask, &at91_port->idr);
80*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
81*4882a593Smuzhiyun writel(mask, &at91_port->per);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun return 0;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun /*
88*4882a593Smuzhiyun * mux the pin to the "A" internal peripheral role.
89*4882a593Smuzhiyun */
at91_set_a_periph(unsigned port,unsigned pin,int use_pullup)90*4882a593Smuzhiyun int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
93*4882a593Smuzhiyun u32 mask;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
96*4882a593Smuzhiyun mask = 1 << pin;
97*4882a593Smuzhiyun writel(mask, &at91_port->idr);
98*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
99*4882a593Smuzhiyun writel(mask, &at91_port->mux.pio2.asr);
100*4882a593Smuzhiyun writel(mask, &at91_port->pdr);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun return 0;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /*
107*4882a593Smuzhiyun * mux the pin to the "B" internal peripheral role.
108*4882a593Smuzhiyun */
at91_set_b_periph(unsigned port,unsigned pin,int use_pullup)109*4882a593Smuzhiyun int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
112*4882a593Smuzhiyun u32 mask;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
115*4882a593Smuzhiyun mask = 1 << pin;
116*4882a593Smuzhiyun writel(mask, &at91_port->idr);
117*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
118*4882a593Smuzhiyun writel(mask, &at91_port->mux.pio2.bsr);
119*4882a593Smuzhiyun writel(mask, &at91_port->pdr);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun return 0;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /*
126*4882a593Smuzhiyun * mux the pin to the "A" internal peripheral role.
127*4882a593Smuzhiyun */
at91_pio3_set_a_periph(unsigned port,unsigned pin,int use_pullup)128*4882a593Smuzhiyun int at91_pio3_set_a_periph(unsigned port, unsigned pin, int use_pullup)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
131*4882a593Smuzhiyun u32 mask;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
134*4882a593Smuzhiyun mask = 1 << pin;
135*4882a593Smuzhiyun writel(mask, &at91_port->idr);
136*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
137*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr1) & ~mask,
138*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr1);
139*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr2) & ~mask,
140*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr2);
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun writel(mask, &at91_port->pdr);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun return 0;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun /*
149*4882a593Smuzhiyun * mux the pin to the "B" internal peripheral role.
150*4882a593Smuzhiyun */
at91_pio3_set_b_periph(unsigned port,unsigned pin,int use_pullup)151*4882a593Smuzhiyun int at91_pio3_set_b_periph(unsigned port, unsigned pin, int use_pullup)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
154*4882a593Smuzhiyun u32 mask;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
157*4882a593Smuzhiyun mask = 1 << pin;
158*4882a593Smuzhiyun writel(mask, &at91_port->idr);
159*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
160*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr1) | mask,
161*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr1);
162*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr2) & ~mask,
163*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr2);
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun writel(mask, &at91_port->pdr);
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun return 0;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun /*
171*4882a593Smuzhiyun * mux the pin to the "C" internal peripheral role.
172*4882a593Smuzhiyun */
at91_pio3_set_c_periph(unsigned port,unsigned pin,int use_pullup)173*4882a593Smuzhiyun int at91_pio3_set_c_periph(unsigned port, unsigned pin, int use_pullup)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
176*4882a593Smuzhiyun u32 mask;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
179*4882a593Smuzhiyun mask = 1 << pin;
180*4882a593Smuzhiyun writel(mask, &at91_port->idr);
181*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
182*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr1) & ~mask,
183*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr1);
184*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr2) | mask,
185*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr2);
186*4882a593Smuzhiyun writel(mask, &at91_port->pdr);
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun return 0;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun /*
193*4882a593Smuzhiyun * mux the pin to the "D" internal peripheral role.
194*4882a593Smuzhiyun */
at91_pio3_set_d_periph(unsigned port,unsigned pin,int use_pullup)195*4882a593Smuzhiyun int at91_pio3_set_d_periph(unsigned port, unsigned pin, int use_pullup)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
198*4882a593Smuzhiyun u32 mask;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
201*4882a593Smuzhiyun mask = 1 << pin;
202*4882a593Smuzhiyun writel(mask, &at91_port->idr);
203*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, use_pullup);
204*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr1) | mask,
205*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr1);
206*4882a593Smuzhiyun writel(readl(&at91_port->mux.pio3.abcdsr2) | mask,
207*4882a593Smuzhiyun &at91_port->mux.pio3.abcdsr2);
208*4882a593Smuzhiyun writel(mask, &at91_port->pdr);
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun return 0;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun #ifdef CONFIG_DM_GPIO
at91_get_port_output(struct at91_port * at91_port,int offset)215*4882a593Smuzhiyun static bool at91_get_port_output(struct at91_port *at91_port, int offset)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun u32 mask, val;
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun mask = 1 << offset;
220*4882a593Smuzhiyun val = readl(&at91_port->osr);
221*4882a593Smuzhiyun return val & mask;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun #endif
224*4882a593Smuzhiyun
at91_set_port_input(struct at91_port * at91_port,int offset,int use_pullup)225*4882a593Smuzhiyun static void at91_set_port_input(struct at91_port *at91_port, int offset,
226*4882a593Smuzhiyun int use_pullup)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun u32 mask;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun mask = 1 << offset;
231*4882a593Smuzhiyun writel(mask, &at91_port->idr);
232*4882a593Smuzhiyun at91_set_port_pullup(at91_port, offset, use_pullup);
233*4882a593Smuzhiyun writel(mask, &at91_port->odr);
234*4882a593Smuzhiyun writel(mask, &at91_port->per);
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /*
238*4882a593Smuzhiyun * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
239*4882a593Smuzhiyun * configure it for an input.
240*4882a593Smuzhiyun */
at91_set_pio_input(unsigned port,u32 pin,int use_pullup)241*4882a593Smuzhiyun int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK))
246*4882a593Smuzhiyun at91_set_port_input(at91_port, pin, use_pullup);
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun return 0;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun
at91_set_port_output(struct at91_port * at91_port,int offset,int value)251*4882a593Smuzhiyun static void at91_set_port_output(struct at91_port *at91_port, int offset,
252*4882a593Smuzhiyun int value)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun u32 mask;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun mask = 1 << offset;
257*4882a593Smuzhiyun writel(mask, &at91_port->idr);
258*4882a593Smuzhiyun writel(mask, &at91_port->pudr);
259*4882a593Smuzhiyun if (value)
260*4882a593Smuzhiyun writel(mask, &at91_port->sodr);
261*4882a593Smuzhiyun else
262*4882a593Smuzhiyun writel(mask, &at91_port->codr);
263*4882a593Smuzhiyun writel(mask, &at91_port->oer);
264*4882a593Smuzhiyun writel(mask, &at91_port->per);
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /*
268*4882a593Smuzhiyun * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
269*4882a593Smuzhiyun * and configure it for an output.
270*4882a593Smuzhiyun */
at91_set_pio_output(unsigned port,u32 pin,int value)271*4882a593Smuzhiyun int at91_set_pio_output(unsigned port, u32 pin, int value)
272*4882a593Smuzhiyun {
273*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK))
276*4882a593Smuzhiyun at91_set_port_output(at91_port, pin, value);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun return 0;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun /*
282*4882a593Smuzhiyun * enable/disable the glitch filter. mostly used with IRQ handling.
283*4882a593Smuzhiyun */
at91_set_pio_deglitch(unsigned port,unsigned pin,int is_on)284*4882a593Smuzhiyun int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
287*4882a593Smuzhiyun u32 mask;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
290*4882a593Smuzhiyun mask = 1 << pin;
291*4882a593Smuzhiyun if (is_on)
292*4882a593Smuzhiyun writel(mask, &at91_port->ifer);
293*4882a593Smuzhiyun else
294*4882a593Smuzhiyun writel(mask, &at91_port->ifdr);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun return 0;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun /*
301*4882a593Smuzhiyun * enable/disable the glitch filter. mostly used with IRQ handling.
302*4882a593Smuzhiyun */
at91_pio3_set_pio_deglitch(unsigned port,unsigned pin,int is_on)303*4882a593Smuzhiyun int at91_pio3_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
306*4882a593Smuzhiyun u32 mask;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
309*4882a593Smuzhiyun mask = 1 << pin;
310*4882a593Smuzhiyun if (is_on) {
311*4882a593Smuzhiyun writel(mask, &at91_port->mux.pio3.ifscdr);
312*4882a593Smuzhiyun writel(mask, &at91_port->ifer);
313*4882a593Smuzhiyun } else {
314*4882a593Smuzhiyun writel(mask, &at91_port->ifdr);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun return 0;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun /*
322*4882a593Smuzhiyun * enable/disable the debounce filter.
323*4882a593Smuzhiyun */
at91_pio3_set_pio_debounce(unsigned port,unsigned pin,int is_on,int div)324*4882a593Smuzhiyun int at91_pio3_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
327*4882a593Smuzhiyun u32 mask;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
330*4882a593Smuzhiyun mask = 1 << pin;
331*4882a593Smuzhiyun if (is_on) {
332*4882a593Smuzhiyun writel(mask, &at91_port->mux.pio3.ifscer);
333*4882a593Smuzhiyun writel(div & PIO_SCDR_DIV, &at91_port->mux.pio3.scdr);
334*4882a593Smuzhiyun writel(mask, &at91_port->ifer);
335*4882a593Smuzhiyun } else {
336*4882a593Smuzhiyun writel(mask, &at91_port->ifdr);
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun return 0;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /*
344*4882a593Smuzhiyun * enable/disable the pull-down.
345*4882a593Smuzhiyun * If pull-up already enabled while calling the function, we disable it.
346*4882a593Smuzhiyun */
at91_pio3_set_pio_pulldown(unsigned port,unsigned pin,int is_on)347*4882a593Smuzhiyun int at91_pio3_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
350*4882a593Smuzhiyun u32 mask;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
353*4882a593Smuzhiyun mask = 1 << pin;
354*4882a593Smuzhiyun if (is_on) {
355*4882a593Smuzhiyun at91_set_pio_pullup(port, pin, 0);
356*4882a593Smuzhiyun writel(mask, &at91_port->mux.pio3.ppder);
357*4882a593Smuzhiyun } else
358*4882a593Smuzhiyun writel(mask, &at91_port->mux.pio3.ppddr);
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun return 0;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
at91_pio3_set_pio_pullup(unsigned port,unsigned pin,int use_pullup)364*4882a593Smuzhiyun int at91_pio3_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun if (use_pullup)
369*4882a593Smuzhiyun at91_pio3_set_pio_pulldown(port, pin, 0);
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK))
372*4882a593Smuzhiyun at91_set_port_pullup(at91_port, pin, use_pullup);
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun return 0;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /*
378*4882a593Smuzhiyun * disable Schmitt trigger
379*4882a593Smuzhiyun */
at91_pio3_set_pio_disable_schmitt_trig(unsigned port,unsigned pin)380*4882a593Smuzhiyun int at91_pio3_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
383*4882a593Smuzhiyun u32 mask;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
386*4882a593Smuzhiyun mask = 1 << pin;
387*4882a593Smuzhiyun writel(readl(&at91_port->schmitt) | mask,
388*4882a593Smuzhiyun &at91_port->schmitt);
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun return 0;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun /*
395*4882a593Smuzhiyun * enable/disable the multi-driver. This is only valid for output and
396*4882a593Smuzhiyun * allows the output pin to run as an open collector output.
397*4882a593Smuzhiyun */
at91_set_pio_multi_drive(unsigned port,unsigned pin,int is_on)398*4882a593Smuzhiyun int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
401*4882a593Smuzhiyun u32 mask;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK)) {
404*4882a593Smuzhiyun mask = 1 << pin;
405*4882a593Smuzhiyun if (is_on)
406*4882a593Smuzhiyun writel(mask, &at91_port->mder);
407*4882a593Smuzhiyun else
408*4882a593Smuzhiyun writel(mask, &at91_port->mddr);
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun return 0;
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
at91_set_port_value(struct at91_port * at91_port,int offset,int value)414*4882a593Smuzhiyun static void at91_set_port_value(struct at91_port *at91_port, int offset,
415*4882a593Smuzhiyun int value)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun u32 mask;
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun mask = 1 << offset;
420*4882a593Smuzhiyun if (value)
421*4882a593Smuzhiyun writel(mask, &at91_port->sodr);
422*4882a593Smuzhiyun else
423*4882a593Smuzhiyun writel(mask, &at91_port->codr);
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /*
427*4882a593Smuzhiyun * assuming the pin is muxed as a gpio output, set its value.
428*4882a593Smuzhiyun */
at91_set_pio_value(unsigned port,unsigned pin,int value)429*4882a593Smuzhiyun int at91_set_pio_value(unsigned port, unsigned pin, int value)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK))
434*4882a593Smuzhiyun at91_set_port_value(at91_port, pin, value);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun return 0;
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun
at91_get_port_value(struct at91_port * at91_port,int offset)439*4882a593Smuzhiyun static int at91_get_port_value(struct at91_port *at91_port, int offset)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun u32 pdsr = 0, mask;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun mask = 1 << offset;
444*4882a593Smuzhiyun pdsr = readl(&at91_port->pdsr) & mask;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun return pdsr != 0;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun /*
449*4882a593Smuzhiyun * read the pin's value (works even if it's not muxed as a gpio).
450*4882a593Smuzhiyun */
at91_get_pio_value(unsigned port,unsigned pin)451*4882a593Smuzhiyun int at91_get_pio_value(unsigned port, unsigned pin)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun struct at91_port *at91_port = at91_pio_get_port(port);
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun if (at91_port && (pin < GPIO_PER_BANK))
456*4882a593Smuzhiyun return at91_get_port_value(at91_port, pin);
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun return 0;
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun #ifndef CONFIG_DM_GPIO
462*4882a593Smuzhiyun /* Common GPIO API */
463*4882a593Smuzhiyun
gpio_request(unsigned gpio,const char * label)464*4882a593Smuzhiyun int gpio_request(unsigned gpio, const char *label)
465*4882a593Smuzhiyun {
466*4882a593Smuzhiyun return 0;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
gpio_free(unsigned gpio)469*4882a593Smuzhiyun int gpio_free(unsigned gpio)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun return 0;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
gpio_direction_input(unsigned gpio)474*4882a593Smuzhiyun int gpio_direction_input(unsigned gpio)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun at91_set_pio_input(at91_gpio_to_port(gpio),
477*4882a593Smuzhiyun at91_gpio_to_pin(gpio), 0);
478*4882a593Smuzhiyun return 0;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
gpio_direction_output(unsigned gpio,int value)481*4882a593Smuzhiyun int gpio_direction_output(unsigned gpio, int value)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun at91_set_pio_output(at91_gpio_to_port(gpio),
484*4882a593Smuzhiyun at91_gpio_to_pin(gpio), value);
485*4882a593Smuzhiyun return 0;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
gpio_get_value(unsigned gpio)488*4882a593Smuzhiyun int gpio_get_value(unsigned gpio)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun return at91_get_pio_value(at91_gpio_to_port(gpio),
491*4882a593Smuzhiyun at91_gpio_to_pin(gpio));
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
gpio_set_value(unsigned gpio,int value)494*4882a593Smuzhiyun int gpio_set_value(unsigned gpio, int value)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun at91_set_pio_value(at91_gpio_to_port(gpio),
497*4882a593Smuzhiyun at91_gpio_to_pin(gpio), value);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun return 0;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun #endif
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun #ifdef CONFIG_DM_GPIO
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun struct at91_port_priv {
506*4882a593Smuzhiyun struct at91_port *regs;
507*4882a593Smuzhiyun };
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun /* set GPIO pin 'gpio' as an input */
at91_gpio_direction_input(struct udevice * dev,unsigned offset)510*4882a593Smuzhiyun static int at91_gpio_direction_input(struct udevice *dev, unsigned offset)
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun struct at91_port_priv *port = dev_get_priv(dev);
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun at91_set_port_input(port->regs, offset, 0);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun return 0;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun /* set GPIO pin 'gpio' as an output, with polarity 'value' */
at91_gpio_direction_output(struct udevice * dev,unsigned offset,int value)520*4882a593Smuzhiyun static int at91_gpio_direction_output(struct udevice *dev, unsigned offset,
521*4882a593Smuzhiyun int value)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun struct at91_port_priv *port = dev_get_priv(dev);
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun at91_set_port_output(port->regs, offset, value);
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun return 0;
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun /* read GPIO IN value of pin 'gpio' */
at91_gpio_get_value(struct udevice * dev,unsigned offset)531*4882a593Smuzhiyun static int at91_gpio_get_value(struct udevice *dev, unsigned offset)
532*4882a593Smuzhiyun {
533*4882a593Smuzhiyun struct at91_port_priv *port = dev_get_priv(dev);
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun return at91_get_port_value(port->regs, offset);
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun /* write GPIO OUT value to pin 'gpio' */
at91_gpio_set_value(struct udevice * dev,unsigned offset,int value)539*4882a593Smuzhiyun static int at91_gpio_set_value(struct udevice *dev, unsigned offset,
540*4882a593Smuzhiyun int value)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun struct at91_port_priv *port = dev_get_priv(dev);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun at91_set_port_value(port->regs, offset, value);
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun return 0;
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun
at91_gpio_get_function(struct udevice * dev,unsigned offset)549*4882a593Smuzhiyun static int at91_gpio_get_function(struct udevice *dev, unsigned offset)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun struct at91_port_priv *port = dev_get_priv(dev);
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /* GPIOF_FUNC is not implemented yet */
554*4882a593Smuzhiyun if (at91_get_port_output(port->regs, offset))
555*4882a593Smuzhiyun return GPIOF_OUTPUT;
556*4882a593Smuzhiyun else
557*4882a593Smuzhiyun return GPIOF_INPUT;
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun static const struct dm_gpio_ops gpio_at91_ops = {
561*4882a593Smuzhiyun .direction_input = at91_gpio_direction_input,
562*4882a593Smuzhiyun .direction_output = at91_gpio_direction_output,
563*4882a593Smuzhiyun .get_value = at91_gpio_get_value,
564*4882a593Smuzhiyun .set_value = at91_gpio_set_value,
565*4882a593Smuzhiyun .get_function = at91_gpio_get_function,
566*4882a593Smuzhiyun };
567*4882a593Smuzhiyun
at91_gpio_probe(struct udevice * dev)568*4882a593Smuzhiyun static int at91_gpio_probe(struct udevice *dev)
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun struct at91_port_priv *port = dev_get_priv(dev);
571*4882a593Smuzhiyun struct at91_port_platdata *plat = dev_get_platdata(dev);
572*4882a593Smuzhiyun struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
573*4882a593Smuzhiyun struct clk clk;
574*4882a593Smuzhiyun int ret;
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun ret = clk_get_by_index(dev, 0, &clk);
577*4882a593Smuzhiyun if (ret)
578*4882a593Smuzhiyun return ret;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun ret = clk_enable(&clk);
581*4882a593Smuzhiyun if (ret)
582*4882a593Smuzhiyun return ret;
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun clk_free(&clk);
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun uc_priv->bank_name = plat->bank_name;
587*4882a593Smuzhiyun uc_priv->gpio_count = GPIO_PER_BANK;
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL)
590*4882a593Smuzhiyun plat->base_addr = (uint32_t)devfdt_get_addr_ptr(dev);
591*4882a593Smuzhiyun #endif
592*4882a593Smuzhiyun port->regs = (struct at91_port *)plat->base_addr;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun return 0;
595*4882a593Smuzhiyun }
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL)
598*4882a593Smuzhiyun static const struct udevice_id at91_gpio_ids[] = {
599*4882a593Smuzhiyun { .compatible = "atmel,at91rm9200-gpio" },
600*4882a593Smuzhiyun { }
601*4882a593Smuzhiyun };
602*4882a593Smuzhiyun #endif
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun U_BOOT_DRIVER(gpio_at91) = {
605*4882a593Smuzhiyun .name = "gpio_at91",
606*4882a593Smuzhiyun .id = UCLASS_GPIO,
607*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL)
608*4882a593Smuzhiyun .of_match = at91_gpio_ids,
609*4882a593Smuzhiyun .platdata_auto_alloc_size = sizeof(struct at91_port_platdata),
610*4882a593Smuzhiyun #endif
611*4882a593Smuzhiyun .ops = &gpio_at91_ops,
612*4882a593Smuzhiyun .probe = at91_gpio_probe,
613*4882a593Smuzhiyun .priv_auto_alloc_size = sizeof(struct at91_port_priv),
614*4882a593Smuzhiyun };
615*4882a593Smuzhiyun #endif
616