MPC8641HPCN: Enable CONFIG_ADDR_MAP
[oweals/u-boot.git] / cpu / at32ap / pio.c
index 8b6c3a35df505a6510d85445e1bbc74798cee318..f64004b65913a2f299ca218257b109223ef446d2 100644 (file)
  */
 #include <common.h>
 
-#include <asm/errno.h>
 #include <asm/io.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/memory-map.h>
 
 #include "pio2.h"
 
-struct pio_state {
-       const struct device *dev;
-       u32 alloc_mask;
-};
+void gpio_select_periph_A(unsigned int pin, int use_pullup)
+{
+       void *base = gpio_pin_to_addr(pin);
+       uint32_t mask = 1 << (pin & 0x1f);
+
+       if (!base)
+               panic("Invalid GPIO pin %u\n", pin);
 
-static struct pio_state pio_state[CFG_NR_PIOS];
+       pio2_writel(base, ASR, mask);
+       pio2_writel(base, PDR, mask);
+       if (use_pullup)
+               pio2_writel(base, PUER, mask);
+       else
+               pio2_writel(base, PUDR, mask);
+}
 
-int gpio_set_func(enum device_id gpio_devid, unsigned int start,
-                 unsigned int nr_pins, enum gpio_func func)
+void gpio_select_periph_B(unsigned int pin, int use_pullup)
 {
-       const struct device *gpio;
-       struct pio_state *state;
-       u32 mask;
+       void *base = gpio_pin_to_addr(pin);
+       uint32_t mask = 1 << (pin & 0x1f);
 
-       state = &pio_state[gpio_devid - DEVICE_PIOA];
+       if (!base)
+               panic("Invalid GPIO pin %u\n", pin);
 
-       gpio = get_device(gpio_devid);
-       if (!gpio)
-               return -EBUSY;
+       pio2_writel(base, BSR, mask);
+       pio2_writel(base, PDR, mask);
+       if (use_pullup)
+               pio2_writel(base, PUER, mask);
+       else
+               pio2_writel(base, PUDR, mask);
+}
 
-       state->dev = gpio;
-       mask = ((1 << nr_pins) - 1) << start;
+void gpio_select_pio(unsigned int pin, unsigned long gpiof_flags)
+{
+       void *base = gpio_pin_to_addr(pin);
+       uint32_t mask = 1 << (pin & 0x1f);
 
-       if (mask & state->alloc_mask) {
-               put_device(gpio);
-               return -EBUSY;
-       }
-       state->alloc_mask |= mask;
-
-       switch (func) {
-       case GPIO_FUNC_GPIO:
-               /* TODO */
-               return -EINVAL;
-       case GPIO_FUNC_A:
-               pio2_writel(gpio, ASR, mask);
-               pio2_writel(gpio, PDR, mask);
-               pio2_writel(gpio, PUDR, mask);
-               break;
-       case GPIO_FUNC_B:
-               pio2_writel(gpio, BSR, mask);
-               pio2_writel(gpio, PDR, mask);
-               pio2_writel(gpio, PUDR, mask);
-               break;
+       if (!base)
+               panic("Invalid GPIO pin %u\n", pin);
+
+       if (gpiof_flags & GPIOF_OUTPUT) {
+               if (gpiof_flags & GPIOF_MULTIDRV)
+                       pio2_writel(base, MDER, mask);
+               else
+                       pio2_writel(base, MDDR, mask);
+               pio2_writel(base, PUDR, mask);
+               pio2_writel(base, OER, mask);
+       } else {
+               if (gpiof_flags & GPIOF_PULLUP)
+                       pio2_writel(base, PUER, mask);
+               else
+                       pio2_writel(base, PUDR, mask);
+               if (gpiof_flags & GPIOF_DEGLITCH)
+                       pio2_writel(base, IFER, mask);
+               else
+                       pio2_writel(base, IFDR, mask);
+               pio2_writel(base, ODR, mask);
        }
 
-       return 0;
+       pio2_writel(base, PER, mask);
 }
 
-void gpio_free(enum device_id gpio_devid, unsigned int start,
-              unsigned int nr_pins)
+void gpio_set_value(unsigned int pin, int value)
 {
-       const struct device *gpio;
-       struct pio_state *state;
-       u32 mask;
+       void *base = gpio_pin_to_addr(pin);
+       uint32_t mask = 1 << (pin & 0x1f);
+
+       if (!base)
+               panic("Invalid GPIO pin %u\n", pin);
 
-       state = &pio_state[gpio_devid - DEVICE_PIOA];
-       gpio = state->dev;
-       mask = ((1 << nr_pins) - 1) << start;
+       if (value)
+               pio2_writel(base, SODR, mask);
+       else
+               pio2_writel(base, CODR, mask);
+}
+
+int gpio_get_value(unsigned int pin)
+{
+       void *base = gpio_pin_to_addr(pin);
+       int value;
 
-       pio2_writel(gpio, ODR, mask);
-       pio2_writel(gpio, PER, mask);
+       if (!base)
+               panic("Invalid GPIO pin %u\n", pin);
 
-       state->alloc_mask &= ~mask;
-       put_device(gpio);
+       value = pio2_readl(base, PDSR);
+       return (value >> (pin & 0x1f)) & 1;
 }