MIPS: RB532: Provide functions for gpio configuration

As gpiolib doesn't support pin multiplexing, it provides no way to
access the GPIOFUNC register. Also there is no support for setting
interrupt status and level. These functions provide access to them and
are needed by the CompactFlash driver.

Signed-off-by: Phil Sutter <n0-1@freewrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by Phil Sutter and committed by Ralf Baechle 2e373952 f43909df

+77 -122
+2
arch/mips/include/asm/mach-rc32434/gpio.h
··· 84 extern unsigned get_434_reg(unsigned reg_offs); 85 extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask); 86 extern unsigned char get_latch_u5(void); 87 88 #endif /* _RC32434_GPIO_H_ */
··· 84 extern unsigned get_434_reg(unsigned reg_offs); 85 extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask); 86 extern unsigned char get_latch_u5(void); 87 + extern void rb532_gpio_set_ilevel(int bit, unsigned gpio); 88 + extern void rb532_gpio_set_istat(int bit, unsigned gpio); 89 90 #endif /* _RC32434_GPIO_H_ */
+75 -122
arch/mips/rb532/gpio.c
··· 39 struct rb532_gpio_chip { 40 struct gpio_chip chip; 41 void __iomem *regbase; 42 - void (*set_int_level)(struct gpio_chip *chip, unsigned offset, int value); 43 - int (*get_int_level)(struct gpio_chip *chip, unsigned offset); 44 - void (*set_int_status)(struct gpio_chip *chip, unsigned offset, int value); 45 - int (*get_int_status)(struct gpio_chip *chip, unsigned offset); 46 }; 47 48 struct mpmc_device dev3; ··· 107 } 108 EXPORT_SYMBOL(get_latch_u5); 109 110 /* 111 * Return GPIO level */ 112 static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) 113 { 114 - u32 mask = 1 << offset; 115 struct rb532_gpio_chip *gpch; 116 117 gpch = container_of(chip, struct rb532_gpio_chip, chip); 118 - return readl(gpch->regbase + GPIOD) & mask; 119 } 120 121 /* ··· 156 static void rb532_gpio_set(struct gpio_chip *chip, 157 unsigned offset, int value) 158 { 159 - unsigned long flags; 160 - u32 mask = 1 << offset; 161 - u32 tmp; 162 struct rb532_gpio_chip *gpch; 163 - void __iomem *gpvr; 164 165 gpch = container_of(chip, struct rb532_gpio_chip, chip); 166 - gpvr = gpch->regbase + GPIOD; 167 - 168 - local_irq_save(flags); 169 - tmp = readl(gpvr); 170 - if (value) 171 - tmp |= mask; 172 - else 173 - tmp &= ~mask; 174 - writel(tmp, gpvr); 175 - local_irq_restore(flags); 176 } 177 178 /* ··· 167 */ 168 static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 169 { 170 - unsigned long flags; 171 - u32 mask = 1 << offset; 172 - u32 value; 173 struct rb532_gpio_chip *gpch; 174 - void __iomem *gpdr; 175 176 gpch = container_of(chip, struct rb532_gpio_chip, chip); 177 - gpdr = gpch->regbase + GPIOCFG; 178 179 - local_irq_save(flags); 180 - value = readl(gpdr); 181 - value &= ~mask; 182 - writel(value, gpdr); 183 - local_irq_restore(flags); 184 185 return 0; 186 } 187 ··· 184 static int rb532_gpio_direction_output(struct gpio_chip *chip, 185 unsigned offset, int value) 186 { 187 - unsigned long flags; 188 - u32 mask = 1 << offset; 189 - u32 tmp; 190 struct rb532_gpio_chip *gpch; 191 - void __iomem *gpdr; 192 193 gpch = container_of(chip, struct rb532_gpio_chip, chip); 194 - writel(mask, gpch->regbase + GPIOD); 195 - gpdr = gpch->regbase + GPIOCFG; 196 197 - local_irq_save(flags); 198 - tmp = readl(gpdr); 199 - tmp |= mask; 200 - writel(tmp, gpdr); 201 - local_irq_restore(flags); 202 203 return 0; 204 - } 205 - 206 - /* 207 - * Set the GPIO interrupt level 208 - */ 209 - static void rb532_gpio_set_int_level(struct gpio_chip *chip, 210 - unsigned offset, int value) 211 - { 212 - unsigned long flags; 213 - u32 mask = 1 << offset; 214 - u32 tmp; 215 - struct rb532_gpio_chip *gpch; 216 - void __iomem *gpil; 217 - 218 - gpch = container_of(chip, struct rb532_gpio_chip, chip); 219 - gpil = gpch->regbase + GPIOILEVEL; 220 - 221 - local_irq_save(flags); 222 - tmp = readl(gpil); 223 - if (value) 224 - tmp |= mask; 225 - else 226 - tmp &= ~mask; 227 - writel(tmp, gpil); 228 - local_irq_restore(flags); 229 - } 230 - 231 - /* 232 - * Get the GPIO interrupt level 233 - */ 234 - static int rb532_gpio_get_int_level(struct gpio_chip *chip, unsigned offset) 235 - { 236 - u32 mask = 1 << offset; 237 - struct rb532_gpio_chip *gpch; 238 - 239 - gpch = container_of(chip, struct rb532_gpio_chip, chip); 240 - return readl(gpch->regbase + GPIOILEVEL) & mask; 241 - } 242 - 243 - /* 244 - * Set the GPIO interrupt status 245 - */ 246 - static void rb532_gpio_set_int_status(struct gpio_chip *chip, 247 - unsigned offset, int value) 248 - { 249 - unsigned long flags; 250 - u32 mask = 1 << offset; 251 - u32 tmp; 252 - struct rb532_gpio_chip *gpch; 253 - void __iomem *gpis; 254 - 255 - gpch = container_of(chip, struct rb532_gpio_chip, chip); 256 - gpis = gpch->regbase + GPIOISTAT; 257 - 258 - local_irq_save(flags); 259 - tmp = readl(gpis); 260 - if (value) 261 - tmp |= mask; 262 - else 263 - tmp &= ~mask; 264 - writel(tmp, gpis); 265 - local_irq_restore(flags); 266 - } 267 - 268 - /* 269 - * Get the GPIO interrupt status 270 - */ 271 - static int rb532_gpio_get_int_status(struct gpio_chip *chip, unsigned offset) 272 - { 273 - u32 mask = 1 << offset; 274 - struct rb532_gpio_chip *gpch; 275 - 276 - gpch = container_of(chip, struct rb532_gpio_chip, chip); 277 - return readl(gpch->regbase + GPIOISTAT) & mask; 278 } 279 280 static struct rb532_gpio_chip rb532_gpio_chip[] = { ··· 209 .base = 0, 210 .ngpio = 32, 211 }, 212 - .get_int_level = rb532_gpio_get_int_level, 213 - .set_int_level = rb532_gpio_set_int_level, 214 - .get_int_status = rb532_gpio_get_int_status, 215 - .set_int_status = rb532_gpio_set_int_status, 216 }, 217 }; 218 219 int __init rb532_gpio_init(void) 220 { ··· 261 return -ENXIO; 262 } 263 264 - /* Set the interrupt status and level for the CF pin */ 265 - rb532_gpio_set_int_level(&rb532_gpio_chip->chip, CF_GPIO_NUM, 1); 266 - rb532_gpio_set_int_status(&rb532_gpio_chip->chip, CF_GPIO_NUM, 0); 267 268 return 0; 269 }
··· 39 struct rb532_gpio_chip { 40 struct gpio_chip chip; 41 void __iomem *regbase; 42 }; 43 44 struct mpmc_device dev3; ··· 111 } 112 EXPORT_SYMBOL(get_latch_u5); 113 114 + /* rb532_set_bit - sanely set a bit 115 + * 116 + * bitval: new value for the bit 117 + * offset: bit index in the 4 byte address range 118 + * ioaddr: 4 byte aligned address being altered 119 + */ 120 + static inline void rb532_set_bit(unsigned bitval, 121 + unsigned offset, void __iomem *ioaddr) 122 + { 123 + unsigned long flags; 124 + u32 val; 125 + 126 + bitval = !!bitval; /* map parameter to {0,1} */ 127 + 128 + local_irq_save(flags); 129 + 130 + val = readl(ioaddr); 131 + val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */ 132 + val |= ( bitval << offset ); /* set bit if bitval == 1 */ 133 + writel(val, ioaddr); 134 + 135 + local_irq_restore(flags); 136 + } 137 + 138 + /* rb532_get_bit - read a bit 139 + * 140 + * returns the boolean state of the bit, which may be > 1 141 + */ 142 + static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) 143 + { 144 + return (readl(ioaddr) & (1 << offset)); 145 + } 146 + 147 /* 148 * Return GPIO level */ 149 static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) 150 { 151 struct rb532_gpio_chip *gpch; 152 153 gpch = container_of(chip, struct rb532_gpio_chip, chip); 154 + return rb532_get_bit(offset, gpch->regbase + GPIOD); 155 } 156 157 /* ··· 128 static void rb532_gpio_set(struct gpio_chip *chip, 129 unsigned offset, int value) 130 { 131 struct rb532_gpio_chip *gpch; 132 133 gpch = container_of(chip, struct rb532_gpio_chip, chip); 134 + rb532_set_bit(value, offset, gpch->regbase + GPIOD); 135 } 136 137 /* ··· 152 */ 153 static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 154 { 155 struct rb532_gpio_chip *gpch; 156 157 gpch = container_of(chip, struct rb532_gpio_chip, chip); 158 159 + if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) 160 + return 1; /* alternate function, GPIOCFG is ignored */ 161 162 + rb532_set_bit(0, offset, gpch->regbase + GPIOCFG); 163 return 0; 164 } 165 ··· 176 static int rb532_gpio_direction_output(struct gpio_chip *chip, 177 unsigned offset, int value) 178 { 179 struct rb532_gpio_chip *gpch; 180 181 gpch = container_of(chip, struct rb532_gpio_chip, chip); 182 183 + if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) 184 + return 1; /* alternate function, GPIOCFG is ignored */ 185 186 + /* set the initial output value */ 187 + rb532_set_bit(value, offset, gpch->regbase + GPIOD); 188 + 189 + rb532_set_bit(1, offset, gpch->regbase + GPIOCFG); 190 return 0; 191 } 192 193 static struct rb532_gpio_chip rb532_gpio_chip[] = { ··· 280 .base = 0, 281 .ngpio = 32, 282 }, 283 }, 284 }; 285 + 286 + /* 287 + * Set GPIO interrupt level 288 + */ 289 + void rb532_gpio_set_ilevel(int bit, unsigned gpio) 290 + { 291 + rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOILEVEL); 292 + } 293 + EXPORT_SYMBOL(rb532_gpio_set_ilevel); 294 + 295 + /* 296 + * Set GPIO interrupt status 297 + */ 298 + void rb532_gpio_set_istat(int bit, unsigned gpio) 299 + { 300 + rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOISTAT); 301 + } 302 + EXPORT_SYMBOL(rb532_gpio_set_istat); 303 + 304 + /* 305 + * Configure GPIO alternate function 306 + */ 307 + static void rb532_gpio_set_func(int bit, unsigned gpio) 308 + { 309 + rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOFUNC); 310 + } 311 312 int __init rb532_gpio_init(void) 313 { ··· 310 return -ENXIO; 311 } 312 313 + /* configure CF_GPIO_NUM as CFRDY IRQ source */ 314 + rb532_gpio_set_func(0, CF_GPIO_NUM); 315 + rb532_gpio_direction_input(&rb532_gpio_chip->chip, CF_GPIO_NUM); 316 + rb532_gpio_set_ilevel(1, CF_GPIO_NUM); 317 + rb532_gpio_set_istat(0, CF_GPIO_NUM); 318 319 return 0; 320 }