1 /* 2 * Miscellaneous functions for IDT EB434 board 3 * 4 * Copyright 2004 IDT Inc. (rischelp@idt.com) 5 * Copyright 2006 Phil Sutter <n0-1@freewrt.org> 6 * Copyright 2007 Florian Fainelli <florian@openwrt.org> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * You should have received a copy of the GNU General Public License along 25 * with this program; if not, write to the Free Software Foundation, Inc., 26 * 675 Mass Ave, Cambridge, MA 02139, USA. 27 */ 28 29 #include <linux/kernel.h> 30 #include <linux/gpio.h> 31 #include <linux/init.h> 32 #include <linux/types.h> 33 #include <linux/pci.h> 34 #include <linux/spinlock.h> 35 #include <linux/io.h> 36 #include <linux/platform_device.h> 37 38 #include <asm/addrspace.h> 39 40 #include <asm/mach-rc32434/rb.h> 41 42 struct rb532_gpio_reg __iomem *rb532_gpio_reg0; 43 EXPORT_SYMBOL(rb532_gpio_reg0); 44 45 struct mpmc_device dev3; 46 47 static struct resource rb532_gpio_reg0_res[] = { 48 { 49 .name = "gpio_reg0", 50 .start = REGBASE + GPIOBASE, 51 .end = REGBASE + GPIOBASE + sizeof(struct rb532_gpio_reg) - 1, 52 .flags = IORESOURCE_MEM, 53 } 54 }; 55 56 static struct resource rb532_dev3_ctl_res[] = { 57 { 58 .name = "dev3_ctl", 59 .start = REGBASE + DEV3BASE, 60 .end = REGBASE + DEV3BASE + sizeof(struct dev_reg) - 1, 61 .flags = IORESOURCE_MEM, 62 } 63 }; 64 65 void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val) 66 { 67 unsigned long flags; 68 unsigned data; 69 unsigned i = 0; 70 71 spin_lock_irqsave(&dev3.lock, flags); 72 73 data = readl(IDT434_REG_BASE + reg_offs); 74 for (i = 0; i != len; ++i) { 75 if (val & (1 << i)) 76 data |= (1 << (i + bit)); 77 else 78 data &= ~(1 << (i + bit)); 79 } 80 writel(data, (IDT434_REG_BASE + reg_offs)); 81 82 spin_unlock_irqrestore(&dev3.lock, flags); 83 } 84 EXPORT_SYMBOL(set_434_reg); 85 86 unsigned get_434_reg(unsigned reg_offs) 87 { 88 return readl(IDT434_REG_BASE + reg_offs); 89 } 90 EXPORT_SYMBOL(get_434_reg); 91 92 void set_latch_u5(unsigned char or_mask, unsigned char nand_mask) 93 { 94 unsigned long flags; 95 96 spin_lock_irqsave(&dev3.lock, flags); 97 98 dev3.state = (dev3.state | or_mask) & ~nand_mask; 99 writel(dev3.state, &dev3.base); 100 101 spin_unlock_irqrestore(&dev3.lock, flags); 102 } 103 EXPORT_SYMBOL(set_latch_u5); 104 105 unsigned char get_latch_u5(void) 106 { 107 return dev3.state; 108 } 109 EXPORT_SYMBOL(get_latch_u5); 110 111 int rb532_gpio_get_value(unsigned gpio) 112 { 113 return readl(&rb532_gpio_reg0->gpiod) & (1 << gpio); 114 } 115 EXPORT_SYMBOL(rb532_gpio_get_value); 116 117 void rb532_gpio_set_value(unsigned gpio, int value) 118 { 119 unsigned tmp; 120 121 tmp = readl(&rb532_gpio_reg0->gpiod) & ~(1 << gpio); 122 if (value) 123 tmp |= 1 << gpio; 124 125 writel(tmp, (void *)&rb532_gpio_reg0->gpiod); 126 } 127 EXPORT_SYMBOL(rb532_gpio_set_value); 128 129 int rb532_gpio_direction_input(unsigned gpio) 130 { 131 writel(readl(&rb532_gpio_reg0->gpiocfg) & ~(1 << gpio), 132 (void *)&rb532_gpio_reg0->gpiocfg); 133 134 return 0; 135 } 136 EXPORT_SYMBOL(rb532_gpio_direction_input); 137 138 int rb532_gpio_direction_output(unsigned gpio, int value) 139 { 140 gpio_set_value(gpio, value); 141 writel(readl(&rb532_gpio_reg0->gpiocfg) | (1 << gpio), 142 (void *)&rb532_gpio_reg0->gpiocfg); 143 144 return 0; 145 } 146 EXPORT_SYMBOL(rb532_gpio_direction_output); 147 148 void rb532_gpio_set_int_level(unsigned gpio, int value) 149 { 150 unsigned tmp; 151 152 tmp = readl(&rb532_gpio_reg0->gpioilevel) & ~(1 << gpio); 153 if (value) 154 tmp |= 1 << gpio; 155 writel(tmp, (void *)&rb532_gpio_reg0->gpioilevel); 156 } 157 EXPORT_SYMBOL(rb532_gpio_set_int_level); 158 159 int rb532_gpio_get_int_level(unsigned gpio) 160 { 161 return readl(&rb532_gpio_reg0->gpioilevel) & (1 << gpio); 162 } 163 EXPORT_SYMBOL(rb532_gpio_get_int_level); 164 165 void rb532_gpio_set_int_status(unsigned gpio, int value) 166 { 167 unsigned tmp; 168 169 tmp = readl(&rb532_gpio_reg0->gpioistat); 170 if (value) 171 tmp |= 1 << gpio; 172 writel(tmp, (void *)&rb532_gpio_reg0->gpioistat); 173 } 174 EXPORT_SYMBOL(rb532_gpio_set_int_status); 175 176 int rb532_gpio_get_int_status(unsigned gpio) 177 { 178 return readl(&rb532_gpio_reg0->gpioistat) & (1 << gpio); 179 } 180 EXPORT_SYMBOL(rb532_gpio_get_int_status); 181 182 void rb532_gpio_set_func(unsigned gpio, int value) 183 { 184 unsigned tmp; 185 186 tmp = readl(&rb532_gpio_reg0->gpiofunc); 187 if (value) 188 tmp |= 1 << gpio; 189 writel(tmp, (void *)&rb532_gpio_reg0->gpiofunc); 190 } 191 EXPORT_SYMBOL(rb532_gpio_set_func); 192 193 int rb532_gpio_get_func(unsigned gpio) 194 { 195 return readl(&rb532_gpio_reg0->gpiofunc) & (1 << gpio); 196 } 197 EXPORT_SYMBOL(rb532_gpio_get_func); 198 199 int __init rb532_gpio_init(void) 200 { 201 rb532_gpio_reg0 = ioremap_nocache(rb532_gpio_reg0_res[0].start, 202 rb532_gpio_reg0_res[0].end - 203 rb532_gpio_reg0_res[0].start); 204 205 if (!rb532_gpio_reg0) { 206 printk(KERN_ERR "rb532: cannot remap GPIO register 0\n"); 207 return -ENXIO; 208 } 209 210 dev3.base = ioremap_nocache(rb532_dev3_ctl_res[0].start, 211 rb532_dev3_ctl_res[0].end - 212 rb532_dev3_ctl_res[0].start); 213 214 if (!dev3.base) { 215 printk(KERN_ERR "rb532: cannot remap device controller 3\n"); 216 return -ENXIO; 217 } 218 219 return 0; 220 } 221 arch_initcall(rb532_gpio_init); 222