xref: /linux/arch/m68k/include/asm/mcfgpio.h (revision 83c6bdb827c9422fe6e02130d9546800143304c1)
1af39bb8bSsfking@fdwdc.com /*
2af39bb8bSsfking@fdwdc.com  * Coldfire generic GPIO support.
3af39bb8bSsfking@fdwdc.com  *
4af39bb8bSsfking@fdwdc.com  * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
5af39bb8bSsfking@fdwdc.com  *
6af39bb8bSsfking@fdwdc.com  * This program is free software; you can redistribute it and/or modify
7af39bb8bSsfking@fdwdc.com  * it under the terms of the GNU General Public License as published by
8af39bb8bSsfking@fdwdc.com  * the Free Software Foundation; version 2 of the License.
9af39bb8bSsfking@fdwdc.com  *
10af39bb8bSsfking@fdwdc.com  * This program is distributed in the hope that it will be useful,
11af39bb8bSsfking@fdwdc.com  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12af39bb8bSsfking@fdwdc.com  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13af39bb8bSsfking@fdwdc.com  * GNU General Public License for more details.
14af39bb8bSsfking@fdwdc.com  */
15af39bb8bSsfking@fdwdc.com 
16af39bb8bSsfking@fdwdc.com #ifndef mcfgpio_h
17af39bb8bSsfking@fdwdc.com #define mcfgpio_h
18af39bb8bSsfking@fdwdc.com 
19eac57949SSteven King #ifdef CONFIG_GPIOLIB
20af39bb8bSsfking@fdwdc.com #include <asm-generic/gpio.h>
21eac57949SSteven King #else
22af39bb8bSsfking@fdwdc.com 
23eac57949SSteven King int __mcfgpio_get_value(unsigned gpio);
24eac57949SSteven King void __mcfgpio_set_value(unsigned gpio, int value);
25eac57949SSteven King int __mcfgpio_direction_input(unsigned gpio);
26eac57949SSteven King int __mcfgpio_direction_output(unsigned gpio, int value);
27eac57949SSteven King int __mcfgpio_request(unsigned gpio);
28eac57949SSteven King void __mcfgpio_free(unsigned gpio);
29af39bb8bSsfking@fdwdc.com 
30eac57949SSteven King /* our alternate 'gpiolib' functions */
31eac57949SSteven King static inline int __gpio_get_value(unsigned gpio)
32eac57949SSteven King {
33eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
34eac57949SSteven King 		return __mcfgpio_get_value(gpio);
35eac57949SSteven King 	else
36eac57949SSteven King 		return -EINVAL;
37eac57949SSteven King }
38f23c144dSGreg Ungerer 
39eac57949SSteven King static inline void __gpio_set_value(unsigned gpio, int value)
40eac57949SSteven King {
41eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
42eac57949SSteven King 		__mcfgpio_set_value(gpio, value);
43eac57949SSteven King }
44eac57949SSteven King 
45eac57949SSteven King static inline int __gpio_cansleep(unsigned gpio)
46eac57949SSteven King {
47eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
48eac57949SSteven King 		return 0;
49eac57949SSteven King 	else
50eac57949SSteven King 		return -EINVAL;
51eac57949SSteven King }
52eac57949SSteven King 
53eac57949SSteven King static inline int __gpio_to_irq(unsigned gpio)
54eac57949SSteven King {
55eac57949SSteven King 	return -EINVAL;
56eac57949SSteven King }
57eac57949SSteven King 
58eac57949SSteven King static inline int gpio_direction_input(unsigned gpio)
59eac57949SSteven King {
60eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
61eac57949SSteven King 		return __mcfgpio_direction_input(gpio);
62eac57949SSteven King 	else
63eac57949SSteven King 		return -EINVAL;
64eac57949SSteven King }
65eac57949SSteven King 
66eac57949SSteven King static inline int gpio_direction_output(unsigned gpio, int value)
67eac57949SSteven King {
68eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
69eac57949SSteven King 		return __mcfgpio_direction_output(gpio, value);
70eac57949SSteven King 	else
71eac57949SSteven King 		return -EINVAL;
72eac57949SSteven King }
73eac57949SSteven King 
74eac57949SSteven King static inline int gpio_request(unsigned gpio, const char *label)
75eac57949SSteven King {
76eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
77eac57949SSteven King 		return __mcfgpio_request(gpio);
78eac57949SSteven King 	else
79eac57949SSteven King 		return -EINVAL;
80eac57949SSteven King }
81eac57949SSteven King 
82eac57949SSteven King static inline void gpio_free(unsigned gpio)
83eac57949SSteven King {
84eac57949SSteven King 	if (gpio < MCFGPIO_PIN_MAX)
85eac57949SSteven King 		__mcfgpio_free(gpio);
86eac57949SSteven King }
87eac57949SSteven King 
88eac57949SSteven King #endif /* CONFIG_GPIOLIB */
89eac57949SSteven King 
90af39bb8bSsfking@fdwdc.com 
91c269d4efSGreg Ungerer /*
92eac57949SSteven King  * The Freescale Coldfire family is quite varied in how they implement GPIO.
93eac57949SSteven King  * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have
94eac57949SSteven King  * only one port, others have multiple ports; some have a single data latch
95eac57949SSteven King  * for both input and output, others have a separate pin data register to read
96eac57949SSteven King  * input; some require a read-modify-write access to change an output, others
97eac57949SSteven King  * have set and clear registers for some of the outputs; Some have all the
98eac57949SSteven King  * GPIOs in a single control area, others have some GPIOs implemented in
99eac57949SSteven King  * different modules.
100c269d4efSGreg Ungerer  *
101eac57949SSteven King  * This implementation attempts accommodate the differences while presenting
102eac57949SSteven King  * a generic interface that will optimize to as few instructions as possible.
103c269d4efSGreg Ungerer  */
104eac57949SSteven King #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
105eac57949SSteven King     defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
106eac57949SSteven King     defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
1076eac4027SGreg Ungerer     defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \
108bea8bcb1SSteven King     defined(CONFIG_M5441x)
109c269d4efSGreg Ungerer 
110eac57949SSteven King /* These parts have GPIO organized by 8 bit ports */
111eac57949SSteven King 
112eac57949SSteven King #define MCFGPIO_PORTTYPE		u8
113eac57949SSteven King #define MCFGPIO_PORTSIZE		8
114eac57949SSteven King #define mcfgpio_read(port)		__raw_readb(port)
115eac57949SSteven King #define mcfgpio_write(data, port)	__raw_writeb(data, port)
116eac57949SSteven King 
117eac57949SSteven King #elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272)
118eac57949SSteven King 
119eac57949SSteven King /* These parts have GPIO organized by 16 bit ports */
120eac57949SSteven King 
121eac57949SSteven King #define MCFGPIO_PORTTYPE		u16
122eac57949SSteven King #define MCFGPIO_PORTSIZE		16
123eac57949SSteven King #define mcfgpio_read(port)		__raw_readw(port)
124eac57949SSteven King #define mcfgpio_write(data, port)	__raw_writew(data, port)
125eac57949SSteven King 
12604e037aaSSteven King #elif defined(CONFIG_M5249) || defined(CONFIG_M525x)
127eac57949SSteven King 
128eac57949SSteven King /* These parts have GPIO organized by 32 bit ports */
129eac57949SSteven King 
130eac57949SSteven King #define MCFGPIO_PORTTYPE		u32
131eac57949SSteven King #define MCFGPIO_PORTSIZE		32
132eac57949SSteven King #define mcfgpio_read(port)		__raw_readl(port)
133eac57949SSteven King #define mcfgpio_write(data, port)	__raw_writel(data, port)
134c269d4efSGreg Ungerer 
135af39bb8bSsfking@fdwdc.com #endif
136eac57949SSteven King 
137eac57949SSteven King #define mcfgpio_bit(gpio)		(1 << ((gpio) %  MCFGPIO_PORTSIZE))
138eac57949SSteven King #define mcfgpio_port(gpio)		((gpio) / MCFGPIO_PORTSIZE)
139eac57949SSteven King 
140eac57949SSteven King #if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
141bea8bcb1SSteven King     defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
142*83c6bdb8SSteven King     defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \
143*83c6bdb8SSteven King     defined(CONFIG_M5441x)
144eac57949SSteven King /*
145eac57949SSteven King  * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses
146eac57949SSteven King  * read-modify-write to change an output and a GPIO module which has separate
147eac57949SSteven King  * set/clr registers to directly change outputs with a single write access.
148eac57949SSteven King  */
149eac57949SSteven King #if defined(CONFIG_M528x)
150eac57949SSteven King /*
151eac57949SSteven King  * The 528x also has GPIOs in other modules (GPT, QADC) which use
152eac57949SSteven King  * read-modify-write as well as those controlled by the EPORT and GPIO modules.
153eac57949SSteven King  */
154eac57949SSteven King #define MCFGPIO_SCR_START		40
155bea8bcb1SSteven King #elif defined(CONFIGM5441x)
156bea8bcb1SSteven King /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */
157bea8bcb1SSteven King #define MCFGPIO_SCR_START		0
158eac57949SSteven King #else
159eac57949SSteven King #define MCFGPIO_SCR_START		8
160eac57949SSteven King #endif
161eac57949SSteven King 
162eac57949SSteven King #define MCFGPIO_SETR_PORT(gpio)		(MCFGPIO_SETR + \
163eac57949SSteven King 					mcfgpio_port(gpio - MCFGPIO_SCR_START))
164eac57949SSteven King 
165eac57949SSteven King #define MCFGPIO_CLRR_PORT(gpio)		(MCFGPIO_CLRR + \
166eac57949SSteven King 					mcfgpio_port(gpio - MCFGPIO_SCR_START))
167eac57949SSteven King #else
168eac57949SSteven King 
169eac57949SSteven King #define MCFGPIO_SCR_START		MCFGPIO_PIN_MAX
170eac57949SSteven King /* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */
171eac57949SSteven King #define MCFGPIO_SETR_PORT(gpio)		0
172eac57949SSteven King #define MCFGPIO_CLRR_PORT(gpio)		0
173eac57949SSteven King 
174eac57949SSteven King #endif
175eac57949SSteven King /*
176eac57949SSteven King  * Coldfire specific helper functions
177eac57949SSteven King  */
178eac57949SSteven King 
179eac57949SSteven King /* return the port pin data register for a gpio */
180eac57949SSteven King static inline u32 __mcfgpio_ppdr(unsigned gpio)
181eac57949SSteven King {
182eac57949SSteven King #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
183eac57949SSteven King     defined(CONFIG_M5307) || defined(CONFIG_M5407)
184eac57949SSteven King 	return MCFSIM_PADAT;
185eac57949SSteven King #elif defined(CONFIG_M5272)
186eac57949SSteven King 	if (gpio < 16)
187eac57949SSteven King 		return MCFSIM_PADAT;
188eac57949SSteven King 	else if (gpio < 32)
189eac57949SSteven King 		return MCFSIM_PBDAT;
190eac57949SSteven King 	else
191eac57949SSteven King 		return MCFSIM_PCDAT;
19204e037aaSSteven King #elif defined(CONFIG_M5249) || defined(CONFIG_M525x)
193eac57949SSteven King 	if (gpio < 32)
194eac57949SSteven King 		return MCFSIM2_GPIOREAD;
195eac57949SSteven King 	else
196eac57949SSteven King 		return MCFSIM2_GPIO1READ;
197eac57949SSteven King #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
198bea8bcb1SSteven King       defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
199*83c6bdb8SSteven King       defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \
200*83c6bdb8SSteven King       defined(CONFIG_M5441x)
201bea8bcb1SSteven King #if !defined(CONFIG_M5441x)
202eac57949SSteven King 	if (gpio < 8)
203eac57949SSteven King 		return MCFEPORT_EPPDR;
204eac57949SSteven King #if defined(CONFIG_M528x)
205eac57949SSteven King 	else if (gpio < 16)
206eac57949SSteven King 		return MCFGPTA_GPTPORT;
207eac57949SSteven King 	else if (gpio < 24)
208eac57949SSteven King 		return MCFGPTB_GPTPORT;
209eac57949SSteven King 	else if (gpio < 32)
210eac57949SSteven King 		return MCFQADC_PORTQA;
211eac57949SSteven King 	else if (gpio < 40)
212eac57949SSteven King 		return MCFQADC_PORTQB;
213bea8bcb1SSteven King #endif /* defined(CONFIG_M528x) */
214eac57949SSteven King 	else
215bea8bcb1SSteven King #endif /* !defined(CONFIG_M5441x) */
216eac57949SSteven King 		return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
217eac57949SSteven King #else
218eac57949SSteven King 	return 0;
219eac57949SSteven King #endif
220eac57949SSteven King }
221eac57949SSteven King 
222eac57949SSteven King /* return the port output data register for a gpio */
223eac57949SSteven King static inline u32 __mcfgpio_podr(unsigned gpio)
224eac57949SSteven King {
225eac57949SSteven King #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
226eac57949SSteven King     defined(CONFIG_M5307) || defined(CONFIG_M5407)
227eac57949SSteven King 	return MCFSIM_PADAT;
228eac57949SSteven King #elif defined(CONFIG_M5272)
229eac57949SSteven King 	if (gpio < 16)
230eac57949SSteven King 		return MCFSIM_PADAT;
231eac57949SSteven King 	else if (gpio < 32)
232eac57949SSteven King 		return MCFSIM_PBDAT;
233eac57949SSteven King 	else
234eac57949SSteven King 		return MCFSIM_PCDAT;
23504e037aaSSteven King #elif defined(CONFIG_M5249) || defined(CONFIG_M525x)
236eac57949SSteven King 	if (gpio < 32)
237eac57949SSteven King 		return MCFSIM2_GPIOWRITE;
238eac57949SSteven King 	else
239eac57949SSteven King 		return MCFSIM2_GPIO1WRITE;
240eac57949SSteven King #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
241bea8bcb1SSteven King       defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
242*83c6bdb8SSteven King       defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \
243*83c6bdb8SSteven King       defined(CONFIG_M5441x)
244bea8bcb1SSteven King #if !defined(CONFIG_M5441x)
245eac57949SSteven King 	if (gpio < 8)
246eac57949SSteven King 		return MCFEPORT_EPDR;
247eac57949SSteven King #if defined(CONFIG_M528x)
248eac57949SSteven King 	else if (gpio < 16)
249eac57949SSteven King 		return MCFGPTA_GPTPORT;
250eac57949SSteven King 	else if (gpio < 24)
251eac57949SSteven King 		return MCFGPTB_GPTPORT;
252eac57949SSteven King 	else if (gpio < 32)
253eac57949SSteven King 		return MCFQADC_PORTQA;
254eac57949SSteven King 	else if (gpio < 40)
255eac57949SSteven King 		return MCFQADC_PORTQB;
256bea8bcb1SSteven King #endif /* defined(CONFIG_M528x) */
257eac57949SSteven King 	else
258bea8bcb1SSteven King #endif /* !defined(CONFIG_M5441x) */
259eac57949SSteven King 		return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
260eac57949SSteven King #else
261eac57949SSteven King 	return 0;
262eac57949SSteven King #endif
263eac57949SSteven King }
264eac57949SSteven King 
265eac57949SSteven King /* return the port direction data register for a gpio */
266eac57949SSteven King static inline u32 __mcfgpio_pddr(unsigned gpio)
267eac57949SSteven King {
268eac57949SSteven King #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
269eac57949SSteven King     defined(CONFIG_M5307) || defined(CONFIG_M5407)
270eac57949SSteven King 	return MCFSIM_PADDR;
271eac57949SSteven King #elif defined(CONFIG_M5272)
272eac57949SSteven King 	if (gpio < 16)
273eac57949SSteven King 		return MCFSIM_PADDR;
274eac57949SSteven King 	else if (gpio < 32)
275eac57949SSteven King 		return MCFSIM_PBDDR;
276eac57949SSteven King 	else
277eac57949SSteven King 		return MCFSIM_PCDDR;
27804e037aaSSteven King #elif defined(CONFIG_M5249) || defined(CONFIG_M525x)
279eac57949SSteven King 	if (gpio < 32)
280eac57949SSteven King 		return MCFSIM2_GPIOENABLE;
281eac57949SSteven King 	else
282eac57949SSteven King 		return MCFSIM2_GPIO1ENABLE;
283eac57949SSteven King #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
284bea8bcb1SSteven King       defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
285*83c6bdb8SSteven King       defined(CONFIG_M53xx) || defined(CONFIG_M54xx) || \
286*83c6bdb8SSteven King       defined(CONFIG_M5441x)
287bea8bcb1SSteven King #if !defined(CONFIG_M5441x)
288eac57949SSteven King 	if (gpio < 8)
289eac57949SSteven King 		return MCFEPORT_EPDDR;
290eac57949SSteven King #if defined(CONFIG_M528x)
291eac57949SSteven King 	else if (gpio < 16)
292eac57949SSteven King 		return MCFGPTA_GPTDDR;
293eac57949SSteven King 	else if (gpio < 24)
294eac57949SSteven King 		return MCFGPTB_GPTDDR;
295eac57949SSteven King 	else if (gpio < 32)
296eac57949SSteven King 		return MCFQADC_DDRQA;
297eac57949SSteven King 	else if (gpio < 40)
298eac57949SSteven King 		return MCFQADC_DDRQB;
299bea8bcb1SSteven King #endif /* defined(CONFIG_M528x) */
300eac57949SSteven King 	else
301bea8bcb1SSteven King #endif /* !defined(CONFIG_M5441x) */
302eac57949SSteven King 		return MCFGPIO_PDDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
303eac57949SSteven King #else
304eac57949SSteven King 	return 0;
305eac57949SSteven King #endif
306eac57949SSteven King }
307eac57949SSteven King 
308eac57949SSteven King #endif /* mcfgpio_h */
309