ramips: properly setup the FEATURES variable
[openwrt.git] / target / linux / ramips / files-3.7 / arch / mips / ralink / common / gpio.c
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
16 static 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
24 static 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
29 static 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
34 static 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
49 static 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
70 static 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
79 static 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
88 static __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 }