1 /*
2  * SPDX-License-Identifier:	GPL-2.0+
3  */
4 
5 /*
6  * MPC8xx I/O port pin manipulation functions
7  * Roughly based on iopin_8260.h
8  */
9 
10 #ifndef _ASM_IOPIN_8XX_H_
11 #define _ASM_IOPIN_8XX_H_
12 
13 #include <linux/types.h>
14 #include <asm/8xx_immap.h>
15 
16 #ifdef __KERNEL__
17 
18 typedef struct {
19 	u_char port:2;	/* port number (A=0, B=1, C=2, D=3) */
20 	u_char pin:5;	/* port pin (0-31) */
21 	u_char flag:1;	/* for whatever */
22 } iopin_t;
23 
24 #define IOPIN_PORTA	0
25 #define IOPIN_PORTB	1
26 #define IOPIN_PORTC	2
27 #define IOPIN_PORTD	3
28 
29 static __inline__ void
30 iopin_set_high(iopin_t *iopin)
31 {
32 	if (iopin->port == IOPIN_PORTA) {
33 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padat;
34 		*datp |= (1 << (15 - iopin->pin));
35 	} else if (iopin->port == IOPIN_PORTB) {
36 		volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdat;
37 		*datp |= (1 << (31 - iopin->pin));
38 	} else if (iopin->port == IOPIN_PORTC) {
39 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdat;
40 		*datp |= (1 << (15 - iopin->pin));
41 	} else if (iopin->port == IOPIN_PORTD) {
42 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddat;
43 		*datp |= (1 << (15 - iopin->pin));
44 	}
45 }
46 
47 static __inline__ void
48 iopin_set_low(iopin_t *iopin)
49 {
50 	if (iopin->port == IOPIN_PORTA) {
51 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padat;
52 		*datp &= ~(1 << (15 - iopin->pin));
53 	} else if (iopin->port == IOPIN_PORTB) {
54 		volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdat;
55 		*datp &= ~(1 << (31 - iopin->pin));
56 	} else if (iopin->port == IOPIN_PORTC) {
57 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdat;
58 		*datp &= ~(1 << (15 - iopin->pin));
59 	} else if (iopin->port == IOPIN_PORTD) {
60 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddat;
61 		*datp &= ~(1 << (15 - iopin->pin));
62 	}
63 }
64 
65 static __inline__ uint
66 iopin_is_high(iopin_t *iopin)
67 {
68 	if (iopin->port == IOPIN_PORTA) {
69 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padat;
70 		return (*datp >> (15 - iopin->pin)) & 1;
71 	} else if (iopin->port == IOPIN_PORTB) {
72 		volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdat;
73 		return (*datp >> (31 - iopin->pin)) & 1;
74 	} else if (iopin->port == IOPIN_PORTC) {
75 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdat;
76 		return (*datp >> (15 - iopin->pin)) & 1;
77 	} else if (iopin->port == IOPIN_PORTD) {
78 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddat;
79 		return (*datp >> (15 - iopin->pin)) & 1;
80 	}
81 	return 0;
82 }
83 
84 static __inline__ uint
85 iopin_is_low(iopin_t *iopin)
86 {
87 	if (iopin->port == IOPIN_PORTA) {
88 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padat;
89 		return ((*datp >> (15 - iopin->pin)) & 1) ^ 1;
90 	} else if (iopin->port == IOPIN_PORTB) {
91 		volatile uint *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdat;
92 		return ((*datp >> (31 - iopin->pin)) & 1) ^ 1;
93 	} else if (iopin->port == IOPIN_PORTC) {
94 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdat;
95 		return ((*datp >> (15 - iopin->pin)) & 1) ^ 1;
96 	} else if (iopin->port == IOPIN_PORTD) {
97 		volatile ushort *datp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddat;
98 		return ((*datp >> (15 - iopin->pin)) & 1) ^ 1;
99 	}
100 	return 0;
101 }
102 
103 static __inline__ void
104 iopin_set_out(iopin_t *iopin)
105 {
106 	if (iopin->port == IOPIN_PORTA) {
107 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padir;
108 		*dirp |= (1 << (15 - iopin->pin));
109 	} else if (iopin->port == IOPIN_PORTB) {
110 		volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdir;
111 		*dirp |= (1 << (31 - iopin->pin));
112 	} else if (iopin->port == IOPIN_PORTC) {
113 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdir;
114 		*dirp |= (1 << (15 - iopin->pin));
115 	} else if (iopin->port == IOPIN_PORTD) {
116 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddir;
117 		*dirp |= (1 << (15 - iopin->pin));
118 	}
119 }
120 
121 static __inline__ void
122 iopin_set_in(iopin_t *iopin)
123 {
124 	if (iopin->port == IOPIN_PORTA) {
125 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padir;
126 		*dirp &= ~(1 << (15 - iopin->pin));
127 	} else if (iopin->port == IOPIN_PORTB) {
128 		volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdir;
129 		*dirp &= ~(1 << (31 - iopin->pin));
130 	} else if (iopin->port == IOPIN_PORTC) {
131 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdir;
132 		*dirp &= ~(1 << (15 - iopin->pin));
133 	} else if (iopin->port == IOPIN_PORTD) {
134 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddir;
135 		*dirp &= ~(1 << (15 - iopin->pin));
136 	}
137 }
138 
139 static __inline__ uint
140 iopin_is_out(iopin_t *iopin)
141 {
142 	if (iopin->port == IOPIN_PORTA) {
143 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padir;
144 		return (*dirp >> (15 - iopin->pin)) & 1;
145 	} else if (iopin->port == IOPIN_PORTB) {
146 		volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdir;
147 		return (*dirp >> (31 - iopin->pin)) & 1;
148 	} else if (iopin->port == IOPIN_PORTC) {
149 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdir;
150 		return (*dirp >> (15 - iopin->pin)) & 1;
151 	} else if (iopin->port == IOPIN_PORTD) {
152 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddir;
153 		return (*dirp >> (15 - iopin->pin)) & 1;
154 	}
155 	return 0;
156 }
157 
158 static __inline__ uint
159 iopin_is_in(iopin_t *iopin)
160 {
161 	if (iopin->port == IOPIN_PORTA) {
162 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_padir;
163 		return ((*dirp >> (15 - iopin->pin)) & 1) ^ 1;
164 	} else if (iopin->port == IOPIN_PORTB) {
165 		volatile uint *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbdir;
166 		return ((*dirp >> (31 - iopin->pin)) & 1) ^ 1;
167 	} else if (iopin->port == IOPIN_PORTC) {
168 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcdir;
169 		return ((*dirp >> (15 - iopin->pin)) & 1) ^ 1;
170 	} else if (iopin->port == IOPIN_PORTD) {
171 		volatile ushort *dirp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddir;
172 		return ((*dirp >> (15 - iopin->pin)) & 1) ^ 1;
173 	}
174 	return 0;
175 }
176 
177 static __inline__ void
178 iopin_set_odr(iopin_t *iopin)
179 {
180 	if (iopin->port == IOPIN_PORTA) {
181 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_paodr;
182 		*odrp |= (1 << (15 - iopin->pin));
183 	} else if (iopin->port == IOPIN_PORTB) {
184 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbodr;
185 		*odrp |= (1 << (31 - iopin->pin));
186 	}
187 }
188 
189 static __inline__ void
190 iopin_set_act(iopin_t *iopin)
191 {
192 	if (iopin->port == IOPIN_PORTA) {
193 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_paodr;
194 		*odrp &= ~(1 << (15 - iopin->pin));
195 	} else if (iopin->port == IOPIN_PORTB) {
196 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbodr;
197 		*odrp &= ~(1 << (31 - iopin->pin));
198 	}
199 }
200 
201 static __inline__ uint
202 iopin_is_odr(iopin_t *iopin)
203 {
204 	if (iopin->port == IOPIN_PORTA) {
205 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_paodr;
206 		return (*odrp >> (15 - iopin->pin)) & 1;
207 	} else if (iopin->port == IOPIN_PORTB) {
208 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbodr;
209 		return (*odrp >> (31 - iopin->pin)) & 1;
210 	}
211 	return 0;
212 }
213 
214 static __inline__ uint
215 iopin_is_act(iopin_t *iopin)
216 {
217 	if (iopin->port == IOPIN_PORTA) {
218 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_paodr;
219 		return ((*odrp >> (15 - iopin->pin)) & 1) ^ 1;
220 	} else if (iopin->port == IOPIN_PORTB) {
221 		volatile ushort *odrp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbodr;
222 		return ((*odrp >> (31 - iopin->pin)) & 1) ^ 1;
223 	}
224 	return 0;
225 }
226 
227 static __inline__ void
228 iopin_set_ded(iopin_t *iopin)
229 {
230 	if (iopin->port == IOPIN_PORTA) {
231 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_papar;
232 		*parp |= (1 << (15 - iopin->pin));
233 	} else if (iopin->port == IOPIN_PORTB) {
234 		volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbpar;
235 		*parp |= (1 << (31 - iopin->pin));
236 	} else if (iopin->port == IOPIN_PORTC) {
237 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcpar;
238 		*parp |= (1 << (15 - iopin->pin));
239 	} else if (iopin->port == IOPIN_PORTD) {
240 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdpar;
241 		*parp |= (1 << (15 - iopin->pin));
242 	}
243 }
244 
245 static __inline__ void
246 iopin_set_gen(iopin_t *iopin)
247 {
248 	if (iopin->port == IOPIN_PORTA) {
249 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_papar;
250 		*parp &= ~(1 << (15 - iopin->pin));
251 	} else if (iopin->port == IOPIN_PORTB) {
252 		volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbpar;
253 		*parp &= ~(1 << (31 - iopin->pin));
254 	} else if (iopin->port == IOPIN_PORTC) {
255 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcpar;
256 		*parp &= ~(1 << (15 - iopin->pin));
257 	} else if (iopin->port == IOPIN_PORTD) {
258 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdpar;
259 		*parp &= ~(1 << (15 - iopin->pin));
260 	}
261 }
262 
263 static __inline__ uint
264 iopin_is_ded(iopin_t *iopin)
265 {
266 	if (iopin->port == IOPIN_PORTA) {
267 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_papar;
268 		return (*parp >> (15 - iopin->pin)) & 1;
269 	} else if (iopin->port == IOPIN_PORTB) {
270 		volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbpar;
271 		return (*parp >> (31 - iopin->pin)) & 1;
272 	} else if (iopin->port == IOPIN_PORTC) {
273 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcpar;
274 		return (*parp >> (15 - iopin->pin)) & 1;
275 	} else if (iopin->port == IOPIN_PORTD) {
276 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdpar;
277 		return (*parp >> (15 - iopin->pin)) & 1;
278 	}
279 	return 0;
280 }
281 
282 static __inline__ uint
283 iopin_is_gen(iopin_t *iopin)
284 {
285 	if (iopin->port == IOPIN_PORTA) {
286 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_papar;
287 		return ((*parp >> (15 - iopin->pin)) & 1) ^ 1;
288 	} else if (iopin->port == IOPIN_PORTB) {
289 		volatile uint *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_pbpar;
290 		return ((*parp >> (31 - iopin->pin)) & 1) ^ 1;
291 	} else if (iopin->port == IOPIN_PORTC) {
292 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcpar;
293 		return ((*parp >> (15 - iopin->pin)) & 1) ^ 1;
294 	} else if (iopin->port == IOPIN_PORTD) {
295 		volatile ushort *parp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdpar;
296 		return ((*parp >> (15 - iopin->pin)) & 1) ^ 1;
297 	}
298 	return 0;
299 }
300 
301 static __inline__ void
302 iopin_set_opt2(iopin_t *iopin)
303 {
304 	if (iopin->port == IOPIN_PORTC) {
305 		volatile ushort *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcso;
306 		*sorp |= (1 << (15 - iopin->pin));
307 	}
308 }
309 
310 static __inline__ void
311 iopin_set_opt1(iopin_t *iopin)
312 {
313 	if (iopin->port == IOPIN_PORTC) {
314 		volatile ushort *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcso;
315 		*sorp &= ~(1 << (15 - iopin->pin));
316 	}
317 }
318 
319 static __inline__ uint
320 iopin_is_opt2(iopin_t *iopin)
321 {
322 	if (iopin->port == IOPIN_PORTC) {
323 		volatile ushort *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcso;
324 		return (*sorp >> (15 - iopin->pin)) & 1;
325 	}
326 	return 0;
327 }
328 
329 static __inline__ uint
330 iopin_is_opt1(iopin_t *iopin)
331 {
332 	if (iopin->port == IOPIN_PORTC) {
333 		volatile ushort *sorp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcso;
334 		return ((*sorp >> (15 - iopin->pin)) & 1) ^ 1;
335 	}
336 	return 0;
337 }
338 
339 static __inline__ void
340 iopin_set_falledge(iopin_t *iopin)
341 {
342 	if (iopin->port == IOPIN_PORTC) {
343 		volatile ushort *intp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcint;
344 		*intp |= (1 << (15 - iopin->pin));
345 	}
346 }
347 
348 static __inline__ void
349 iopin_set_anyedge(iopin_t *iopin)
350 {
351 	if (iopin->port == IOPIN_PORTC) {
352 		volatile ushort *intp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcint;
353 		*intp &= ~(1 << (15 - iopin->pin));
354 	}
355 }
356 
357 static __inline__ uint
358 iopin_is_falledge(iopin_t *iopin)
359 {
360 	if (iopin->port == IOPIN_PORTC) {
361 		volatile ushort *intp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcint;
362 		return (*intp >> (15 - iopin->pin)) & 1;
363 	}
364 	return 0;
365 }
366 
367 static __inline__ uint
368 iopin_is_anyedge(iopin_t *iopin)
369 {
370 	if (iopin->port == IOPIN_PORTC) {
371 		volatile ushort *intp = &((immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pcint;
372 		return ((*intp >> (15 - iopin->pin)) & 1) ^ 1;
373 	}
374 	return 0;
375 }
376 
377 #endif /* __KERNEL__ */
378 
379 #endif /* _ASM_IOPIN_8XX_H_ */
380