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