int gpio_request(unsigned gpio, const char *label) { if (check_gpio(gpio) < 0) return -EINVAL; /* * Allow that the identical GPIO can * be requested from the same driver twice * Do nothing and return - */ if (cmp_label(gpio, label) == 0) return 0; if (unlikely(is_reserved(gpio, gpio, 1))) { printf("bfin-gpio: GPIO %d is already reserved by %s !\n", gpio, get_label(gpio)); return -EBUSY; } if (unlikely(is_reserved(peri, gpio, 1))) { printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", gpio, get_label(gpio)); return -EBUSY; } else { /* Reset POLAR setting when acquiring a gpio for the first time */ set_gpio_polar(gpio, 0); } reserve(gpio, gpio); set_label(gpio, label); port_setup(gpio, GPIO_USAGE); return 0; }
/** * Request a gpio before using it. * * NOTE: Argument 'label' is unused. */ int gpio_request(unsigned gpio, const char *label) { if (check_gpio(gpio) < 0) return -1; return 0; }
/** * gpio_set_value - Modify the value of the pin with specified value * @gpio: gpio pin number within the device * @value: value used to modify the value of the specified pin * * This function calculates the register offset (i.e to lower 16 bits or * upper 16 bits) based on the given pin number and sets the value of a * gpio pin to the specified value. The value is either 0 or non-zero. */ int gpio_set_value(unsigned gpio, int value) { unsigned int reg_offset, bank_num, bank_pin_num; if (check_gpio(gpio) < 0) return -1; zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) { /* only 16 data bits in bit maskable reg */ bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM; reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); } else { reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); } /* * get the 32 bit value to be written to the mask/data register where * the upper 16 bits is the mask and lower 16 bits is the data */ value = !!value; value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset); return 0; }
/** * Get value of the specified gpio */ int gpio_get_value(unsigned gpio) { const struct gpio_bank *bank; void *reg; int input; if (check_gpio(gpio) < 0) return -1; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { case METHOD_GPIO_24XX: input = _get_gpio_direction(bank, get_gpio_index(gpio)); switch (input) { case OMAP_GPIO_DIR_IN: reg += OMAP_GPIO_DATAIN; break; case OMAP_GPIO_DIR_OUT: reg += OMAP_GPIO_DATAOUT; break; default: return -1; } break; default: return -1; } return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; }
/*! * Release ownership for a GPIO pin * @param pin a name defined by \b iomux_pin_name_t */ void mxc_free_gpio(iomux_pin_name_t pin) { struct gpio_port *port; u32 index, gpio = IOMUX_TO_GPIO(pin); if (check_gpio(gpio) < 0) return; port = get_gpio_port(gpio); index = GPIO_TO_INDEX(gpio); spin_lock(&port->lock); if ((!(port->reserved_map & (1 << index)))) { printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n", port->num, index); dump_stack(); spin_unlock(&port->lock); return; } port->reserved_map &= ~(1 << index); port->irq_is_level_map &= ~(1 << index); _set_gpio_direction(port, index, 1); _set_gpio_irqenable(port, index, 0); _clear_gpio_irqstatus(port, index); spin_unlock(&port->lock); }
int omap_request_gpio(int gpio) { if (check_gpio(gpio) < 0) return -EINVAL; return 0; }
int pnx_gpio_read_pin(int gpio) { struct gpio_bank *bank; void __iomem *reg; u32 l = 0; int irq, index; if (!check_gpio(gpio)) return -EINVAL; bank = get_gpio_bank(gpio); index = get_gpio_index(gpio); if (!check_gpio_requested(bank, index)) return -EINVAL; /* check if the GPIO is used as extint */ irq = pnx_gpio_to_extint(gpio); if (irq >= 0) { /* and if it's an alternate internal signal */ /* (cf PNX67xx datasheet table 444)*/ reg = (void __iomem*) EXTINT_CFGx(irq); l = __raw_readl(reg); if (l & EXTINT_SEL_ALTERNATE) { reg = (void __iomem*) EXTINT_SIGNAL_REG; return (__raw_readl(reg) & (1 << irq)) !=0; } } reg = bank->gpio_base; reg += PNX_GPIO_PINS_OFFSET; return (__raw_readl(reg) & (1 << index)) != 0; }
static void port_setup(unsigned gpio, unsigned short usage) { #if defined(BF538_FAMILY) /* * BF538/9 Port C,D and E are special. * Inverted PORT_FER polarity on CDE and no PORF_FER on F * Regular PORT F GPIOs are handled here, CDE are exclusively * managed by GPIOLIB */ if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES) return; gpio -= MAX_BLACKFIN_GPIOS; if (usage == GPIO_USAGE) *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); else *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); SSYNC(); return; #endif if (check_gpio(gpio)) return; #if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) || \ defined(CONFIG_BF50x) if (usage == GPIO_USAGE) *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); #endif }
int peripheral_request(unsigned short per, const char *label) { unsigned short ident = P_IDENT(per); /* * Don't cares are pins with only one dedicated function */ if (per & P_DONTCARE) return 0; if (!(per & P_DEFINED)) return -ENODEV; BUG_ON(ident >= MAX_RESOURCES); /* If a pin can be muxed as either GPIO or peripheral, make * sure it is not already a GPIO pin when we request it. */ if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) { printf("%s: Peripheral %d is already reserved as GPIO by %s !\n", __func__, ident, get_label(ident)); return -EBUSY; } if (unlikely(is_reserved(peri, ident, 1))) { /* * Pin functions like AMC address strobes my * be requested and used by several drivers */ if (!(per & P_MAYSHARE)) { /* * Allow that the identical pin function can * be requested from the same driver twice */ if (cmp_label(ident, label) == 0) goto anyway; printf("%s: Peripheral %d function %d is already reserved by %s !\n", __func__, ident, P_FUNCT2MUX(per), get_label(ident)); return -EBUSY; } } anyway: reserve(peri, ident); portmux_setup(per); port_setup(ident, PERIPHERAL_USAGE); set_label(ident, label); return 0; }
void omap_set_gpio_direction(int gpio, int is_input) { struct gpio_bank *bank; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); _set_gpio_direction(bank, get_gpio_index(gpio), is_input); }
void omap_set_gpio_dataout(int gpio, int enable) { struct gpio_bank *bank; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); _set_gpio_dataout(bank, get_gpio_index(gpio), enable); }
void omap_free_gpio(int gpio) { struct gpio_bank *bank; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); _reset_gpio(bank, gpio); }
/* * ubi_port_setup() */ static void ubi_port_setup(unsigned gpio, unsigned short usage) { if (!check_gpio(gpio)) { if (usage) { UBICOM32_GPIO_ENABLE(gpio); } else { UBICOM32_GPIO_DISABLE(gpio); } } }
/** * Set value of the specified gpio */ int gpio_set_value(unsigned gpio, int value) { const struct gpio_bank *bank; if (check_gpio(gpio) < 0) return -1; bank = get_gpio_bank(gpio); _set_gpio_dataout(bank, get_gpio_index(gpio), value); return 0; }
void omap_free_gpio(int gpio) { #if !defined (CONFIG_OMAP3_CE30X) && !defined (CONFIG_OMAP3_A317) struct gpio_bank *bank; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); _reset_gpio(bank, gpio); #endif }
/*! * Return the data value of a GPIO signal. * @param pin a name defined by \b iomux_pin_name_t * * @return value (0 or 1) of the GPIO signal; -1 if pass in invalid pin */ int mxc_get_gpio_datain(iomux_pin_name_t pin) { struct gpio_port *port; u32 gpio = IOMUX_TO_GPIO(pin); if (check_gpio(gpio) < 0) return -1; port = get_gpio_port(gpio); return (__raw_readl(port->base + GPIO_DR) >> GPIO_TO_INDEX(gpio)) & 1; }
/** * Set gpio direction as input */ int gpio_direction_input(unsigned gpio) { const struct gpio_bank *bank; if (check_gpio(gpio) < 0) return -1; bank = get_gpio_bank(gpio); _set_gpio_direction(bank, get_gpio_index(gpio), 1); return 0; }
void pnx_gpio_free(int gpio) { int index; struct gpio_bank *bank; if (!check_gpio(gpio)) return; index = get_gpio_index(gpio); bank = get_gpio_bank(gpio); _pnx_gpio_free(bank, index); }
/*! * Exported function to set a GPIO pin's direction * @param pin a name defined by \b iomux_pin_name_t * @param is_input 1 (or non-zero) for input; 0 for output */ void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input) { struct gpio_port *port; u32 gpio = IOMUX_TO_GPIO(pin); if (check_gpio(gpio) < 0) return; port = get_gpio_port(gpio); spin_lock(&port->lock); _set_gpio_direction(port, GPIO_TO_INDEX(gpio), is_input); spin_unlock(&port->lock); }
/*! * Request ownership for a GPIO pin. The caller has to check the return value * of this function to make sure it returns 0 before make use of that pin. * @param pin a name defined by \b iomux_pin_name_t * @return 0 if successful; Non-zero otherwise */ int mxc_request_gpio(iomux_pin_name_t pin) { struct gpio_port *port; u32 index, gpio = IOMUX_TO_GPIO(pin); if (check_gpio(gpio) < 0) return -EINVAL; port = get_gpio_port(gpio); index = GPIO_TO_INDEX(gpio); return _request_gpio(port, index); }
/*! * Exported function to set a GPIO pin's data output * @param pin a name defined by \b iomux_pin_name_t * @param data value to be set (only 0 or 1 is valid) */ void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data) { struct gpio_port *port; u32 gpio = IOMUX_TO_GPIO(pin); if (check_gpio(gpio) < 0) return; port = get_gpio_port(gpio); spin_lock(&port->lock); _set_gpio_dataout(port, GPIO_TO_INDEX(gpio), (data == 0) ? 0 : 1); spin_unlock(&port->lock); }
int pnx_gpio_request(int gpio) { int index; struct gpio_bank *bank; if (!check_gpio(gpio)) return -EINVAL; index = get_gpio_index(gpio); bank = get_gpio_bank(gpio); return _pnx_gpio_request(bank, index); }
/** * gpio_get_value - Get the state of the specified pin of GPIO device * @gpio: gpio pin number within the device * * This function reads the state of the specified pin of the GPIO device. * * Return: 0 if the pin is low, 1 if pin is high. */ int gpio_get_value(unsigned gpio) { u32 data; unsigned int bank_num, bank_pin_num; if (check_gpio(gpio) < 0) return -1; zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); data = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); return (data >> bank_pin_num) & 1; }
int gpio_free(unsigned gpio) { if (check_gpio(gpio) < 0) return -1; if (unlikely(!is_reserved(gpio, gpio, 0))) { gpio_error(gpio); return -1; } unreserve(gpio, gpio); set_label(gpio, "free"); return 0; }
void gpio_labels(void) { int c, gpio; for (c = 0; c < MAX_RESOURCES; c++) { gpio = is_reserved(gpio, c, 1); if (!check_gpio(c) && gpio) printf("GPIO_%d:\t%s\tGPIO %s\n", c, get_label(c), get_gpio_dir(c) ? "OUTPUT" : "INPUT"); else if (is_reserved(peri, c, 1)) printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c)); else continue; } }
void Button< driver >::handle_callback(){ state_t new_state = check_gpio(); // Transition! if(state != new_state){ state = new_state; switch(new_state){ case ST_PRESSED: if(press_handler){ press_handler(press_param); } case ST_RELEASED: if(release_handler){ release_handler(release_param); } } } }
int pnx_gpio_write_pin(int gpio, int gpio_value) { struct gpio_bank *bank; unsigned long index; if (!check_gpio(gpio)) return -EINVAL; bank = get_gpio_bank(gpio); index = get_gpio_index(gpio); if (!check_gpio_requested(bank, index)) return -EINVAL; spin_lock(&bank->lock); _write_gpio_pin(bank, index, gpio_value); spin_unlock(&bank->lock); return 0; }
int omap_get_gpio_datain(int gpio) { struct gpio_bank *bank; void *reg; if (check_gpio(gpio) < 0) return -EINVAL; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_DATAIN; break; default: return -EINVAL; } return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; }
int pnx_gpio_set_mode(int gpio, int mode) { struct gpio_bank *bank; int index; if (!check_gpio(gpio)) return -EINVAL; bank = get_gpio_bank(gpio); index = get_gpio_index(gpio); if (!check_gpio_requested(bank, index)) return -EINVAL; spin_lock(&bank->lock); _set_gpio_mode(bank, get_gpio_index(gpio), mode); spin_unlock(&bank->lock); return 0; }
/* * gpio_proc_read() */ static int ubi_gpio_proc_read(char *buf, char **start, off_t offset, int len, int *unused_i, void *unused_v) { int c, outlen = 0; for (c = 0; c < MAX_UBICOM_GPIOS; c++) { if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) { len = sprintf(buf, "GPIO_%d:\t\tGPIO %s\n", c, ubi_get_gpio_dir(c) ? "OUTPUT" : "INPUT"); } else { continue; } buf += len; outlen += len; } return outlen; }