1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
7  */
8 
9 #ifndef __BCM47XX_GPIO_H
10 #define __BCM47XX_GPIO_H
11 
12 #include <linux/ssb/ssb_embedded.h>
13 #include <linux/bcma/bcma.h>
14 #include <asm/mach-bcm47xx/bcm47xx.h>
15 
16 #define BCM47XX_EXTIF_GPIO_LINES	5
17 #define BCM47XX_CHIPCO_GPIO_LINES	16
18 
19 extern int gpio_request(unsigned gpio, const char *label);
20 extern void gpio_free(unsigned gpio);
21 extern int gpio_to_irq(unsigned gpio);
22 
gpio_get_value(unsigned gpio)23 static inline int gpio_get_value(unsigned gpio)
24 {
25 	switch (bcm47xx_bus_type) {
26 #ifdef CONFIG_BCM47XX_SSB
27 	case BCM47XX_BUS_TYPE_SSB:
28 		return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
29 #endif
30 #ifdef CONFIG_BCM47XX_BCMA
31 	case BCM47XX_BUS_TYPE_BCMA:
32 		return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
33 					   1 << gpio);
34 #endif
35 	}
36 	return -EINVAL;
37 }
38 
39 #define gpio_get_value_cansleep	gpio_get_value
40 
gpio_set_value(unsigned gpio,int value)41 static inline void gpio_set_value(unsigned gpio, int value)
42 {
43 	switch (bcm47xx_bus_type) {
44 #ifdef CONFIG_BCM47XX_SSB
45 	case BCM47XX_BUS_TYPE_SSB:
46 		ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
47 			     value ? 1 << gpio : 0);
48 		return;
49 #endif
50 #ifdef CONFIG_BCM47XX_BCMA
51 	case BCM47XX_BUS_TYPE_BCMA:
52 		bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
53 				     value ? 1 << gpio : 0);
54 		return;
55 #endif
56 	}
57 }
58 
59 #define gpio_set_value_cansleep gpio_set_value
60 
gpio_cansleep(unsigned gpio)61 static inline int gpio_cansleep(unsigned gpio)
62 {
63 	return 0;
64 }
65 
gpio_is_valid(unsigned gpio)66 static inline int gpio_is_valid(unsigned gpio)
67 {
68 	return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES);
69 }
70 
71 
gpio_direction_input(unsigned gpio)72 static inline int gpio_direction_input(unsigned gpio)
73 {
74 	switch (bcm47xx_bus_type) {
75 #ifdef CONFIG_BCM47XX_SSB
76 	case BCM47XX_BUS_TYPE_SSB:
77 		ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
78 		return 0;
79 #endif
80 #ifdef CONFIG_BCM47XX_BCMA
81 	case BCM47XX_BUS_TYPE_BCMA:
82 		bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
83 				       0);
84 		return 0;
85 #endif
86 	}
87 	return -EINVAL;
88 }
89 
gpio_direction_output(unsigned gpio,int value)90 static inline int gpio_direction_output(unsigned gpio, int value)
91 {
92 	switch (bcm47xx_bus_type) {
93 #ifdef CONFIG_BCM47XX_SSB
94 	case BCM47XX_BUS_TYPE_SSB:
95 		/* first set the gpio out value */
96 		ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
97 			     value ? 1 << gpio : 0);
98 		/* then set the gpio mode */
99 		ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
100 		return 0;
101 #endif
102 #ifdef CONFIG_BCM47XX_BCMA
103 	case BCM47XX_BUS_TYPE_BCMA:
104 		/* first set the gpio out value */
105 		bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
106 				     value ? 1 << gpio : 0);
107 		/* then set the gpio mode */
108 		bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
109 				       1 << gpio);
110 		return 0;
111 #endif
112 	}
113 	return -EINVAL;
114 }
115 
gpio_intmask(unsigned gpio,int value)116 static inline int gpio_intmask(unsigned gpio, int value)
117 {
118 	switch (bcm47xx_bus_type) {
119 #ifdef CONFIG_BCM47XX_SSB
120 	case BCM47XX_BUS_TYPE_SSB:
121 		ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
122 				 value ? 1 << gpio : 0);
123 		return 0;
124 #endif
125 #ifdef CONFIG_BCM47XX_BCMA
126 	case BCM47XX_BUS_TYPE_BCMA:
127 		bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
128 					 1 << gpio, value ? 1 << gpio : 0);
129 		return 0;
130 #endif
131 	}
132 	return -EINVAL;
133 }
134 
gpio_polarity(unsigned gpio,int value)135 static inline int gpio_polarity(unsigned gpio, int value)
136 {
137 	switch (bcm47xx_bus_type) {
138 #ifdef CONFIG_BCM47XX_SSB
139 	case BCM47XX_BUS_TYPE_SSB:
140 		ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
141 				  value ? 1 << gpio : 0);
142 		return 0;
143 #endif
144 #ifdef CONFIG_BCM47XX_BCMA
145 	case BCM47XX_BUS_TYPE_BCMA:
146 		bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
147 					  1 << gpio, value ? 1 << gpio : 0);
148 		return 0;
149 #endif
150 	}
151 	return -EINVAL;
152 }
153 
154 
155 #endif /* __BCM47XX_GPIO_H */
156