Blame view
arch/mips/rb532/gpio.c
5.24 KB
73b4390fb [MIPS] Routerboar... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* * Miscellaneous functions for IDT EB434 board * * Copyright 2004 IDT Inc. (rischelp@idt.com) * Copyright 2006 Phil Sutter <n0-1@freewrt.org> * Copyright 2007 Florian Fainelli <florian@openwrt.org> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/kernel.h> |
73b4390fb [MIPS] Routerboar... |
30 31 |
#include <linux/init.h> #include <linux/types.h> |
cae39d138 mips: add export.... |
32 |
#include <linux/export.h> |
73b4390fb [MIPS] Routerboar... |
33 |
#include <linux/spinlock.h> |
73b4390fb [MIPS] Routerboar... |
34 |
#include <linux/platform_device.h> |
d888e25b8 MIPS: RB532: Conv... |
35 |
#include <linux/gpio.h> |
73b4390fb [MIPS] Routerboar... |
36 37 |
#include <asm/mach-rc32434/rb.h> |
d888e25b8 MIPS: RB532: Conv... |
38 39 40 41 42 |
#include <asm/mach-rc32434/gpio.h> struct rb532_gpio_chip { struct gpio_chip chip; void __iomem *regbase; |
d888e25b8 MIPS: RB532: Conv... |
43 |
}; |
73b4390fb [MIPS] Routerboar... |
44 |
|
73b4390fb [MIPS] Routerboar... |
45 46 47 |
static struct resource rb532_gpio_reg0_res[] = { { .name = "gpio_reg0", |
3c8cf8caa MIPS: RB532: Use ... |
48 49 |
.start = REGBASE + GPIOBASE, .end = REGBASE + GPIOBASE + sizeof(struct rb532_gpio_reg) - 1, |
73b4390fb [MIPS] Routerboar... |
50 51 52 |
.flags = IORESOURCE_MEM, } }; |
2e373952c MIPS: RB532: Prov... |
53 54 55 56 57 58 59 60 61 62 63 |
/* rb532_set_bit - sanely set a bit * * bitval: new value for the bit * offset: bit index in the 4 byte address range * ioaddr: 4 byte aligned address being altered */ static inline void rb532_set_bit(unsigned bitval, unsigned offset, void __iomem *ioaddr) { unsigned long flags; u32 val; |
2e373952c MIPS: RB532: Prov... |
64 65 66 |
local_irq_save(flags); val = readl(ioaddr); |
5379a5fdf MIPS: RB532: Fix ... |
67 68 |
val &= ~(!bitval << offset); /* unset bit if bitval == 0 */ val |= (!!bitval << offset); /* set bit if bitval == 1 */ |
2e373952c MIPS: RB532: Prov... |
69 70 71 72 73 74 75 76 77 78 79 80 81 |
writel(val, ioaddr); local_irq_restore(flags); } /* rb532_get_bit - read a bit * * returns the boolean state of the bit, which may be > 1 */ static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) { return (readl(ioaddr) & (1 << offset)); } |
d888e25b8 MIPS: RB532: Conv... |
82 83 84 |
/* * Return GPIO level */ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) |
73b4390fb [MIPS] Routerboar... |
85 |
{ |
d888e25b8 MIPS: RB532: Conv... |
86 87 88 |
struct rb532_gpio_chip *gpch; gpch = container_of(chip, struct rb532_gpio_chip, chip); |
2e373952c MIPS: RB532: Prov... |
89 |
return rb532_get_bit(offset, gpch->regbase + GPIOD); |
73b4390fb [MIPS] Routerboar... |
90 |
} |
73b4390fb [MIPS] Routerboar... |
91 |
|
d888e25b8 MIPS: RB532: Conv... |
92 93 94 95 96 |
/* * Set output GPIO level */ static void rb532_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
73b4390fb [MIPS] Routerboar... |
97 |
{ |
d888e25b8 MIPS: RB532: Conv... |
98 |
struct rb532_gpio_chip *gpch; |
73b4390fb [MIPS] Routerboar... |
99 |
|
d888e25b8 MIPS: RB532: Conv... |
100 |
gpch = container_of(chip, struct rb532_gpio_chip, chip); |
2e373952c MIPS: RB532: Prov... |
101 |
rb532_set_bit(value, offset, gpch->regbase + GPIOD); |
73b4390fb [MIPS] Routerboar... |
102 |
} |
73b4390fb [MIPS] Routerboar... |
103 |
|
d888e25b8 MIPS: RB532: Conv... |
104 105 106 107 |
/* * Set GPIO direction to input */ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
73b4390fb [MIPS] Routerboar... |
108 |
{ |
d888e25b8 MIPS: RB532: Conv... |
109 |
struct rb532_gpio_chip *gpch; |
73b4390fb [MIPS] Routerboar... |
110 |
|
d888e25b8 MIPS: RB532: Conv... |
111 |
gpch = container_of(chip, struct rb532_gpio_chip, chip); |
73b4390fb [MIPS] Routerboar... |
112 |
|
33763d571 MIPS: RB532: Auto... |
113 114 |
/* disable alternate function in case it's set */ rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); |
73b4390fb [MIPS] Routerboar... |
115 |
|
2e373952c MIPS: RB532: Prov... |
116 |
rb532_set_bit(0, offset, gpch->regbase + GPIOCFG); |
73b4390fb [MIPS] Routerboar... |
117 118 |
return 0; } |
73b4390fb [MIPS] Routerboar... |
119 |
|
d888e25b8 MIPS: RB532: Conv... |
120 121 122 123 124 |
/* * Set GPIO direction to output */ static int rb532_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) |
73b4390fb [MIPS] Routerboar... |
125 |
{ |
d888e25b8 MIPS: RB532: Conv... |
126 |
struct rb532_gpio_chip *gpch; |
d888e25b8 MIPS: RB532: Conv... |
127 128 |
gpch = container_of(chip, struct rb532_gpio_chip, chip); |
d888e25b8 MIPS: RB532: Conv... |
129 |
|
33763d571 MIPS: RB532: Auto... |
130 131 |
/* disable alternate function in case it's set */ rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC); |
73b4390fb [MIPS] Routerboar... |
132 |
|
2e373952c MIPS: RB532: Prov... |
133 134 135 136 |
/* set the initial output value */ rb532_set_bit(value, offset, gpch->regbase + GPIOD); rb532_set_bit(1, offset, gpch->regbase + GPIOCFG); |
d888e25b8 MIPS: RB532: Conv... |
137 |
return 0; |
73b4390fb [MIPS] Routerboar... |
138 |
} |
73b4390fb [MIPS] Routerboar... |
139 |
|
2e373952c MIPS: RB532: Prov... |
140 141 142 143 144 145 146 147 148 149 150 151 152 |
static struct rb532_gpio_chip rb532_gpio_chip[] = { [0] = { .chip = { .label = "gpio0", .direction_input = rb532_gpio_direction_input, .direction_output = rb532_gpio_direction_output, .get = rb532_gpio_get, .set = rb532_gpio_set, .base = 0, .ngpio = 32, }, }, }; |
73b4390fb [MIPS] Routerboar... |
153 |
|
d888e25b8 MIPS: RB532: Conv... |
154 |
/* |
2e373952c MIPS: RB532: Prov... |
155 |
* Set GPIO interrupt level |
d888e25b8 MIPS: RB532: Conv... |
156 |
*/ |
2e373952c MIPS: RB532: Prov... |
157 |
void rb532_gpio_set_ilevel(int bit, unsigned gpio) |
73b4390fb [MIPS] Routerboar... |
158 |
{ |
2e373952c MIPS: RB532: Prov... |
159 |
rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOILEVEL); |
73b4390fb [MIPS] Routerboar... |
160 |
} |
2e373952c MIPS: RB532: Prov... |
161 |
EXPORT_SYMBOL(rb532_gpio_set_ilevel); |
73b4390fb [MIPS] Routerboar... |
162 |
|
d888e25b8 MIPS: RB532: Conv... |
163 |
/* |
2e373952c MIPS: RB532: Prov... |
164 |
* Set GPIO interrupt status |
d888e25b8 MIPS: RB532: Conv... |
165 |
*/ |
2e373952c MIPS: RB532: Prov... |
166 |
void rb532_gpio_set_istat(int bit, unsigned gpio) |
73b4390fb [MIPS] Routerboar... |
167 |
{ |
2e373952c MIPS: RB532: Prov... |
168 |
rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOISTAT); |
73b4390fb [MIPS] Routerboar... |
169 |
} |
2e373952c MIPS: RB532: Prov... |
170 |
EXPORT_SYMBOL(rb532_gpio_set_istat); |
73b4390fb [MIPS] Routerboar... |
171 |
|
d888e25b8 MIPS: RB532: Conv... |
172 |
/* |
2e373952c MIPS: RB532: Prov... |
173 |
* Configure GPIO alternate function |
d888e25b8 MIPS: RB532: Conv... |
174 |
*/ |
0fc6bc0d6 MIPS: RB532: Expo... |
175 |
void rb532_gpio_set_func(unsigned gpio) |
73b4390fb [MIPS] Routerboar... |
176 |
{ |
0fc6bc0d6 MIPS: RB532: Expo... |
177 |
rb532_set_bit(1, gpio, rb532_gpio_chip->regbase + GPIOFUNC); |
73b4390fb [MIPS] Routerboar... |
178 |
} |
0fc6bc0d6 MIPS: RB532: Expo... |
179 |
EXPORT_SYMBOL(rb532_gpio_set_func); |
d888e25b8 MIPS: RB532: Conv... |
180 |
|
73b4390fb [MIPS] Routerboar... |
181 182 |
int __init rb532_gpio_init(void) { |
d888e25b8 MIPS: RB532: Conv... |
183 |
struct resource *r; |
73b4390fb [MIPS] Routerboar... |
184 |
|
d888e25b8 MIPS: RB532: Conv... |
185 |
r = rb532_gpio_reg0_res; |
3436830af MIPS: RB532: Fix ... |
186 |
rb532_gpio_chip->regbase = ioremap_nocache(r->start, resource_size(r)); |
d888e25b8 MIPS: RB532: Conv... |
187 188 |
if (!rb532_gpio_chip->regbase) { |
73b4390fb [MIPS] Routerboar... |
189 190 191 192 |
printk(KERN_ERR "rb532: cannot remap GPIO register 0 "); return -ENXIO; } |
d888e25b8 MIPS: RB532: Conv... |
193 194 |
/* Register our GPIO chip */ gpiochip_add(&rb532_gpio_chip->chip); |
73b4390fb [MIPS] Routerboar... |
195 196 197 |
return 0; } arch_initcall(rb532_gpio_init); |