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 #include <asm/io.h>
16 
17 #ifdef __KERNEL__
18 
19 typedef struct {
20 	u_char port:2;	/* port number (A=0, B=1, C=2, D=3) */
21 	u_char pin:5;	/* port pin (0-31) */
22 	u_char flag:1;	/* for whatever */
23 } iopin_t;
24 
25 #define IOPIN_PORTA	0
26 #define IOPIN_PORTB	1
27 #define IOPIN_PORTC	2
28 #define IOPIN_PORTD	3
29 
30 static inline void iopin_set_high(iopin_t *iopin)
31 {
32 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
33 
34 	if (iopin->port == IOPIN_PORTA) {
35 		ushort __iomem *datp = &immap->im_ioport.iop_padat;
36 
37 		setbits_be16(datp, 1 << (15 - iopin->pin));
38 	} else if (iopin->port == IOPIN_PORTB) {
39 		uint __iomem *datp = &immap->im_cpm.cp_pbdat;
40 
41 		setbits_be32(datp, 1 << (31 - iopin->pin));
42 	} else if (iopin->port == IOPIN_PORTC) {
43 		ushort __iomem *datp = &immap->im_ioport.iop_pcdat;
44 
45 		setbits_be16(datp, 1 << (15 - iopin->pin));
46 	} else if (iopin->port == IOPIN_PORTD) {
47 		ushort __iomem *datp = &immap->im_ioport.iop_pddat;
48 
49 		setbits_be16(datp, 1 << (15 - iopin->pin));
50 	}
51 }
52 
53 static inline void iopin_set_low(iopin_t *iopin)
54 {
55 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
56 
57 	if (iopin->port == IOPIN_PORTA) {
58 		ushort __iomem *datp = &immap->im_ioport.iop_padat;
59 
60 		clrbits_be16(datp, 1 << (15 - iopin->pin));
61 	} else if (iopin->port == IOPIN_PORTB) {
62 		uint __iomem *datp = &immap->im_cpm.cp_pbdat;
63 
64 		clrbits_be32(datp, 1 << (31 - iopin->pin));
65 	} else if (iopin->port == IOPIN_PORTC) {
66 		ushort __iomem *datp = &immap->im_ioport.iop_pcdat;
67 
68 		clrbits_be16(datp, 1 << (15 - iopin->pin));
69 	} else if (iopin->port == IOPIN_PORTD) {
70 		ushort __iomem *datp = &immap->im_ioport.iop_pddat;
71 
72 		clrbits_be16(datp, 1 << (15 - iopin->pin));
73 	}
74 }
75 
76 static inline uint iopin_is_high(iopin_t *iopin)
77 {
78 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
79 
80 	if (iopin->port == IOPIN_PORTA) {
81 		ushort __iomem *datp = &immap->im_ioport.iop_padat;
82 
83 		return (in_be16(datp) >> (15 - iopin->pin)) & 1;
84 	} else if (iopin->port == IOPIN_PORTB) {
85 		uint __iomem *datp = &immap->im_cpm.cp_pbdat;
86 
87 		return (in_be32(datp) >> (31 - iopin->pin)) & 1;
88 	} else if (iopin->port == IOPIN_PORTC) {
89 		ushort __iomem *datp = &immap->im_ioport.iop_pcdat;
90 
91 		return (in_be16(datp) >> (15 - iopin->pin)) & 1;
92 	} else if (iopin->port == IOPIN_PORTD) {
93 		ushort __iomem *datp = &immap->im_ioport.iop_pddat;
94 
95 		return (in_be16(datp) >> (15 - iopin->pin)) & 1;
96 	}
97 	return 0;
98 }
99 
100 static inline uint iopin_is_low(iopin_t *iopin)
101 {
102 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
103 
104 	if (iopin->port == IOPIN_PORTA) {
105 		ushort __iomem *datp = &immap->im_ioport.iop_padat;
106 
107 		return ((in_be16(datp) >> (15 - iopin->pin)) & 1) ^ 1;
108 	} else if (iopin->port == IOPIN_PORTB) {
109 		uint __iomem *datp = &immap->im_cpm.cp_pbdat;
110 
111 		return ((in_be32(datp) >> (31 - iopin->pin)) & 1) ^ 1;
112 	} else if (iopin->port == IOPIN_PORTC) {
113 		ushort __iomem *datp = &immap->im_ioport.iop_pcdat;
114 
115 		return ((in_be16(datp) >> (15 - iopin->pin)) & 1) ^ 1;
116 	} else if (iopin->port == IOPIN_PORTD) {
117 		ushort __iomem *datp = &immap->im_ioport.iop_pddat;
118 
119 		return ((in_be16(datp) >> (15 - iopin->pin)) & 1) ^ 1;
120 	}
121 	return 0;
122 }
123 
124 static inline void iopin_set_out(iopin_t *iopin)
125 {
126 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
127 
128 	if (iopin->port == IOPIN_PORTA) {
129 		ushort __iomem *dirp = &immap->im_ioport.iop_padir;
130 
131 		setbits_be16(dirp, 1 << (15 - iopin->pin));
132 	} else if (iopin->port == IOPIN_PORTB) {
133 		uint __iomem *dirp = &immap->im_cpm.cp_pbdir;
134 
135 		setbits_be32(dirp, 1 << (31 - iopin->pin));
136 	} else if (iopin->port == IOPIN_PORTC) {
137 		ushort __iomem *dirp = &immap->im_ioport.iop_pcdir;
138 
139 		setbits_be16(dirp, 1 << (15 - iopin->pin));
140 	} else if (iopin->port == IOPIN_PORTD) {
141 		ushort __iomem *dirp = &immap->im_ioport.iop_pddir;
142 
143 		setbits_be16(dirp, 1 << (15 - iopin->pin));
144 	}
145 }
146 
147 static inline void iopin_set_in(iopin_t *iopin)
148 {
149 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
150 
151 	if (iopin->port == IOPIN_PORTA) {
152 		ushort __iomem *dirp = &immap->im_ioport.iop_padir;
153 
154 		clrbits_be16(dirp, 1 << (15 - iopin->pin));
155 	} else if (iopin->port == IOPIN_PORTB) {
156 		uint __iomem *dirp = &immap->im_cpm.cp_pbdir;
157 
158 		clrbits_be32(dirp, 1 << (31 - iopin->pin));
159 	} else if (iopin->port == IOPIN_PORTC) {
160 		ushort __iomem *dirp = &immap->im_ioport.iop_pcdir;
161 
162 		clrbits_be16(dirp, 1 << (15 - iopin->pin));
163 	} else if (iopin->port == IOPIN_PORTD) {
164 		ushort __iomem *dirp = &immap->im_ioport.iop_pddir;
165 
166 		clrbits_be16(dirp, 1 << (15 - iopin->pin));
167 	}
168 }
169 
170 static inline uint iopin_is_out(iopin_t *iopin)
171 {
172 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
173 
174 	if (iopin->port == IOPIN_PORTA) {
175 		ushort __iomem *dirp = &immap->im_ioport.iop_padir;
176 
177 		return (in_be16(dirp) >> (15 - iopin->pin)) & 1;
178 	} else if (iopin->port == IOPIN_PORTB) {
179 		uint __iomem *dirp = &immap->im_cpm.cp_pbdir;
180 
181 		return (in_be32(dirp) >> (31 - iopin->pin)) & 1;
182 	} else if (iopin->port == IOPIN_PORTC) {
183 		ushort __iomem *dirp = &immap->im_ioport.iop_pcdir;
184 
185 		return (in_be16(dirp) >> (15 - iopin->pin)) & 1;
186 	} else if (iopin->port == IOPIN_PORTD) {
187 		ushort __iomem *dirp = &immap->im_ioport.iop_pddir;
188 
189 		return (in_be16(dirp) >> (15 - iopin->pin)) & 1;
190 	}
191 	return 0;
192 }
193 
194 static inline uint iopin_is_in(iopin_t *iopin)
195 {
196 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
197 
198 	if (iopin->port == IOPIN_PORTA) {
199 		ushort __iomem *dirp = &immap->im_ioport.iop_padir;
200 
201 		return ((in_be16(dirp) >> (15 - iopin->pin)) & 1) ^ 1;
202 	} else if (iopin->port == IOPIN_PORTB) {
203 		uint __iomem *dirp = &immap->im_cpm.cp_pbdir;
204 
205 		return ((in_be32(dirp) >> (31 - iopin->pin)) & 1) ^ 1;
206 	} else if (iopin->port == IOPIN_PORTC) {
207 		ushort __iomem *dirp = &immap->im_ioport.iop_pcdir;
208 
209 		return ((in_be16(dirp) >> (15 - iopin->pin)) & 1) ^ 1;
210 	} else if (iopin->port == IOPIN_PORTD) {
211 		ushort __iomem *dirp = &immap->im_ioport.iop_pddir;
212 
213 		return ((in_be16(dirp) >> (15 - iopin->pin)) & 1) ^ 1;
214 	}
215 	return 0;
216 }
217 
218 static inline void iopin_set_odr(iopin_t *iopin)
219 {
220 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
221 
222 	if (iopin->port == IOPIN_PORTA) {
223 		ushort __iomem *odrp = &immap->im_ioport.iop_paodr;
224 
225 		setbits_be16(odrp, 1 << (15 - iopin->pin));
226 	} else if (iopin->port == IOPIN_PORTB) {
227 		ushort __iomem *odrp = &immap->im_cpm.cp_pbodr;
228 
229 		setbits_be16(odrp, 1 << (31 - iopin->pin));
230 	}
231 }
232 
233 static inline void iopin_set_act(iopin_t *iopin)
234 {
235 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
236 
237 	if (iopin->port == IOPIN_PORTA) {
238 		ushort __iomem *odrp = &immap->im_ioport.iop_paodr;
239 
240 		clrbits_be16(odrp, 1 << (15 - iopin->pin));
241 	} else if (iopin->port == IOPIN_PORTB) {
242 		ushort __iomem *odrp = &immap->im_cpm.cp_pbodr;
243 
244 		clrbits_be16(odrp, 1 << (31 - iopin->pin));
245 	}
246 }
247 
248 static inline uint iopin_is_odr(iopin_t *iopin)
249 {
250 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
251 
252 	if (iopin->port == IOPIN_PORTA) {
253 		ushort __iomem *odrp = &immap->im_ioport.iop_paodr;
254 
255 		return (in_be16(odrp) >> (15 - iopin->pin)) & 1;
256 	} else if (iopin->port == IOPIN_PORTB) {
257 		ushort __iomem *odrp = &immap->im_cpm.cp_pbodr;
258 
259 		return (in_be16(odrp) >> (31 - iopin->pin)) & 1;
260 	}
261 	return 0;
262 }
263 
264 static inline uint iopin_is_act(iopin_t *iopin)
265 {
266 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
267 
268 	if (iopin->port == IOPIN_PORTA) {
269 		ushort __iomem *odrp = &immap->im_ioport.iop_paodr;
270 
271 		return ((in_be16(odrp) >> (15 - iopin->pin)) & 1) ^ 1;
272 	} else if (iopin->port == IOPIN_PORTB) {
273 		ushort __iomem *odrp = &immap->im_cpm.cp_pbodr;
274 
275 		return ((in_be16(odrp) >> (31 - iopin->pin)) & 1) ^ 1;
276 	}
277 	return 0;
278 }
279 
280 static inline void iopin_set_ded(iopin_t *iopin)
281 {
282 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
283 
284 	if (iopin->port == IOPIN_PORTA) {
285 		ushort __iomem *parp = &immap->im_ioport.iop_papar;
286 
287 		setbits_be16(parp, 1 << (15 - iopin->pin));
288 	} else if (iopin->port == IOPIN_PORTB) {
289 		uint __iomem *parp = &immap->im_cpm.cp_pbpar;
290 
291 		setbits_be32(parp, 1 << (31 - iopin->pin));
292 	} else if (iopin->port == IOPIN_PORTC) {
293 		ushort __iomem *parp = &immap->im_ioport.iop_pcpar;
294 
295 		setbits_be16(parp, 1 << (15 - iopin->pin));
296 	} else if (iopin->port == IOPIN_PORTD) {
297 		ushort __iomem *parp = &immap->im_ioport.iop_pdpar;
298 
299 		setbits_be16(parp, 1 << (15 - iopin->pin));
300 	}
301 }
302 
303 static inline void iopin_set_gen(iopin_t *iopin)
304 {
305 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
306 
307 	if (iopin->port == IOPIN_PORTA) {
308 		ushort __iomem *parp = &immap->im_ioport.iop_papar;
309 
310 		clrbits_be16(parp, 1 << (15 - iopin->pin));
311 	} else if (iopin->port == IOPIN_PORTB) {
312 		uint __iomem *parp = &immap->im_cpm.cp_pbpar;
313 
314 		clrbits_be32(parp, 1 << (31 - iopin->pin));
315 	} else if (iopin->port == IOPIN_PORTC) {
316 		ushort __iomem *parp = &immap->im_ioport.iop_pcpar;
317 
318 		clrbits_be16(parp, 1 << (15 - iopin->pin));
319 	} else if (iopin->port == IOPIN_PORTD) {
320 		ushort __iomem *parp = &immap->im_ioport.iop_pdpar;
321 
322 		clrbits_be16(parp, 1 << (15 - iopin->pin));
323 	}
324 }
325 
326 static inline uint iopin_is_ded(iopin_t *iopin)
327 {
328 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
329 
330 	if (iopin->port == IOPIN_PORTA) {
331 		ushort __iomem *parp = &immap->im_ioport.iop_papar;
332 
333 		return (in_be16(parp) >> (15 - iopin->pin)) & 1;
334 	} else if (iopin->port == IOPIN_PORTB) {
335 		uint __iomem *parp = &immap->im_cpm.cp_pbpar;
336 
337 		return (in_be32(parp) >> (31 - iopin->pin)) & 1;
338 	} else if (iopin->port == IOPIN_PORTC) {
339 		ushort __iomem *parp = &immap->im_ioport.iop_pcpar;
340 
341 		return (in_be16(parp) >> (15 - iopin->pin)) & 1;
342 	} else if (iopin->port == IOPIN_PORTD) {
343 		ushort __iomem *parp = &immap->im_ioport.iop_pdpar;
344 
345 		return (in_be16(parp) >> (15 - iopin->pin)) & 1;
346 	}
347 	return 0;
348 }
349 
350 static inline uint iopin_is_gen(iopin_t *iopin)
351 {
352 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
353 
354 	if (iopin->port == IOPIN_PORTA) {
355 		ushort __iomem *parp = &immap->im_ioport.iop_papar;
356 
357 		return ((in_be16(parp) >> (15 - iopin->pin)) & 1) ^ 1;
358 	} else if (iopin->port == IOPIN_PORTB) {
359 		uint __iomem *parp = &immap->im_cpm.cp_pbpar;
360 
361 		return ((in_be32(parp) >> (31 - iopin->pin)) & 1) ^ 1;
362 	} else if (iopin->port == IOPIN_PORTC) {
363 		ushort __iomem *parp = &immap->im_ioport.iop_pcpar;
364 
365 		return ((in_be16(parp) >> (15 - iopin->pin)) & 1) ^ 1;
366 	} else if (iopin->port == IOPIN_PORTD) {
367 		ushort __iomem *parp = &immap->im_ioport.iop_pdpar;
368 
369 		return ((in_be16(parp) >> (15 - iopin->pin)) & 1) ^ 1;
370 	}
371 	return 0;
372 }
373 
374 static inline void iopin_set_opt2(iopin_t *iopin)
375 {
376 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
377 
378 	if (iopin->port == IOPIN_PORTC) {
379 		ushort __iomem *sorp = &immap->im_ioport.iop_pcso;
380 
381 		setbits_be16(sorp, 1 << (15 - iopin->pin));
382 	}
383 }
384 
385 static inline void iopin_set_opt1(iopin_t *iopin)
386 {
387 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
388 
389 	if (iopin->port == IOPIN_PORTC) {
390 		ushort __iomem *sorp = &immap->im_ioport.iop_pcso;
391 
392 		clrbits_be16(sorp, 1 << (15 - iopin->pin));
393 	}
394 }
395 
396 static inline uint iopin_is_opt2(iopin_t *iopin)
397 {
398 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
399 
400 	if (iopin->port == IOPIN_PORTC) {
401 		ushort __iomem *sorp = &immap->im_ioport.iop_pcso;
402 
403 		return (in_be16(sorp) >> (15 - iopin->pin)) & 1;
404 	}
405 	return 0;
406 }
407 
408 static inline uint iopin_is_opt1(iopin_t *iopin)
409 {
410 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
411 
412 	if (iopin->port == IOPIN_PORTC) {
413 		ushort __iomem *sorp = &immap->im_ioport.iop_pcso;
414 
415 		return ((in_be16(sorp) >> (15 - iopin->pin)) & 1) ^ 1;
416 	}
417 	return 0;
418 }
419 
420 static inline void iopin_set_falledge(iopin_t *iopin)
421 {
422 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
423 
424 	if (iopin->port == IOPIN_PORTC) {
425 		ushort __iomem *intp = &immap->im_ioport.iop_pcint;
426 
427 		setbits_be16(intp, 1 << (15 - iopin->pin));
428 	}
429 }
430 
431 static inline void iopin_set_anyedge(iopin_t *iopin)
432 {
433 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
434 
435 	if (iopin->port == IOPIN_PORTC) {
436 		ushort __iomem *intp = &immap->im_ioport.iop_pcint;
437 
438 		clrbits_be16(intp, 1 << (15 - iopin->pin));
439 	}
440 }
441 
442 static inline uint iopin_is_falledge(iopin_t *iopin)
443 {
444 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
445 
446 	if (iopin->port == IOPIN_PORTC) {
447 		ushort __iomem *intp = &immap->im_ioport.iop_pcint;
448 
449 		return (in_be16(intp) >> (15 - iopin->pin)) & 1;
450 	}
451 	return 0;
452 }
453 
454 static inline uint iopin_is_anyedge(iopin_t *iopin)
455 {
456 	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
457 
458 	if (iopin->port == IOPIN_PORTC) {
459 		ushort __iomem *intp = &immap->im_ioport.iop_pcint;
460 
461 		return ((in_be16(intp) >> (15 - iopin->pin)) & 1) ^ 1;
462 	}
463 	return 0;
464 }
465 
466 #endif /* __KERNEL__ */
467 
468 #endif /* _ASM_IOPIN_8XX_H_ */
469