/* * Read the pin's value (works even if it's set up as output); * returns zero/nonzero. * * Note that changes are synched to the GPIO clock, so reading values back * right after you've set them may give old values. */ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio_controller *d = chip2controller(chip); struct davinci_gpio_regs __iomem *g = d->regs; return (1 << offset) & __raw_readl(&g->in_data); }
/* * Assuming the pin is muxed as a gpio output, set its output value. */ static void davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct davinci_gpio_controller *d = chip2controller(chip); struct davinci_gpio_regs __iomem *g = d->regs; __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); }
static int davinci_get_direction(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio_controller *d = chip2controller(chip); struct davinci_gpio_regs __iomem *g = d->regs; return ((readl_relaxed(&g->dir)) & (1 << offset)) ? GPIOF_DIR_IN : GPIOF_DIR_OUT; }
static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio_controller *ctlr = chip2controller(chip); struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; unsigned gpio = chip->base + offset; int ret; ret = gpio_reg_get_bit(regs->data_in, gpio); return ret ? 1 : 0; }
static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio_controller *ctlr = chip2controller(chip); struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; unsigned gpio = chip->base + offset; unsigned long flags; spin_lock_irqsave(&ctlr->lock, flags); gpio_reg_clear_bit(regs->enable, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); }
static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset) { struct davinci_gpio_controller *ctlr = chip2controller(chip); struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; unsigned gpio = chip->base + offset; unsigned long flags; spin_lock_irqsave(&ctlr->lock, flags); gpio_reg_set_bit(regs->direction, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); return 0; }
static void tnetv107x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct davinci_gpio_controller *ctlr = chip2controller(chip); struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; unsigned gpio = chip->base + offset; unsigned long flags; spin_lock_irqsave(&ctlr->lock, flags); if (value) gpio_reg_set_bit(regs->data_out, gpio); else gpio_reg_clear_bit(regs->data_out, gpio); spin_unlock_irqrestore(&ctlr->lock, flags); }
static inline int __davinci_direction(struct gpio_chip *chip, unsigned offset, bool out, int value) { struct davinci_gpio_controller *d = chip2controller(chip); struct davinci_gpio_regs __iomem *g = d->regs; u32 temp; u32 mask = 1 << offset; temp = readl_relaxed(&g->dir); if (out) { temp &= ~mask; writel_relaxed(mask, value ? &g->set_data : &g->clr_data); } else { temp |= mask; } writel_relaxed(temp, &g->dir); return 0; }
/* board setup code *MUST* setup pinmux and enable the GPIO clock. */ static inline int __davinci_direction(struct gpio_chip *chip, unsigned offset, bool out, int value) { struct davinci_gpio_controller *d = chip2controller(chip); struct davinci_gpio_regs __iomem *g = d->regs; unsigned long flags; u32 temp; u32 mask = 1 << offset; spin_lock_irqsave(&d->lock, flags); temp = __raw_readl(&g->dir); if (out) { temp &= ~mask; __raw_writel(mask, value ? &g->set_data : &g->clr_data); } else { temp |= mask; } __raw_writel(temp, &g->dir); spin_unlock_irqrestore(&d->lock, flags); return 0; }