[scripts] ext-toolchain.sh: properly handle toolchains without sysroot support
[openwrt.git] / package / broadcom-diag / src / gpio.h
1 #ifndef __DIAG_GPIO_H
2 #define __DIAG_GPIO_H
3
4 #include <linux/interrupt.h>
5 #include <linux/ssb/ssb_embedded.h>
6 #include <linux/gpio.h>
7 #include <bcm47xx.h>
8
9 static inline u32 gpio_in(void)
10 {
11         switch (bcm47xx_bus_type) {
12 #ifdef CONFIG_BCM47XX_SSB
13         case BCM47XX_BUS_TYPE_SSB:
14                 return ssb_gpio_in(&bcm47xx_bus.ssb, ~0);
15 #endif
16 #ifdef CONFIG_BCM47XX_BCMA
17         case BCM47XX_BUS_TYPE_BCMA:
18                 return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc, ~0);
19 #endif
20         }
21         return -EINVAL;
22 }
23
24 static inline u32 gpio_out(u32 mask, u32 value)
25 {
26         switch (bcm47xx_bus_type) {
27 #ifdef CONFIG_BCM47XX_SSB
28         case BCM47XX_BUS_TYPE_SSB:
29                 return ssb_gpio_out(&bcm47xx_bus.ssb, mask, value);
30 #endif
31 #ifdef CONFIG_BCM47XX_BCMA
32         case BCM47XX_BUS_TYPE_BCMA:
33                 return bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, mask, value);
34 #endif
35         }
36         return -EINVAL;
37 }
38
39 static inline u32 gpio_outen(u32 mask, u32 value)
40 {
41         switch (bcm47xx_bus_type) {
42 #ifdef CONFIG_BCM47XX_SSB
43         case BCM47XX_BUS_TYPE_SSB:
44                 ssb_gpio_outen(&bcm47xx_bus.ssb, mask, value);
45                 return 0;
46 #endif
47 #ifdef CONFIG_BCM47XX_BCMA
48         case BCM47XX_BUS_TYPE_BCMA:
49                 bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, mask, value);
50                 return 0;
51 #endif
52         }
53         return -EINVAL;
54 }
55
56 static inline u32 gpio_control(u32 mask, u32 value)
57 {
58         switch (bcm47xx_bus_type) {
59 #ifdef CONFIG_BCM47XX_SSB
60         case BCM47XX_BUS_TYPE_SSB:
61                 return ssb_gpio_control(&bcm47xx_bus.ssb, mask, value);
62 #endif
63 #ifdef CONFIG_BCM47XX_BCMA
64         case BCM47XX_BUS_TYPE_BCMA:
65                 return bcma_chipco_gpio_control(&bcm47xx_bus.bcma.bus.drv_cc, mask, value);
66 #endif
67         }
68         return -EINVAL;
69 }
70
71 static inline u32 gpio_setintmask(u32 mask, u32 value)
72 {
73         switch (bcm47xx_bus_type) {
74 #ifdef CONFIG_BCM47XX_SSB
75         case BCM47XX_BUS_TYPE_SSB:
76                 return ssb_gpio_intmask(&bcm47xx_bus.ssb, mask, value);
77 #endif
78 #ifdef CONFIG_BCM47XX_BCMA
79         case BCM47XX_BUS_TYPE_BCMA:
80                 return bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc, mask, value);
81 #endif
82         }
83         return -EINVAL;
84 }
85
86 static inline u32 gpio_intpolarity(u32 mask, u32 value)
87 {
88         switch (bcm47xx_bus_type) {
89 #ifdef CONFIG_BCM47XX_SSB
90         case BCM47XX_BUS_TYPE_SSB:
91                 return ssb_gpio_polarity(&bcm47xx_bus.ssb, mask, value);
92 #endif
93 #ifdef CONFIG_BCM47XX_BCMA
94         case BCM47XX_BUS_TYPE_BCMA:
95                 return bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc, mask, value);
96 #endif
97         }
98         return -EINVAL;
99 }
100
101 #ifdef CONFIG_BCM47XX_SSB
102 static inline u32 __ssb_write32_masked(struct ssb_device *dev, u16 offset,
103                                        u32 mask, u32 value)
104 {
105         value &= mask;
106         value |= ssb_read32(dev, offset) & ~mask;
107         ssb_write32(dev, offset, value);
108         return value;
109 }
110 #endif
111
112 #ifdef CONFIG_BCM47XX_BCMA
113 static inline u32 __bcma_write32_masked(struct bcma_device *dev, u16 offset,
114                                        u32 mask, u32 value)
115 {
116         value &= mask;
117         value |= bcma_read32(dev, offset) & ~mask;
118         bcma_write32(dev, offset, value);
119         return value;
120 }
121 #endif
122
123 static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *))
124 {
125         int irq;
126
127         irq = gpio_to_irq(0);
128         if (irq == -EINVAL) return;
129         
130         if (enabled) {
131                 if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler))
132                         return;
133         } else {
134                 free_irq(irq, handler);
135         }
136
137         switch (bcm47xx_bus_type) {
138 #ifdef CONFIG_BCM47XX_SSB
139         case BCM47XX_BUS_TYPE_SSB:
140                 if (bcm47xx_bus.ssb.chipco.dev)
141                         __ssb_write32_masked(bcm47xx_bus.ssb.chipco.dev, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0));
142 #endif
143 #ifdef CONFIG_BCM47XX_BCMA
144         case BCM47XX_BUS_TYPE_BCMA:
145                 if (bcm47xx_bus.bcma.bus.drv_cc.core)
146                         __bcma_write32_masked(bcm47xx_bus.bcma.bus.drv_cc.core, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO, (enabled ? BCMA_CC_IRQ_GPIO : 0));
147 #endif
148         }
149 }
150
151 #define EXTIF_ADDR 0x1f000000
152 #define EXTIF_UART (EXTIF_ADDR + 0x00800000)
153
154 #define GPIO_TYPE_NORMAL        (0x0 << 24)
155 #define GPIO_TYPE_EXTIF         (0x1 << 24)
156 #define GPIO_TYPE_MASK          (0xf << 24)
157
158 static inline void gpio_set_extif(int gpio, int value)
159 {
160         volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (gpio & ~GPIO_TYPE_MASK);
161         if (value)
162                 *addr = 0xFF;
163         else
164                 *addr;
165 }
166
167 #endif /* __DIAG_GPIO_H */