xref: /linux/arch/mips/include/asm/mach-au1x00/gpio-au1300.h (revision cdd5b5a9761fd66d17586e4f4ba6588c70e640ea)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * gpio-au1300.h -- GPIO control for Au1300 GPIC and compatibles.
4  *
5  * Copyright (c) 2009-2011 Manuel Lauss <manuel.lauss@googlemail.com>
6  */
7 
8 #ifndef _GPIO_AU1300_H_
9 #define _GPIO_AU1300_H_
10 
11 #include <asm/addrspace.h>
12 #include <asm/io.h>
13 #include <asm/mach-au1x00/au1000.h>
14 
15 struct gpio;
16 struct gpio_chip;
17 
18 /* with the current GPIC design, up to 128 GPIOs are possible.
19  * The only implementation so far is in the Au1300, which has 75 externally
20  * available GPIOs.
21  */
22 #define AU1300_GPIO_BASE	0
23 #define AU1300_GPIO_NUM		75
24 #define AU1300_GPIO_MAX		(AU1300_GPIO_BASE + AU1300_GPIO_NUM - 1)
25 
26 #define AU1300_GPIC_ADDR	\
27 	(void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR)
28 
au1300_gpio_get_value(unsigned int gpio)29 static inline int au1300_gpio_get_value(unsigned int gpio)
30 {
31 	void __iomem *roff = AU1300_GPIC_ADDR;
32 	int bit;
33 
34 	gpio -= AU1300_GPIO_BASE;
35 	roff += GPIC_GPIO_BANKOFF(gpio);
36 	bit = GPIC_GPIO_TO_BIT(gpio);
37 	return __raw_readl(roff + AU1300_GPIC_PINVAL) & bit;
38 }
39 
au1300_gpio_direction_input(unsigned int gpio)40 static inline int au1300_gpio_direction_input(unsigned int gpio)
41 {
42 	void __iomem *roff = AU1300_GPIC_ADDR;
43 	unsigned long bit;
44 
45 	gpio -= AU1300_GPIO_BASE;
46 
47 	roff += GPIC_GPIO_BANKOFF(gpio);
48 	bit = GPIC_GPIO_TO_BIT(gpio);
49 	__raw_writel(bit, roff + AU1300_GPIC_DEVCLR);
50 	wmb();
51 
52 	return 0;
53 }
54 
au1300_gpio_set_value(unsigned int gpio,int v)55 static inline int au1300_gpio_set_value(unsigned int gpio, int v)
56 {
57 	void __iomem *roff = AU1300_GPIC_ADDR;
58 	unsigned long bit;
59 
60 	gpio -= AU1300_GPIO_BASE;
61 
62 	roff += GPIC_GPIO_BANKOFF(gpio);
63 	bit = GPIC_GPIO_TO_BIT(gpio);
64 	__raw_writel(bit, roff + (v ? AU1300_GPIC_PINVAL
65 				    : AU1300_GPIC_PINVALCLR));
66 	wmb();
67 
68 	return 0;
69 }
70 
au1300_gpio_direction_output(unsigned int gpio,int v)71 static inline int au1300_gpio_direction_output(unsigned int gpio, int v)
72 {
73 	/* hw switches to output automatically */
74 	return au1300_gpio_set_value(gpio, v);
75 }
76 
au1300_gpio_to_irq(unsigned int gpio)77 static inline int au1300_gpio_to_irq(unsigned int gpio)
78 {
79 	return AU1300_FIRST_INT + (gpio - AU1300_GPIO_BASE);
80 }
81 
au1300_irq_to_gpio(unsigned int irq)82 static inline int au1300_irq_to_gpio(unsigned int irq)
83 {
84 	return (irq - AU1300_FIRST_INT) + AU1300_GPIO_BASE;
85 }
86 
au1300_gpio_is_valid(unsigned int gpio)87 static inline int au1300_gpio_is_valid(unsigned int gpio)
88 {
89 	int ret;
90 
91 	switch (alchemy_get_cputype()) {
92 	case ALCHEMY_CPU_AU1300:
93 		ret = ((gpio >= AU1300_GPIO_BASE) && (gpio <= AU1300_GPIO_MAX));
94 		break;
95 	default:
96 		ret = 0;
97 	}
98 	return ret;
99 }
100 
101 /* hardware remembers gpio 0-63 levels on powerup */
au1300_gpio_getinitlvl(unsigned int gpio)102 static inline int au1300_gpio_getinitlvl(unsigned int gpio)
103 {
104 	void __iomem *roff = AU1300_GPIC_ADDR;
105 	unsigned long v;
106 
107 	if (unlikely(gpio > 63))
108 		return 0;
109 	else if (gpio > 31) {
110 		gpio -= 32;
111 		roff += 4;
112 	}
113 
114 	v = __raw_readl(roff + AU1300_GPIC_RSTVAL);
115 	return (v >> gpio) & 1;
116 }
117 
118 #endif /* _GPIO_AU1300_H_ */
119