| 1 | #ifndef __DIAG_GPIO_H |
| 2 | #define __DIAG_GPIO_H |
| 3 | #include <linux/interrupt.h> |
| 4 | |
| 5 | #ifndef BCMDRIVER |
| 6 | #include <linux/ssb/ssb_embedded.h> |
| 7 | |
| 8 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) |
| 9 | #include <linux/gpio.h> |
| 10 | #define ssb ssb_bcm47xx |
| 11 | #endif |
| 12 | extern struct ssb_bus ssb; |
| 13 | |
| 14 | |
| 15 | static inline u32 gpio_in(void) |
| 16 | { |
| 17 | return ssb_gpio_in(&ssb, ~0); |
| 18 | } |
| 19 | |
| 20 | static inline u32 gpio_out(u32 mask, u32 value) |
| 21 | { |
| 22 | return ssb_gpio_out(&ssb, mask, value); |
| 23 | } |
| 24 | |
| 25 | static inline u32 gpio_outen(u32 mask, u32 value) |
| 26 | { |
| 27 | return ssb_gpio_outen(&ssb, mask, value); |
| 28 | } |
| 29 | |
| 30 | static inline u32 gpio_control(u32 mask, u32 value) |
| 31 | { |
| 32 | return ssb_gpio_control(&ssb, mask, value); |
| 33 | } |
| 34 | |
| 35 | static inline u32 gpio_setintmask(u32 mask, u32 value) |
| 36 | { |
| 37 | return ssb_gpio_intmask(&ssb, mask, value); |
| 38 | } |
| 39 | |
| 40 | static inline u32 gpio_intpolarity(u32 mask, u32 value) |
| 41 | { |
| 42 | return ssb_gpio_polarity(&ssb, mask, value); |
| 43 | } |
| 44 | |
| 45 | static inline u32 __ssb_write32_masked(struct ssb_device *dev, u16 offset, |
| 46 | u32 mask, u32 value) |
| 47 | { |
| 48 | value &= mask; |
| 49 | value |= ssb_read32(dev, offset) & ~mask; |
| 50 | ssb_write32(dev, offset, value); |
| 51 | return value; |
| 52 | } |
| 53 | |
| 54 | static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *)) |
| 55 | { |
| 56 | int irq; |
| 57 | |
| 58 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) |
| 59 | irq = gpio_to_irq(0); |
| 60 | if (irq == -EINVAL) return; |
| 61 | #else |
| 62 | if (ssb.chipco.dev) |
| 63 | irq = ssb_mips_irq(ssb.chipco.dev) + 2; |
| 64 | else if (ssb.extif.dev) |
| 65 | irq = ssb_mips_irq(ssb.extif.dev) + 2; |
| 66 | else return; |
| 67 | #endif |
| 68 | |
| 69 | if (enabled) { |
| 70 | if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler)) |
| 71 | return; |
| 72 | } else { |
| 73 | free_irq(irq, handler); |
| 74 | } |
| 75 | |
| 76 | if (ssb.chipco.dev) |
| 77 | __ssb_write32_masked(ssb.chipco.dev, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0)); |
| 78 | } |
| 79 | |
| 80 | #else |
| 81 | |
| 82 | #include <typedefs.h> |
| 83 | #include <osl.h> |
| 84 | #include <bcmdevs.h> |
| 85 | #include <sbutils.h> |
| 86 | #include <sbconfig.h> |
| 87 | #include <sbchipc.h> |
| 88 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
| 89 | #include <sbmips.h> |
| 90 | #else |
| 91 | #include <hndcpu.h> |
| 92 | #endif |
| 93 | |
| 94 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) |
| 95 | #define sbh bcm947xx_sbh |
| 96 | #define sbh_lock bcm947xx_sbh_lock |
| 97 | #endif |
| 98 | |
| 99 | extern void *sbh; |
| 100 | extern spinlock_t sbh_lock; |
| 101 | |
| 102 | #define gpio_in() sb_gpioin(sbh) |
| 103 | #define gpio_out(mask, value) sb_gpioout(sbh, mask, ((value) & (mask)), GPIO_DRV_PRIORITY) |
| 104 | #define gpio_outen(mask, value) sb_gpioouten(sbh, mask, value, GPIO_DRV_PRIORITY) |
| 105 | #define gpio_control(mask, value) sb_gpiocontrol(sbh, mask, value, GPIO_DRV_PRIORITY) |
| 106 | #define gpio_setintmask(mask, value) sb_gpiointmask(sbh, mask, value, GPIO_DRV_PRIORITY) |
| 107 | #define gpio_intpolarity(mask, value) sb_gpiointpolarity(sbh, mask, value, GPIO_DRV_PRIORITY) |
| 108 | |
| 109 | static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *, struct pt_regs *)) |
| 110 | { |
| 111 | unsigned int coreidx; |
| 112 | unsigned long flags; |
| 113 | chipcregs_t *cc; |
| 114 | int irq; |
| 115 | |
| 116 | spin_lock_irqsave(sbh_lock, flags); |
| 117 | coreidx = sb_coreidx(sbh); |
| 118 | |
| 119 | irq = sb_irq(sbh) + 2; |
| 120 | if (enabled) |
| 121 | request_irq(irq, handler, SA_SHIRQ | SA_SAMPLE_RANDOM, "gpio", handler); |
| 122 | else |
| 123 | free_irq(irq, handler); |
| 124 | |
| 125 | if ((cc = sb_setcore(sbh, SB_CC, 0))) { |
| 126 | int intmask; |
| 127 | |
| 128 | intmask = readl(&cc->intmask); |
| 129 | if (enabled) |
| 130 | intmask |= CI_GPIO; |
| 131 | else |
| 132 | intmask &= ~CI_GPIO; |
| 133 | writel(intmask, &cc->intmask); |
| 134 | } |
| 135 | sb_setcoreidx(sbh, coreidx); |
| 136 | spin_unlock_irqrestore(sbh_lock, flags); |
| 137 | } |
| 138 | |
| 139 | #endif /* BCMDRIVER */ |
| 140 | |
| 141 | #define EXTIF_ADDR 0x1f000000 |
| 142 | #define EXTIF_UART (EXTIF_ADDR + 0x00800000) |
| 143 | |
| 144 | #define GPIO_TYPE_NORMAL (0x0 << 24) |
| 145 | #define GPIO_TYPE_EXTIF (0x1 << 24) |
| 146 | #define GPIO_TYPE_MASK (0xf << 24) |
| 147 | |
| 148 | static inline void gpio_set_extif(int gpio, int value) |
| 149 | { |
| 150 | volatile u8 *addr = (volatile u8 *) KSEG1ADDR(EXTIF_UART) + (gpio & ~GPIO_TYPE_MASK); |
| 151 | if (value) |
| 152 | *addr = 0xFF; |
| 153 | else |
| 154 | *addr; |
| 155 | } |
| 156 | |
| 157 | #endif /* __DIAG_GPIO_H */ |
| 158 | |