diff options
author | Kukjin Kim <kgene.kim@samsung.com> | 2011-08-25 22:03:03 -0400 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2011-09-20 21:52:22 -0400 |
commit | 536137bc9ff1738a7bee9b31047a7cd56860180e (patch) | |
tree | 17e130f1048ca1b5a558e81970a459a9dbadc0e4 /drivers | |
parent | b6fd41e29dea9c6753b1843a77e50433e6123bcb (diff) |
gpio/s3c24xx: move gpio driver into drivers/gpio/
Cc: Ben Dooks <ben-linux@fluff.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/Kconfig | 4 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-s3c24xx.c | 283 |
3 files changed, 288 insertions, 0 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d539efd96d4b..5654e1b082af 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -135,6 +135,10 @@ config GPIO_PLAT_SAMSUNG | |||
135 | def_bool y | 135 | def_bool y |
136 | depends on SAMSUNG_GPIOLIB_4BIT | 136 | depends on SAMSUNG_GPIOLIB_4BIT |
137 | 137 | ||
138 | config GPIO_S3C24XX | ||
139 | def_bool y | ||
140 | depends on PLAT_S3C24XX | ||
141 | |||
138 | config GPIO_S5PC100 | 142 | config GPIO_S5PC100 |
139 | def_bool y | 143 | def_bool y |
140 | depends on CPU_S5PC100 | 144 | depends on CPU_S5PC100 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9588948c96f0..c7f1c00986c9 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -40,6 +40,7 @@ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | |||
40 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o | 40 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o |
41 | 41 | ||
42 | obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o | 42 | obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o |
43 | obj-$(CONFIG_GPIO_S3C24XX) += gpio-s3c24xx.o | ||
43 | obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o | 44 | obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o |
44 | obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o | 45 | obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o |
45 | 46 | ||
diff --git a/drivers/gpio/gpio-s3c24xx.c b/drivers/gpio/gpio-s3c24xx.c new file mode 100644 index 000000000000..ff6103130fe8 --- /dev/null +++ b/drivers/gpio/gpio-s3c24xx.c | |||
@@ -0,0 +1,283 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Simtec Electronics | ||
3 | * http://armlinux.simtec.co.uk/ | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * S3C24XX GPIOlib support | ||
7 | * | ||
8 | * 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 | * the Free Software Foundation; either version 2 of the License. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/sysdev.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <asm/irq.h> | ||
22 | |||
23 | #include <mach/hardware.h> | ||
24 | #include <mach/gpio-fns.h> | ||
25 | #include <mach/regs-gpio.h> | ||
26 | |||
27 | #include <plat/gpio-core.h> | ||
28 | #include <plat/gpio-cfg.h> | ||
29 | #include <plat/gpio-cfg-helpers.h> | ||
30 | #include <plat/pm.h> | ||
31 | |||
32 | static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) | ||
33 | { | ||
34 | return -EINVAL; | ||
35 | } | ||
36 | |||
37 | static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, | ||
38 | unsigned offset, int value) | ||
39 | { | ||
40 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
41 | void __iomem *base = ourchip->base; | ||
42 | unsigned long flags; | ||
43 | unsigned long dat; | ||
44 | unsigned long con; | ||
45 | |||
46 | local_irq_save(flags); | ||
47 | |||
48 | con = __raw_readl(base + 0x00); | ||
49 | dat = __raw_readl(base + 0x04); | ||
50 | |||
51 | dat &= ~(1 << offset); | ||
52 | if (value) | ||
53 | dat |= 1 << offset; | ||
54 | |||
55 | __raw_writel(dat, base + 0x04); | ||
56 | |||
57 | con &= ~(1 << offset); | ||
58 | |||
59 | __raw_writel(con, base + 0x00); | ||
60 | __raw_writel(dat, base + 0x04); | ||
61 | |||
62 | local_irq_restore(flags); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset) | ||
67 | { | ||
68 | if (offset < 4) | ||
69 | return IRQ_EINT0 + offset; | ||
70 | |||
71 | if (offset < 8) | ||
72 | return IRQ_EINT4 + offset - 4; | ||
73 | |||
74 | return -EINVAL; | ||
75 | } | ||
76 | |||
77 | static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { | ||
78 | .set_config = s3c_gpio_setcfg_s3c24xx_a, | ||
79 | .get_config = s3c_gpio_getcfg_s3c24xx_a, | ||
80 | }; | ||
81 | |||
82 | struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { | ||
83 | .set_config = s3c_gpio_setcfg_s3c24xx, | ||
84 | .get_config = s3c_gpio_getcfg_s3c24xx, | ||
85 | }; | ||
86 | |||
87 | struct s3c_gpio_chip s3c24xx_gpios[] = { | ||
88 | [0] = { | ||
89 | .base = S3C2410_GPACON, | ||
90 | .pm = __gpio_pm(&s3c_gpio_pm_1bit), | ||
91 | .config = &s3c24xx_gpiocfg_banka, | ||
92 | .chip = { | ||
93 | .base = S3C2410_GPA(0), | ||
94 | .owner = THIS_MODULE, | ||
95 | .label = "GPIOA", | ||
96 | .ngpio = 24, | ||
97 | .direction_input = s3c24xx_gpiolib_banka_input, | ||
98 | .direction_output = s3c24xx_gpiolib_banka_output, | ||
99 | }, | ||
100 | }, | ||
101 | [1] = { | ||
102 | .base = S3C2410_GPBCON, | ||
103 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
104 | .chip = { | ||
105 | .base = S3C2410_GPB(0), | ||
106 | .owner = THIS_MODULE, | ||
107 | .label = "GPIOB", | ||
108 | .ngpio = 16, | ||
109 | }, | ||
110 | }, | ||
111 | [2] = { | ||
112 | .base = S3C2410_GPCCON, | ||
113 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
114 | .chip = { | ||
115 | .base = S3C2410_GPC(0), | ||
116 | .owner = THIS_MODULE, | ||
117 | .label = "GPIOC", | ||
118 | .ngpio = 16, | ||
119 | }, | ||
120 | }, | ||
121 | [3] = { | ||
122 | .base = S3C2410_GPDCON, | ||
123 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
124 | .chip = { | ||
125 | .base = S3C2410_GPD(0), | ||
126 | .owner = THIS_MODULE, | ||
127 | .label = "GPIOD", | ||
128 | .ngpio = 16, | ||
129 | }, | ||
130 | }, | ||
131 | [4] = { | ||
132 | .base = S3C2410_GPECON, | ||
133 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
134 | .chip = { | ||
135 | .base = S3C2410_GPE(0), | ||
136 | .label = "GPIOE", | ||
137 | .owner = THIS_MODULE, | ||
138 | .ngpio = 16, | ||
139 | }, | ||
140 | }, | ||
141 | [5] = { | ||
142 | .base = S3C2410_GPFCON, | ||
143 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
144 | .chip = { | ||
145 | .base = S3C2410_GPF(0), | ||
146 | .owner = THIS_MODULE, | ||
147 | .label = "GPIOF", | ||
148 | .ngpio = 8, | ||
149 | .to_irq = s3c24xx_gpiolib_bankf_toirq, | ||
150 | }, | ||
151 | }, | ||
152 | [6] = { | ||
153 | .base = S3C2410_GPGCON, | ||
154 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
155 | .irq_base = IRQ_EINT8, | ||
156 | .chip = { | ||
157 | .base = S3C2410_GPG(0), | ||
158 | .owner = THIS_MODULE, | ||
159 | .label = "GPIOG", | ||
160 | .ngpio = 16, | ||
161 | .to_irq = samsung_gpiolib_to_irq, | ||
162 | }, | ||
163 | }, { | ||
164 | .base = S3C2410_GPHCON, | ||
165 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
166 | .chip = { | ||
167 | .base = S3C2410_GPH(0), | ||
168 | .owner = THIS_MODULE, | ||
169 | .label = "GPIOH", | ||
170 | .ngpio = 11, | ||
171 | }, | ||
172 | }, | ||
173 | /* GPIOS for the S3C2443 and later devices. */ | ||
174 | { | ||
175 | .base = S3C2440_GPJCON, | ||
176 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
177 | .chip = { | ||
178 | .base = S3C2410_GPJ(0), | ||
179 | .owner = THIS_MODULE, | ||
180 | .label = "GPIOJ", | ||
181 | .ngpio = 16, | ||
182 | }, | ||
183 | }, { | ||
184 | .base = S3C2443_GPKCON, | ||
185 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
186 | .chip = { | ||
187 | .base = S3C2410_GPK(0), | ||
188 | .owner = THIS_MODULE, | ||
189 | .label = "GPIOK", | ||
190 | .ngpio = 16, | ||
191 | }, | ||
192 | }, { | ||
193 | .base = S3C2443_GPLCON, | ||
194 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
195 | .chip = { | ||
196 | .base = S3C2410_GPL(0), | ||
197 | .owner = THIS_MODULE, | ||
198 | .label = "GPIOL", | ||
199 | .ngpio = 15, | ||
200 | }, | ||
201 | }, { | ||
202 | .base = S3C2443_GPMCON, | ||
203 | .pm = __gpio_pm(&s3c_gpio_pm_2bit), | ||
204 | .chip = { | ||
205 | .base = S3C2410_GPM(0), | ||
206 | .owner = THIS_MODULE, | ||
207 | .label = "GPIOM", | ||
208 | .ngpio = 2, | ||
209 | }, | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | static __init int s3c24xx_gpiolib_init(void) | ||
214 | { | ||
215 | struct s3c_gpio_chip *chip = s3c24xx_gpios; | ||
216 | int gpn; | ||
217 | |||
218 | for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) { | ||
219 | if (!chip->config) | ||
220 | chip->config = &s3c24xx_gpiocfg_default; | ||
221 | |||
222 | s3c_gpiolib_add(chip); | ||
223 | } | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | core_initcall(s3c24xx_gpiolib_init); | ||
228 | |||
229 | /* gpiolib wrappers until these are totally eliminated */ | ||
230 | |||
231 | void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) | ||
232 | { | ||
233 | int ret; | ||
234 | |||
235 | WARN_ON(to); /* should be none of these left */ | ||
236 | |||
237 | if (!to) { | ||
238 | /* if pull is enabled, try first with up, and if that | ||
239 | * fails, try using down */ | ||
240 | |||
241 | ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); | ||
242 | if (ret) | ||
243 | s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN); | ||
244 | } else { | ||
245 | s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); | ||
246 | } | ||
247 | } | ||
248 | EXPORT_SYMBOL(s3c2410_gpio_pullup); | ||
249 | |||
250 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) | ||
251 | { | ||
252 | /* do this via gpiolib until all users removed */ | ||
253 | |||
254 | gpio_request(pin, "temporary"); | ||
255 | gpio_set_value(pin, to); | ||
256 | gpio_free(pin); | ||
257 | } | ||
258 | EXPORT_SYMBOL(s3c2410_gpio_setpin); | ||
259 | |||
260 | unsigned int s3c2410_gpio_getpin(unsigned int pin) | ||
261 | { | ||
262 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
263 | unsigned long offs = pin - chip->chip.base; | ||
264 | |||
265 | return __raw_readl(chip->base + 0x04) & (1<< offs); | ||
266 | } | ||
267 | EXPORT_SYMBOL(s3c2410_gpio_getpin); | ||
268 | |||
269 | unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) | ||
270 | { | ||
271 | unsigned long flags; | ||
272 | unsigned long misccr; | ||
273 | |||
274 | local_irq_save(flags); | ||
275 | misccr = __raw_readl(S3C24XX_MISCCR); | ||
276 | misccr &= ~clear; | ||
277 | misccr ^= change; | ||
278 | __raw_writel(misccr, S3C24XX_MISCCR); | ||
279 | local_irq_restore(flags); | ||
280 | |||
281 | return misccr; | ||
282 | } | ||
283 | EXPORT_SYMBOL(s3c2410_modify_misccr); | ||