diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-07-03 06:24:25 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2008-07-03 11:51:23 -0400 |
commit | f348a2a2817e9d24b1edd4befc9659ec83501ca5 (patch) | |
tree | 99eb68575f9ca61c1de21502db2c41bbf2716609 | |
parent | ed9137f10377a59487cf43c76dd0d3bbf489d799 (diff) |
[ARM] S3C24XX: Add gpiolib support
Add support for gpilib on all S3C24XX platforms.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
-rw-r--r-- | arch/arm/plat-s3c24xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/gpiolib.c | 259 | ||||
-rw-r--r-- | include/asm-arm/arch-s3c2410/gpio.h | 74 |
4 files changed, 273 insertions, 62 deletions
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index b66fb3c4e228..1521f1ce3b2b 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig | |||
@@ -9,6 +9,7 @@ config PLAT_S3C24XX | |||
9 | depends on ARCH_S3C2410 | 9 | depends on ARCH_S3C2410 |
10 | default y if ARCH_S3C2410 | 10 | default y if ARCH_S3C2410 |
11 | select NO_IOPORT | 11 | select NO_IOPORT |
12 | select HAVE_GPIO_LIB | ||
12 | help | 13 | help |
13 | Base platform code for any Samsung S3C24XX device | 14 | Base platform code for any Samsung S3C24XX device |
14 | 15 | ||
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 131d20237dd7..b91e62585684 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile | |||
@@ -16,6 +16,7 @@ obj-y += cpu.o | |||
16 | obj-y += irq.o | 16 | obj-y += irq.o |
17 | obj-y += devs.o | 17 | obj-y += devs.o |
18 | obj-y += gpio.o | 18 | obj-y += gpio.o |
19 | obj-y += gpiolib.o | ||
19 | obj-y += time.o | 20 | obj-y += time.o |
20 | obj-y += clock.o | 21 | obj-y += clock.o |
21 | 22 | ||
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c new file mode 100644 index 000000000000..825d8d0c5ca2 --- /dev/null +++ b/arch/arm/plat-s3c24xx/gpiolib.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* linux/arch/arm/plat-s3c24xx/gpiolib.c | ||
2 | * | ||
3 | * Copyright (c) 2008 Simtec Electronics | ||
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * S3C24XX GPIOlib support | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | ||
21 | |||
22 | #include <asm/hardware.h> | ||
23 | #include <asm/irq.h> | ||
24 | |||
25 | #include <asm/arch/regs-gpio.h> | ||
26 | |||
27 | struct s3c24xx_gpio_chip { | ||
28 | struct gpio_chip chip; | ||
29 | void __iomem *base; | ||
30 | }; | ||
31 | |||
32 | static inline struct s3c24xx_gpio_chip *to_s3c_chip(struct gpio_chip *gpc) | ||
33 | { | ||
34 | return container_of(gpc, struct s3c24xx_gpio_chip, chip); | ||
35 | } | ||
36 | |||
37 | /* these routines are exported for use by other parts of the platform | ||
38 | * and system support, but are not intended to be used directly by the | ||
39 | * drivers themsevles. | ||
40 | */ | ||
41 | |||
42 | int s3c24xx_gpiolib_input(struct gpio_chip *chip, unsigned offset) | ||
43 | { | ||
44 | struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); | ||
45 | void __iomem *base = ourchip->base; | ||
46 | unsigned long flags; | ||
47 | unsigned long con; | ||
48 | |||
49 | local_irq_save(flags); | ||
50 | |||
51 | con = __raw_readl(base + 0x00); | ||
52 | con &= ~(3 << (offset * 2)); | ||
53 | con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); | ||
54 | |||
55 | __raw_writel(con, base + 0x00); | ||
56 | |||
57 | local_irq_restore(flags); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | int s3c24xx_gpiolib_output(struct gpio_chip *chip, | ||
62 | unsigned offset, int value) | ||
63 | { | ||
64 | struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); | ||
65 | void __iomem *base = ourchip->base; | ||
66 | unsigned long flags; | ||
67 | unsigned long dat; | ||
68 | unsigned long con; | ||
69 | |||
70 | local_irq_save(flags); | ||
71 | |||
72 | dat = __raw_readl(base + 0x04); | ||
73 | dat &= ~(1 << offset); | ||
74 | if (value) | ||
75 | dat |= 1 << offset; | ||
76 | __raw_writel(dat, base + 0x04); | ||
77 | |||
78 | con = __raw_readl(base + 0x00); | ||
79 | con &= ~(3 << (offset * 2)); | ||
80 | con |= (S3C2410_GPIO_OUTPUT & 0xf) << (offset * 2); | ||
81 | |||
82 | __raw_writel(con, base + 0x00); | ||
83 | __raw_writel(dat, base + 0x04); | ||
84 | |||
85 | local_irq_restore(flags); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | void s3c24xx_gpiolib_set(struct gpio_chip *chip, unsigned offset, int value) | ||
90 | { | ||
91 | struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); | ||
92 | void __iomem *base = ourchip->base; | ||
93 | unsigned long flags; | ||
94 | unsigned long dat; | ||
95 | |||
96 | local_irq_save(flags); | ||
97 | |||
98 | dat = __raw_readl(base + 0x04); | ||
99 | dat &= ~(1 << offset); | ||
100 | if (value) | ||
101 | dat |= 1 << offset; | ||
102 | __raw_writel(dat, base + 0x04); | ||
103 | |||
104 | local_irq_restore(flags); | ||
105 | } | ||
106 | |||
107 | int s3c24xx_gpiolib_get(struct gpio_chip *chip, unsigned offset) | ||
108 | { | ||
109 | struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); | ||
110 | unsigned long val; | ||
111 | |||
112 | val = __raw_readl(ourchip->base + 0x04); | ||
113 | val >>= offset; | ||
114 | val &= 1; | ||
115 | |||
116 | return val; | ||
117 | } | ||
118 | |||
119 | static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) | ||
120 | { | ||
121 | return -EINVAL; | ||
122 | } | ||
123 | |||
124 | static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, | ||
125 | unsigned offset, int value) | ||
126 | { | ||
127 | struct s3c24xx_gpio_chip *ourchip = to_s3c_chip(chip); | ||
128 | void __iomem *base = ourchip->base; | ||
129 | unsigned long flags; | ||
130 | unsigned long dat; | ||
131 | unsigned long con; | ||
132 | |||
133 | local_irq_save(flags); | ||
134 | |||
135 | con = __raw_readl(base + 0x00); | ||
136 | dat = __raw_readl(base + 0x04); | ||
137 | |||
138 | dat &= ~(1 << offset); | ||
139 | if (value) | ||
140 | dat |= 1 << offset; | ||
141 | |||
142 | __raw_writel(dat, base + 0x04); | ||
143 | |||
144 | con &= ~(1 << offset); | ||
145 | |||
146 | __raw_writel(con, base + 0x00); | ||
147 | __raw_writel(dat, base + 0x04); | ||
148 | |||
149 | local_irq_restore(flags); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | |||
154 | struct s3c24xx_gpio_chip gpios[] = { | ||
155 | [0] = { | ||
156 | .base = S3C24XX_GPIO_BASE(S3C2410_GPA0), | ||
157 | .chip = { | ||
158 | .base = S3C2410_GPA0, | ||
159 | .owner = THIS_MODULE, | ||
160 | .label = "GPIOA", | ||
161 | .ngpio = 24, | ||
162 | .direction_input = s3c24xx_gpiolib_banka_input, | ||
163 | .direction_output = s3c24xx_gpiolib_banka_output, | ||
164 | .set = s3c24xx_gpiolib_set, | ||
165 | .get = s3c24xx_gpiolib_get, | ||
166 | }, | ||
167 | }, | ||
168 | [1] = { | ||
169 | .base = S3C24XX_GPIO_BASE(S3C2410_GPB0), | ||
170 | .chip = { | ||
171 | .base = S3C2410_GPB0, | ||
172 | .owner = THIS_MODULE, | ||
173 | .label = "GPIOB", | ||
174 | .ngpio = 16, | ||
175 | .direction_input = s3c24xx_gpiolib_input, | ||
176 | .direction_output = s3c24xx_gpiolib_output, | ||
177 | .set = s3c24xx_gpiolib_set, | ||
178 | .get = s3c24xx_gpiolib_get, | ||
179 | }, | ||
180 | }, | ||
181 | [2] = { | ||
182 | .base = S3C24XX_GPIO_BASE(S3C2410_GPC0), | ||
183 | .chip = { | ||
184 | .base = S3C2410_GPC0, | ||
185 | .owner = THIS_MODULE, | ||
186 | .label = "GPIOC", | ||
187 | .ngpio = 16, | ||
188 | .direction_input = s3c24xx_gpiolib_input, | ||
189 | .direction_output = s3c24xx_gpiolib_output, | ||
190 | .set = s3c24xx_gpiolib_set, | ||
191 | .get = s3c24xx_gpiolib_get, | ||
192 | }, | ||
193 | }, | ||
194 | [3] = { | ||
195 | .base = S3C24XX_GPIO_BASE(S3C2410_GPD0), | ||
196 | .chip = { | ||
197 | .base = S3C2410_GPD0, | ||
198 | .owner = THIS_MODULE, | ||
199 | .label = "GPIOD", | ||
200 | .ngpio = 16, | ||
201 | .direction_input = s3c24xx_gpiolib_input, | ||
202 | .direction_output = s3c24xx_gpiolib_output, | ||
203 | .set = s3c24xx_gpiolib_set, | ||
204 | .get = s3c24xx_gpiolib_get, | ||
205 | }, | ||
206 | }, | ||
207 | [4] = { | ||
208 | .base = S3C24XX_GPIO_BASE(S3C2410_GPE0), | ||
209 | .chip = { | ||
210 | .base = S3C2410_GPE0, | ||
211 | .label = "GPIOE", | ||
212 | .owner = THIS_MODULE, | ||
213 | .ngpio = 16, | ||
214 | .direction_input = s3c24xx_gpiolib_input, | ||
215 | .direction_output = s3c24xx_gpiolib_output, | ||
216 | .set = s3c24xx_gpiolib_set, | ||
217 | .get = s3c24xx_gpiolib_get, | ||
218 | }, | ||
219 | }, | ||
220 | [5] = { | ||
221 | .base = S3C24XX_GPIO_BASE(S3C2410_GPF0), | ||
222 | .chip = { | ||
223 | .base = S3C2410_GPF0, | ||
224 | .owner = THIS_MODULE, | ||
225 | .label = "GPIOF", | ||
226 | .ngpio = 8, | ||
227 | .direction_input = s3c24xx_gpiolib_input, | ||
228 | .direction_output = s3c24xx_gpiolib_output, | ||
229 | .set = s3c24xx_gpiolib_set, | ||
230 | .get = s3c24xx_gpiolib_get, | ||
231 | }, | ||
232 | }, | ||
233 | [6] = { | ||
234 | .base = S3C24XX_GPIO_BASE(S3C2410_GPG0), | ||
235 | .chip = { | ||
236 | .base = S3C2410_GPG0, | ||
237 | .owner = THIS_MODULE, | ||
238 | .label = "GPIOG", | ||
239 | .ngpio = 10, | ||
240 | .direction_input = s3c24xx_gpiolib_input, | ||
241 | .direction_output = s3c24xx_gpiolib_output, | ||
242 | .set = s3c24xx_gpiolib_set, | ||
243 | .get = s3c24xx_gpiolib_get, | ||
244 | }, | ||
245 | }, | ||
246 | }; | ||
247 | |||
248 | static __init int s3c24xx_gpiolib_init(void) | ||
249 | { | ||
250 | struct s3c24xx_gpio_chip *chip = gpios; | ||
251 | int gpn; | ||
252 | |||
253 | for (gpn = 0; gpn < ARRAY_SIZE(gpios); gpn++, chip++) | ||
254 | gpiochip_add(&chip->chip); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | arch_initcall(s3c24xx_gpiolib_init); | ||
diff --git a/include/asm-arm/arch-s3c2410/gpio.h b/include/asm-arm/arch-s3c2410/gpio.h index 7583895fd336..18e10d2c35ea 100644 --- a/include/asm-arm/arch-s3c2410/gpio.h +++ b/include/asm-arm/arch-s3c2410/gpio.h | |||
@@ -1,68 +1,18 @@ | |||
1 | /* | 1 | /* linux/include/asm-arm/arch-s3c2410/gpio.h |
2 | * linux/include/asm-arm/arch-s3c2410/gpio.h | ||
3 | * | 2 | * |
4 | * S3C2410 GPIO wrappers for arch-neutral GPIO calls | 3 | * Copyright (c) 2008 Simtec Electronics |
4 | * http://armlinux.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | 6 | * |
6 | * Written by Philipp Zabel <philipp.zabel@gmail.com> | 7 | * S3C2410 - GPIO lib support |
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License version 2 as |
10 | * the Free Software Foundation; either version 2 of the License, or | 11 | * published by the Free Software Foundation. |
11 | * (at your option) any later version. | 12 | */ |
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef __ASM_ARCH_S3C2410_GPIO_H | ||
25 | #define __ASM_ARCH_S3C2410_GPIO_H | ||
26 | |||
27 | #include <asm/irq.h> | ||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/arch/regs-gpio.h> | ||
30 | |||
31 | static inline int gpio_request(unsigned gpio, const char *label) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static inline void gpio_free(unsigned gpio) | ||
37 | { | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | static inline int gpio_direction_input(unsigned gpio) | ||
42 | { | ||
43 | s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_INPUT); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static inline int gpio_direction_output(unsigned gpio, int value) | ||
48 | { | ||
49 | s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT); | ||
50 | /* REVISIT can we write the value first, to avoid glitching? */ | ||
51 | s3c2410_gpio_setpin(gpio, value); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | #define gpio_get_value(gpio) s3c2410_gpio_getpin(gpio) | ||
56 | #define gpio_set_value(gpio,value) s3c2410_gpio_setpin(gpio, value) | ||
57 | |||
58 | #include <asm-generic/gpio.h> /* cansleep wrappers */ | ||
59 | |||
60 | #ifdef CONFIG_CPU_S3C2400 | ||
61 | #define gpio_to_irq(gpio) s3c2400_gpio_getirq(gpio) | ||
62 | #else | ||
63 | #define gpio_to_irq(gpio) s3c2410_gpio_getirq(gpio) | ||
64 | #endif | ||
65 | 13 | ||
66 | /* FIXME implement irq_to_gpio() */ | 14 | #define gpio_get_value __gpio_get_value |
15 | #define gpio_set_value __gpio_set_value | ||
16 | #define gpio_cansleep __gpio_cansleep | ||
67 | 17 | ||
68 | #endif | 18 | #include <asm-generic/gpio.h> |