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