aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2011-08-25 22:03:03 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-09-20 21:52:22 -0400
commit536137bc9ff1738a7bee9b31047a7cd56860180e (patch)
tree17e130f1048ca1b5a558e81970a459a9dbadc0e4 /drivers
parentb6fd41e29dea9c6753b1843a77e50433e6123bcb (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/Kconfig4
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-s3c24xx.c283
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
138config GPIO_S3C24XX
139 def_bool y
140 depends on PLAT_S3C24XX
141
138config GPIO_S5PC100 142config 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
40obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o 40obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
41 41
42obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o 42obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
43obj-$(CONFIG_GPIO_S3C24XX) += gpio-s3c24xx.o
43obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o 44obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
44obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o 45obj-$(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
32static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
33{
34 return -EINVAL;
35}
36
37static 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
66static 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
77static 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
82struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
83 .set_config = s3c_gpio_setcfg_s3c24xx,
84 .get_config = s3c_gpio_getcfg_s3c24xx,
85};
86
87struct 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
213static __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}
227core_initcall(s3c24xx_gpiolib_init);
228
229/* gpiolib wrappers until these are totally eliminated */
230
231void 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}
248EXPORT_SYMBOL(s3c2410_gpio_pullup);
249
250void 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}
258EXPORT_SYMBOL(s3c2410_gpio_setpin);
259
260unsigned 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}
267EXPORT_SYMBOL(s3c2410_gpio_getpin);
268
269unsigned 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}
283EXPORT_SYMBOL(s3c2410_modify_misccr);