/* * Acknowledge a gpio pin's interrupt by clearing the bit in the isr. * If the GPIO interrupt is level triggered, it also disables the interrupt. * @param irq a gpio virtual irq number */ static void gpio_ack_irq(u32 irq) { u32 gpio = MXC_IRQ_TO_GPIO(irq); u32 index = GPIO_TO_INDEX(gpio); struct gpio_port *port = get_gpio_port(gpio); _clear_gpio_irqstatus(port, GPIO_TO_INDEX(gpio)); if (port->irq_is_level_map & (1 << index)) { gpio_mask_irq(irq); } }
/* * Enable a gpio pin's interrupt by clearing the bit in the imr. * @param irq a gpio virtual irq number */ static void gpio_unmask_irq(u32 irq) { u32 gpio = MXC_IRQ_TO_GPIO(irq); struct gpio_port *port = get_gpio_port(gpio); _set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 1); }
/*! * 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 imx_gpio_get_pin(unsigned int pin) { u32 gpio_num = IOMUX_TO_GPIO(pin); u32 gpio_off = GPIO_TO_INDEX(gpio_num); u32 baddr = PORT_BADDR(GPIO_TO_PORT(gpio_num)); return (__REG(baddr + GPIO_DR) & (1 << gpio_off)) ? 1 : 0; }
void imx_gpio_pin_cfg_dir(unsigned int pin, int dir) { u32 gpio_num = IOMUX_TO_GPIO(pin); u32 gpio_off = GPIO_TO_INDEX(gpio_num); u32 baddr = PORT_BADDR(GPIO_TO_PORT(gpio_num)); if (dir) __REG(baddr + GPIO_GDIR) |= (1 << gpio_off); else __REG(baddr + GPIO_GDIR) &= ~(1 << gpio_off); }
void imx_gpio_set_pin(unsigned int pin, int val) { u32 gpio_num = IOMUX_TO_GPIO(pin); u32 gpio_off = GPIO_TO_INDEX(gpio_num); u32 baddr = PORT_BADDR(GPIO_TO_PORT(gpio_num)); if (val) __REG(baddr + GPIO_DR) |= (1 << gpio_off); else __REG(baddr + GPIO_DR) &= ~(1 << gpio_off); }
/*! * 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); }
/* * Enable a gpio pin's interrupt by clearing the bit in the imr. * @param irq a gpio virtual irq number */ static int gpio_set_irq_type(u32 irq, u32 type) { u32 gpio = MXC_IRQ_TO_GPIO(irq); struct gpio_port *port = get_gpio_port(gpio); switch (type) { case IRQT_RISING: _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), GPIO_INT_RISE_EDGE); set_irq_handler(irq, do_edge_IRQ); port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio)); break; case IRQT_FALLING: _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), GPIO_INT_FALL_EDGE); set_irq_handler(irq, do_edge_IRQ); port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio)); break; case IRQT_LOW: _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), GPIO_INT_LOW_LEV); set_irq_handler(irq, do_level_IRQ); port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio); break; case IRQT_HIGH: _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), GPIO_INT_HIGH_LEV); set_irq_handler(irq, do_level_IRQ); port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio); break; case IRQT_BOTHEDGE: default: return -EINVAL; break; } return 0; }