diff options
Diffstat (limited to 'arch/arm/plat-samsung/gpio-config.c')
-rw-r--r-- | arch/arm/plat-samsung/gpio-config.c | 111 |
1 files changed, 104 insertions, 7 deletions
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 44a84e896546..a76eef533392 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* linux/arch/arm/plat-s3c/gpio-config.c | 1 | /* linux/arch/arm/plat-s3c/gpio-config.c |
2 | * | 2 | * |
3 | * Copyright 2008 Openmoko, Inc. | 3 | * Copyright 2008 Openmoko, Inc. |
4 | * Copyright 2008 Simtec Electronics | 4 | * Copyright 2008-2010 Simtec Electronics |
5 | * Ben Dooks <ben@simtec.co.uk> | 5 | * Ben Dooks <ben@simtec.co.uk> |
6 | * http://armlinux.simtec.co.uk/ | 6 | * http://armlinux.simtec.co.uk/ |
7 | * | 7 | * |
@@ -33,14 +33,34 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) | |||
33 | 33 | ||
34 | offset = pin - chip->chip.base; | 34 | offset = pin - chip->chip.base; |
35 | 35 | ||
36 | local_irq_save(flags); | 36 | s3c_gpio_lock(chip, flags); |
37 | ret = s3c_gpio_do_setcfg(chip, offset, config); | 37 | ret = s3c_gpio_do_setcfg(chip, offset, config); |
38 | local_irq_restore(flags); | 38 | s3c_gpio_unlock(chip, flags); |
39 | 39 | ||
40 | return ret; | 40 | return ret; |
41 | } | 41 | } |
42 | EXPORT_SYMBOL(s3c_gpio_cfgpin); | 42 | EXPORT_SYMBOL(s3c_gpio_cfgpin); |
43 | 43 | ||
44 | unsigned s3c_gpio_getcfg(unsigned int pin) | ||
45 | { | ||
46 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | ||
47 | unsigned long flags; | ||
48 | unsigned ret = 0; | ||
49 | int offset; | ||
50 | |||
51 | if (chip) { | ||
52 | offset = pin - chip->chip.base; | ||
53 | |||
54 | s3c_gpio_lock(chip, flags); | ||
55 | ret = s3c_gpio_do_getcfg(chip, offset); | ||
56 | s3c_gpio_unlock(chip, flags); | ||
57 | } | ||
58 | |||
59 | return ret; | ||
60 | } | ||
61 | EXPORT_SYMBOL(s3c_gpio_getcfg); | ||
62 | |||
63 | |||
44 | int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) | 64 | int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) |
45 | { | 65 | { |
46 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); | 66 | struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); |
@@ -52,17 +72,17 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) | |||
52 | 72 | ||
53 | offset = pin - chip->chip.base; | 73 | offset = pin - chip->chip.base; |
54 | 74 | ||
55 | local_irq_save(flags); | 75 | s3c_gpio_lock(chip, flags); |
56 | ret = s3c_gpio_do_setpull(chip, offset, pull); | 76 | ret = s3c_gpio_do_setpull(chip, offset, pull); |
57 | local_irq_restore(flags); | 77 | s3c_gpio_unlock(chip, flags); |
58 | 78 | ||
59 | return ret; | 79 | return ret; |
60 | } | 80 | } |
61 | EXPORT_SYMBOL(s3c_gpio_setpull); | 81 | EXPORT_SYMBOL(s3c_gpio_setpull); |
62 | 82 | ||
63 | #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX | 83 | #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX |
64 | int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, | 84 | int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, |
65 | unsigned int off, unsigned int cfg) | 85 | unsigned int off, unsigned int cfg) |
66 | { | 86 | { |
67 | void __iomem *reg = chip->base; | 87 | void __iomem *reg = chip->base; |
68 | unsigned int shift = off; | 88 | unsigned int shift = off; |
@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip, | |||
87 | return 0; | 107 | return 0; |
88 | } | 108 | } |
89 | 109 | ||
110 | unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip, | ||
111 | unsigned int off) | ||
112 | { | ||
113 | u32 con; | ||
114 | |||
115 | con = __raw_readl(chip->base); | ||
116 | con >>= off; | ||
117 | con &= 1; | ||
118 | con++; | ||
119 | |||
120 | return S3C_GPIO_SFN(con); | ||
121 | } | ||
122 | |||
90 | int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, | 123 | int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, |
91 | unsigned int off, unsigned int cfg) | 124 | unsigned int off, unsigned int cfg) |
92 | { | 125 | { |
@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip, | |||
109 | 142 | ||
110 | return 0; | 143 | return 0; |
111 | } | 144 | } |
145 | |||
146 | unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip, | ||
147 | unsigned int off) | ||
148 | { | ||
149 | u32 con; | ||
150 | |||
151 | con = __raw_readl(chip->base); | ||
152 | con >>= off * 2; | ||
153 | con &= 3; | ||
154 | |||
155 | /* this conversion works for IN and OUT as well as special mode */ | ||
156 | return S3C_GPIO_SPECIAL(con); | ||
157 | } | ||
112 | #endif | 158 | #endif |
113 | 159 | ||
114 | #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX | 160 | #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX |
@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, | |||
134 | 180 | ||
135 | return 0; | 181 | return 0; |
136 | } | 182 | } |
183 | |||
184 | unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip, | ||
185 | unsigned int off) | ||
186 | { | ||
187 | void __iomem *reg = chip->base; | ||
188 | unsigned int shift = (off & 7) * 4; | ||
189 | u32 con; | ||
190 | |||
191 | if (off < 8 && chip->chip.ngpio > 8) | ||
192 | reg -= 4; | ||
193 | |||
194 | con = __raw_readl(reg); | ||
195 | con >>= shift; | ||
196 | con &= 0xf; | ||
197 | |||
198 | /* this conversion works for IN and OUT as well as special mode */ | ||
199 | return S3C_GPIO_SPECIAL(con); | ||
200 | } | ||
201 | |||
137 | #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ | 202 | #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */ |
138 | 203 | ||
139 | #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN | 204 | #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN |
@@ -164,3 +229,35 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, | |||
164 | return (__force s3c_gpio_pull_t)pup; | 229 | return (__force s3c_gpio_pull_t)pup; |
165 | } | 230 | } |
166 | #endif | 231 | #endif |
232 | |||
233 | #ifdef CONFIG_S3C_GPIO_PULL_UP | ||
234 | int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | ||
235 | unsigned int off, s3c_gpio_pull_t pull) | ||
236 | { | ||
237 | void __iomem *reg = chip->base + 0x08; | ||
238 | u32 pup = __raw_readl(reg); | ||
239 | |||
240 | pup = __raw_readl(reg); | ||
241 | |||
242 | if (pup == S3C_GPIO_PULL_UP) | ||
243 | pup &= ~(1 << off); | ||
244 | else if (pup == S3C_GPIO_PULL_NONE) | ||
245 | pup |= (1 << off); | ||
246 | else | ||
247 | return -EINVAL; | ||
248 | |||
249 | __raw_writel(pup, reg); | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | ||
254 | unsigned int off) | ||
255 | { | ||
256 | void __iomem *reg = chip->base + 0x08; | ||
257 | u32 pup = __raw_readl(reg); | ||
258 | |||
259 | pup &= (1 << off); | ||
260 | return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP; | ||
261 | } | ||
262 | #endif /* CONFIG_S3C_GPIO_PULL_UP */ | ||
263 | |||