aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s3c24xx/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-s3c24xx/gpio.c')
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c150
1 files changed, 22 insertions, 128 deletions
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
index 5467470badfd..2f3d7c089dfa 100644
--- a/arch/arm/plat-s3c24xx/gpio.c
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/plat-s3c24xx/gpio.c 1/* linux/arch/arm/plat-s3c24xx/gpio.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C24XX GPIO support 6 * S3C24XX GPIO support
@@ -20,12 +20,12 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/ 21*/
22 22
23
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
28#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/gpio.h>
29#include <linux/io.h> 29#include <linux/io.h>
30 30
31#include <mach/hardware.h> 31#include <mach/hardware.h>
@@ -34,133 +34,46 @@
34 34
35#include <mach/regs-gpio.h> 35#include <mach/regs-gpio.h>
36 36
37void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) 37#include <plat/gpio-core.h>
38{
39 void __iomem *base = S3C24XX_GPIO_BASE(pin);
40 unsigned long mask;
41 unsigned long con;
42 unsigned long flags;
43 38
44 if (pin < S3C2410_GPIO_BANKB) { 39/* gpiolib wrappers until these are totally eliminated */
45 mask = 1 << S3C2410_GPIO_OFFSET(pin);
46 } else {
47 mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
48 }
49
50 switch (function) {
51 case S3C2410_GPIO_LEAVE:
52 mask = 0;
53 function = 0;
54 break;
55
56 case S3C2410_GPIO_INPUT:
57 case S3C2410_GPIO_OUTPUT:
58 case S3C2410_GPIO_SFN2:
59 case S3C2410_GPIO_SFN3:
60 if (pin < S3C2410_GPIO_BANKB) {
61 function -= 1;
62 function &= 1;
63 function <<= S3C2410_GPIO_OFFSET(pin);
64 } else {
65 function &= 3;
66 function <<= S3C2410_GPIO_OFFSET(pin)*2;
67 }
68 }
69
70 /* modify the specified register wwith IRQs off */
71
72 local_irq_save(flags);
73
74 con = __raw_readl(base + 0x00);
75 con &= ~mask;
76 con |= function;
77
78 __raw_writel(con, base + 0x00);
79
80 local_irq_restore(flags);
81}
82
83EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
84
85unsigned int s3c2410_gpio_getcfg(unsigned int pin)
86{
87 void __iomem *base = S3C24XX_GPIO_BASE(pin);
88 unsigned long val = __raw_readl(base);
89
90 if (pin < S3C2410_GPIO_BANKB) {
91 val >>= S3C2410_GPIO_OFFSET(pin);
92 val &= 1;
93 val += 1;
94 } else {
95 val >>= S3C2410_GPIO_OFFSET(pin)*2;
96 val &= 3;
97 }
98
99 return val | S3C2410_GPIO_INPUT;
100}
101
102EXPORT_SYMBOL(s3c2410_gpio_getcfg);
103 40
104void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) 41void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
105{ 42{
106 void __iomem *base = S3C24XX_GPIO_BASE(pin); 43 int ret;
107 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
108 unsigned long flags;
109 unsigned long up;
110 44
111 if (pin < S3C2410_GPIO_BANKB) 45 WARN_ON(to); /* should be none of these left */
112 return;
113 46
114 local_irq_save(flags); 47 if (!to) {
115 48 /* if pull is enabled, try first with up, and if that
116 up = __raw_readl(base + 0x08); 49 * fails, try using down */
117 up &= ~(1L << offs);
118 up |= to << offs;
119 __raw_writel(up, base + 0x08);
120 50
121 local_irq_restore(flags); 51 ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
52 if (ret)
53 s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
54 } else {
55 s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
56 }
122} 57}
123
124EXPORT_SYMBOL(s3c2410_gpio_pullup); 58EXPORT_SYMBOL(s3c2410_gpio_pullup);
125 59
126int s3c2410_gpio_getpull(unsigned int pin)
127{
128 void __iomem *base = S3C24XX_GPIO_BASE(pin);
129 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
130
131 if (pin < S3C2410_GPIO_BANKB)
132 return -EINVAL;
133
134 return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
135}
136
137EXPORT_SYMBOL(s3c2410_gpio_getpull);
138
139void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) 60void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
140{ 61{
141 void __iomem *base = S3C24XX_GPIO_BASE(pin); 62 /* do this via gpiolib until all users removed */
142 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
143 unsigned long flags;
144 unsigned long dat;
145 63
146 local_irq_save(flags); 64 gpio_request(pin, "temporary");
147 65 gpio_set_value(pin, to);
148 dat = __raw_readl(base + 0x04); 66 gpio_free(pin);
149 dat &= ~(1 << offs);
150 dat |= to << offs;
151 __raw_writel(dat, base + 0x04);
152
153 local_irq_restore(flags);
154} 67}
155 68
156EXPORT_SYMBOL(s3c2410_gpio_setpin); 69EXPORT_SYMBOL(s3c2410_gpio_setpin);
157 70
158unsigned int s3c2410_gpio_getpin(unsigned int pin) 71unsigned int s3c2410_gpio_getpin(unsigned int pin)
159{ 72{
160 void __iomem *base = S3C24XX_GPIO_BASE(pin); 73 struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
161 unsigned long offs = S3C2410_GPIO_OFFSET(pin); 74 unsigned long offs = pin - chip->chip.base;
162 75
163 return __raw_readl(base + 0x04) & (1<< offs); 76 return __raw_readl(chip->base + 0x04) & (1<< offs);
164} 77}
165 78
166EXPORT_SYMBOL(s3c2410_gpio_getpin); 79EXPORT_SYMBOL(s3c2410_gpio_getpin);
@@ -181,22 +94,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
181} 94}
182 95
183EXPORT_SYMBOL(s3c2410_modify_misccr); 96EXPORT_SYMBOL(s3c2410_modify_misccr);
184
185int s3c2410_gpio_getirq(unsigned int pin)
186{
187 if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
188 return -EINVAL; /* not valid interrupts */
189
190 if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
191 return -EINVAL; /* not valid pin */
192
193 if (pin < S3C2410_GPF(4))
194 return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
195
196 if (pin < S3C2410_GPG(0))
197 return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
198
199 return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
200}
201
202EXPORT_SYMBOL(s3c2410_gpio_getirq);