broadcom-diag: add support for bcma
[openwrt/svn-archive/archive.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 */