1/* 2 * Ralink SoC specific GPIO support 3 * 4 * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation. 9 */ 10 11#include <linux/init.h> 12#include <linux/io.h> 13 14#include <asm/mach-ralink/ramips_gpio.h> 15 16static inline struct ramips_gpio_chip *to_ramips_gpio(struct gpio_chip *chip) 17{ 18 struct ramips_gpio_chip *rg; 19 20 rg = container_of(chip, struct ramips_gpio_chip, chip); 21 return rg; 22} 23 24static inline void ramips_gpio_wr(struct ramips_gpio_chip *rg, u8 reg, u32 val) 25{ 26 __raw_writel(val, rg->regs_base + rg->regs[reg]); 27} 28 29static inline u32 ramips_gpio_rr(struct ramips_gpio_chip *rg, u8 reg) 30{ 31 return __raw_readl(rg->regs_base + rg->regs[reg]); 32} 33 34static int ramips_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 35{ 36 struct ramips_gpio_chip *rg = to_ramips_gpio(chip); 37 unsigned long flags; 38 u32 t; 39 40 spin_lock_irqsave(&rg->lock, flags); 41 t = ramips_gpio_rr(rg, RAMIPS_GPIO_REG_DIR); 42 t &= ~(1 << offset); 43 ramips_gpio_wr(rg, RAMIPS_GPIO_REG_DIR, t); 44 spin_unlock_irqrestore(&rg->lock, flags); 45 46 return 0; 47} 48 49static int ramips_gpio_direction_output(struct gpio_chip *chip, 50 unsigned offset, int value) 51{ 52 struct ramips_gpio_chip *rg = to_ramips_gpio(chip); 53 unsigned long flags; 54 u32 reg; 55 u32 t; 56 57 reg = (value) ? RAMIPS_GPIO_REG_SET : RAMIPS_GPIO_REG_RESET; 58 59 spin_lock_irqsave(&rg->lock, flags); 60 ramips_gpio_wr(rg, reg, 1 << offset); 61 62 t = ramips_gpio_rr(rg, RAMIPS_GPIO_REG_DIR); 63 t |= 1 << offset; 64 ramips_gpio_wr(rg, RAMIPS_GPIO_REG_DIR, t); 65 spin_unlock_irqrestore(&rg->lock, flags); 66 67 return 0; 68} 69 70static void ramips_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 71{ 72 struct ramips_gpio_chip *rg = to_ramips_gpio(chip); 73 u32 reg; 74 75 reg = (value) ? RAMIPS_GPIO_REG_SET : RAMIPS_GPIO_REG_RESET; 76 ramips_gpio_wr(rg, reg, 1 << offset); 77} 78 79static int ramips_gpio_get(struct gpio_chip *chip, unsigned offset) 80{ 81 struct ramips_gpio_chip *rg = to_ramips_gpio(chip); 82 u32 t; 83 84 t = ramips_gpio_rr(rg, RAMIPS_GPIO_REG_DATA); 85 return !!(t & (1 << offset)); 86} 87 88static __init void ramips_gpio_chip_add(struct ramips_gpio_chip *rg) 89{ 90 spin_lock_init(&rg->lock); 91 92 rg->regs_base = ioremap(rg->map_base, rg->map_size); 93 94 rg->chip.direction_input = ramips_gpio_direction_input; 95 rg->chip.direction_output = ramips_gpio_direction_output; 96 rg->chip.get = ramips_gpio_get; 97 rg->chip.set = ramips_gpio_set; 98 99 /* set polarity to low for all lines */ 100 ramips_gpio_wr(rg, RAMIPS_GPIO_REG_POL, 0); 101 102 gpiochip_add(&rg->chip); 103} 104 105__init int ramips_gpio_init(struct ramips_gpio_data *data) 106{ 107 int i; 108 109 for (i = 0; i < data->num_chips; i++) 110 ramips_gpio_chip_add(&data->chips[i]); 111 112 return 0; 113} 114