int gpio_get_value(rt_uint32_t gpio) { rt_uint32_t tmp, base, offset; if (!gpio_available[gpio]) { rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio); return -RT_EBUSY; } offset = gpio % 32; base = gpio_to_base(gpio); tmp = GET_REG(base + REG_GPIO_SWPORTA_DDR); tmp &= BIT(offset); if (tmp) { tmp = GET_REG(base + REG_GPIO_SWPORTA_DR); } else { tmp = GET_REG(base + REG_GPIO_EXT_PORTA); } tmp &= BIT(offset); tmp = tmp >> offset; return tmp; }
int gpio_set_value(unsigned int gpio, int value) { unsigned int offset; int ret=0; rt_ubase_t temp = rt_hw_interrupt_disable(); ret = gpio_to_base(gpio); if (ret < 0) { goto gpio_free; } offset = gpio & ((1 << GPIO_GRP_MASK) -1); if (value) { gpio_set(offset); } else { gpio_clr(offset); } gpio_free: rt_hw_interrupt_enable(temp); return ret; }
int gpio_direction_input(rt_uint32_t gpio) { rt_uint32_t reg, base; if (gpio > NUM_OF_GPIO) { rt_kprintf("ERROR: %s, incorrect GPIO num\n", __func__); return -RT_ERROR; } if (!gpio_available[gpio]) { rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio); return -RT_EBUSY; } base = gpio_to_base(gpio); gpio = gpio % 32; // fixme: lock // spin_lock_irqsave(&chip->lock, flags); reg = GET_REG(base + REG_GPIO_SWPORTA_DDR); reg &= ~(1 << gpio); SET_REG(base + REG_GPIO_SWPORTA_DDR, reg); // spin_unlock_irqrestore(&chip->lock, flags); return 0; }
int nmk_gpio_get(int gpio) { unsigned long base = gpio_to_base(gpio); u32 bit = gpio_to_bit(gpio); return readl(base + GPIO_DAT) & bit; }
void nmk_gpio_set(int gpio, int val) { unsigned long base = gpio_to_base(gpio); u32 bit = gpio_to_bit(gpio); if (val) writel(bit, base + GPIO_DATS); else writel(bit, base + GPIO_DATC); }
void nmk_gpio_dir(int gpio, int dir) { unsigned long base = gpio_to_base(gpio); u32 bit = gpio_to_bit(gpio); if (dir) writel(bit, base + GPIO_DIRS); else writel(bit, base + GPIO_DIRC); }
int gpio_set_irq_type(rt_uint32_t gpio, rt_uint32_t type) { rt_uint32_t int_type, int_polarity; rt_uint32_t bit = gpio % 32; rt_uint32_t base; if (!gpio_available[gpio]) { rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio); return -RT_EBUSY; } base = gpio_to_base(gpio); int_type = GET_REG(base + REG_GPIO_INTTYPE_LEVEL); int_polarity = GET_REG(base + REG_GPIO_INT_POLARITY); switch (type & IRQ_TYPE_TRIGGER_MASK) { case IRQ_TYPE_EDGE_BOTH: int_type |= BIT(bit); // toggle trigger if (gpio_get_value(gpio)) int_polarity &= ~BIT(bit); else int_polarity |= BIT(bit); break; case IRQ_TYPE_EDGE_RISING: int_type |= BIT(bit); int_polarity |= BIT(bit); break; case IRQ_TYPE_EDGE_FALLING: int_type |= BIT(bit); int_polarity &= ~BIT(bit); break; case IRQ_TYPE_LEVEL_HIGH: int_type &= ~BIT(bit); int_polarity |= BIT(bit); break; case IRQ_TYPE_LEVEL_LOW: int_type &= ~BIT(bit); int_polarity &= ~BIT(bit); break; case IRQ_TYPE_NONE: return 0; default: return -RT_ERROR; } SET_REG(base + REG_GPIO_INTTYPE_LEVEL, int_type); SET_REG(base + REG_GPIO_INT_POLARITY, int_polarity); return 0; }
void nmk_gpio_af(int gpio, int alternate_function) { unsigned long base = gpio_to_base(gpio); u32 bit = gpio_to_bit(gpio); u32 afunc, bfunc; /* alternate function is 0..3, with one bit per register */ afunc = readl(base + GPIO_AFSLA) & ~bit; bfunc = readl(base + GPIO_AFSLB) & ~bit; if (alternate_function & 1) afunc |= bit; if (alternate_function & 2) bfunc |= bit; writel(afunc, base + GPIO_AFSLA); writel(bfunc, base + GPIO_AFSLB); }
int gpio_direction_input(unsigned int gpio) { unsigned int offset; int ret=0; rt_ubase_t temp = rt_hw_interrupt_disable(); ret = gpio_to_base(gpio); if (ret < 0) { goto gpio_free; } offset = gpio & ((1 << GPIO_GRP_MASK) -1); gpio_dirin(offset); gpio_free: rt_hw_interrupt_enable(temp); return ret; }
void gpio_enable_debounce(rt_uint32_t gpio) { rt_uint32_t tmp, base, offset; if (!gpio_available[gpio]) { rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio); return; } offset = gpio % 32; base = gpio_to_base(gpio); tmp = GET_REG(base + REG_GPIO_DEBOUNCE); tmp |= BIT(offset); SET_REG(base + REG_GPIO_DEBOUNCE, tmp); }
void gpio_set_direction(rt_uint32_t gpio, rt_uint32_t direction) { rt_uint32_t tmp, base, offset; if (!gpio_available[gpio]) { rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio); return; } offset = gpio % 32; base = gpio_to_base(gpio); tmp = GET_REG(base + REG_GPIO_SWPORTA_DDR); if (direction == GPIO_DIR_OUTPUT) tmp |= BIT(offset); else tmp &= ~BIT(offset); SET_REG(base + REG_GPIO_SWPORTA_DDR, tmp); }
void gpio_set_value(rt_uint32_t gpio, int val) { rt_uint32_t tmp, base, offset; if (!gpio_available[gpio]) { rt_kprintf("ERROR: %s, GPIO %d is not available\n", __func__, gpio); return; } offset = gpio % 32; base = gpio_to_base(gpio); tmp = GET_REG(base + REG_GPIO_SWPORTA_DR); if (val) tmp |= BIT(offset); else tmp &= ~BIT(offset); SET_REG(base + REG_GPIO_SWPORTA_DR, tmp); }