X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fat32ap%2Fpio.c;h=f64004b65913a2f299ca218257b109223ef446d2;hb=9692cab76f7b7891f71c8a9b189465cd3bd68ef0;hp=8b6c3a35df505a6510d85445e1bbc74798cee318;hpb=0ab292cbc1add30abb8767ae64ebfaac7504d1f6;p=oweals%2Fu-boot.git diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c index 8b6c3a35df..f64004b659 100644 --- a/cpu/at32ap/pio.c +++ b/cpu/at32ap/pio.c @@ -21,74 +21,96 @@ */ #include -#include #include -#include +#include +#include #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; }