]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/mips/alchemy/common/gpio.c
ACPI: idle: rename lapic timer workaround routines
[linux-2.6.git] / arch / mips / alchemy / common / gpio.c
1 /*
2  *  Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
3  *      Architecture specific GPIO support
4  *
5  *  This program is free software; you can redistribute  it and/or modify it
6  *  under  the terms of  the GNU General  Public License as published by the
7  *  Free Software Foundation;  either version 2 of the  License, or (at your
8  *  option) any later version.
9  *
10  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
11  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
12  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
13  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
14  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
16  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
18  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20  *
21  *  You should have received a copy of the  GNU General Public License along
22  *  with this program; if not, write  to the Free Software Foundation, Inc.,
23  *  675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  *  Notes :
26  *      au1000 SoC have only one GPIO line : GPIO1
27  *      others have a second one : GPIO2
28  */
29
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/types.h>
33 #include <linux/platform_device.h>
34 #include <linux/gpio.h>
35
36 #include <asm/mach-au1x00/au1000.h>
37 #include <asm/gpio.h>
38
39 struct au1000_gpio_chip {
40         struct gpio_chip        chip;
41         void __iomem            *regbase;
42 };
43
44 #if !defined(CONFIG_SOC_AU1000)
45 static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset)
46 {
47         u32 mask = 1 << offset;
48         struct au1000_gpio_chip *gpch;
49
50         gpch = container_of(chip, struct au1000_gpio_chip, chip);
51         return readl(gpch->regbase + AU1000_GPIO2_ST) & mask;
52 }
53
54 static void au1000_gpio2_set(struct gpio_chip *chip,
55                                 unsigned offset, int value)
56 {
57         u32 mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
58         struct au1000_gpio_chip *gpch;
59         unsigned long flags;
60
61         gpch = container_of(chip, struct au1000_gpio_chip, chip);
62
63         local_irq_save(flags);
64         writel(mask, gpch->regbase + AU1000_GPIO2_OUT);
65         local_irq_restore(flags);
66 }
67
68 static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
69 {
70         u32 mask = 1 << offset;
71         u32 tmp;
72         struct au1000_gpio_chip *gpch;
73         unsigned long flags;
74
75         gpch = container_of(chip, struct au1000_gpio_chip, chip);
76
77         local_irq_save(flags);
78         tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
79         tmp &= ~mask;
80         writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
81         local_irq_restore(flags);
82
83         return 0;
84 }
85
86 static int au1000_gpio2_direction_output(struct gpio_chip *chip,
87                                         unsigned offset, int value)
88 {
89         u32 mask = 1 << offset;
90         u32 out_mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
91         u32 tmp;
92         struct au1000_gpio_chip *gpch;
93         unsigned long flags;
94
95         gpch = container_of(chip, struct au1000_gpio_chip, chip);
96
97         local_irq_save(flags);
98         tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
99         tmp |= mask;
100         writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
101         writel(out_mask, gpch->regbase + AU1000_GPIO2_OUT);
102         local_irq_restore(flags);
103
104         return 0;
105 }
106 #endif /* !defined(CONFIG_SOC_AU1000) */
107
108 static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset)
109 {
110         u32 mask = 1 << offset;
111         struct au1000_gpio_chip *gpch;
112
113         gpch = container_of(chip, struct au1000_gpio_chip, chip);
114         return readl(gpch->regbase + AU1000_GPIO1_ST) & mask;
115 }
116
117 static void au1000_gpio1_set(struct gpio_chip *chip,
118                                 unsigned offset, int value)
119 {
120         u32 mask = 1 << offset;
121         u32 reg_offset;
122         struct au1000_gpio_chip *gpch;
123         unsigned long flags;
124
125         gpch = container_of(chip, struct au1000_gpio_chip, chip);
126
127         if (value)
128                 reg_offset = AU1000_GPIO1_OUT;
129         else
130                 reg_offset = AU1000_GPIO1_CLR;
131
132         local_irq_save(flags);
133         writel(mask, gpch->regbase + reg_offset);
134         local_irq_restore(flags);
135 }
136
137 static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
138 {
139         u32 mask = 1 << offset;
140         struct au1000_gpio_chip *gpch;
141
142         gpch = container_of(chip, struct au1000_gpio_chip, chip);
143         writel(mask, gpch->regbase + AU1000_GPIO1_ST);
144
145         return 0;
146 }
147
148 static int au1000_gpio1_direction_output(struct gpio_chip *chip,
149                                         unsigned offset, int value)
150 {
151         u32 mask = 1 << offset;
152         struct au1000_gpio_chip *gpch;
153
154         gpch = container_of(chip, struct au1000_gpio_chip, chip);
155
156         writel(mask, gpch->regbase + AU1000_GPIO1_TRI_OUT);
157         au1000_gpio1_set(chip, offset, value);
158
159         return 0;
160 }
161
162 struct au1000_gpio_chip au1000_gpio_chip[] = {
163         [0] = {
164                 .regbase                        = (void __iomem *)SYS_BASE,
165                 .chip = {
166                         .label                  = "au1000-gpio1",
167                         .direction_input        = au1000_gpio1_direction_input,
168                         .direction_output       = au1000_gpio1_direction_output,
169                         .get                    = au1000_gpio1_get,
170                         .set                    = au1000_gpio1_set,
171                         .base                   = 0,
172                         .ngpio                  = 32,
173                 },
174         },
175 #if !defined(CONFIG_SOC_AU1000)
176         [1] = {
177                 .regbase                        = (void __iomem *)GPIO2_BASE,
178                 .chip = {
179                         .label                  = "au1000-gpio2",
180                         .direction_input        = au1000_gpio2_direction_input,
181                         .direction_output       = au1000_gpio2_direction_output,
182                         .get                    = au1000_gpio2_get,
183                         .set                    = au1000_gpio2_set,
184                         .base                   = AU1XXX_GPIO_BASE,
185                         .ngpio                  = 32,
186                 },
187         },
188 #endif
189 };
190
191 static int __init au1000_gpio_init(void)
192 {
193         gpiochip_add(&au1000_gpio_chip[0].chip);
194 #if !defined(CONFIG_SOC_AU1000)
195         gpiochip_add(&au1000_gpio_chip[1].chip);
196 #endif
197
198         return 0;
199 }
200 arch_initcall(au1000_gpio_init);
201