xref: /OK3568_Linux_fs/u-boot/drivers/gpio/at91_gpio.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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