diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2010-12-03 10:05:37 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@stericsson.com> | 2010-12-08 07:14:52 -0500 |
commit | dacdc96cd33dee876c704aaed78f41515abe8a81 (patch) | |
tree | d7e3b08e16dbf4eacca1415b0ff88d593ce28763 /arch/arm/plat-nomadik/gpio.c | |
parent | edaa86a4142474c99e4741efb6a916067978a1ee (diff) |
nomadik-gpio: allow sleep mode dir/pull to differ from normal mode
In the nomadik GPIO pin configuration, allow the sleep mode direction
and pull configurations to differ from the ones for the normal state.
PIN_SLPM_PULL_*, PIN_SLPM_INPUT, PIN_SLPM_OUTPUT* macros are provided
for this.
Since the hardware does not allow seperate configurations for sleep mode
and normal mode, this is implemented by having software remux the
configurations as necessary.
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Diffstat (limited to 'arch/arm/plat-nomadik/gpio.c')
-rw-r--r-- | arch/arm/plat-nomadik/gpio.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 85e6fd212a41..5fc8e4d8cd2a 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -119,7 +119,7 @@ static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
122 | pin_cfg_t cfg) | 122 | pin_cfg_t cfg, bool sleep) |
123 | { | 123 | { |
124 | static const char *afnames[] = { | 124 | static const char *afnames[] = { |
125 | [NMK_GPIO_ALT_GPIO] = "GPIO", | 125 | [NMK_GPIO_ALT_GPIO] = "GPIO", |
@@ -145,11 +145,34 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
145 | int output = PIN_DIR(cfg); | 145 | int output = PIN_DIR(cfg); |
146 | int val = PIN_VAL(cfg); | 146 | int val = PIN_VAL(cfg); |
147 | 147 | ||
148 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n", | 148 | dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", |
149 | pin, afnames[af], pullnames[pull], slpmnames[slpm], | 149 | pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], |
150 | output ? "output " : "input", | 150 | output ? "output " : "input", |
151 | output ? (val ? "high" : "low") : ""); | 151 | output ? (val ? "high" : "low") : ""); |
152 | 152 | ||
153 | if (sleep) { | ||
154 | int slpm_pull = PIN_SLPM_PULL(cfg); | ||
155 | int slpm_output = PIN_SLPM_DIR(cfg); | ||
156 | int slpm_val = PIN_SLPM_VAL(cfg); | ||
157 | |||
158 | /* | ||
159 | * The SLPM_* values are normal values + 1 to allow zero to | ||
160 | * mean "same as normal". | ||
161 | */ | ||
162 | if (slpm_pull) | ||
163 | pull = slpm_pull - 1; | ||
164 | if (slpm_output) | ||
165 | output = slpm_output - 1; | ||
166 | if (slpm_val) | ||
167 | val = slpm_val - 1; | ||
168 | |||
169 | dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", | ||
170 | pin, | ||
171 | slpm_pull ? pullnames[pull] : "same", | ||
172 | slpm_output ? (output ? "output" : "input") : "same", | ||
173 | slpm_val ? (val ? "high" : "low") : "same"); | ||
174 | } | ||
175 | |||
153 | if (output) | 176 | if (output) |
154 | __nmk_gpio_make_output(nmk_chip, offset, val); | 177 | __nmk_gpio_make_output(nmk_chip, offset, val); |
155 | else { | 178 | else { |
@@ -175,7 +198,7 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
175 | * side-effects. The gpio can be manipulated later using standard GPIO API | 198 | * side-effects. The gpio can be manipulated later using standard GPIO API |
176 | * calls. | 199 | * calls. |
177 | */ | 200 | */ |
178 | int nmk_config_pin(pin_cfg_t cfg) | 201 | int nmk_config_pin(pin_cfg_t cfg, bool sleep) |
179 | { | 202 | { |
180 | struct nmk_gpio_chip *nmk_chip; | 203 | struct nmk_gpio_chip *nmk_chip; |
181 | int gpio = PIN_NUM(cfg); | 204 | int gpio = PIN_NUM(cfg); |
@@ -186,7 +209,7 @@ int nmk_config_pin(pin_cfg_t cfg) | |||
186 | return -EINVAL; | 209 | return -EINVAL; |
187 | 210 | ||
188 | spin_lock_irqsave(&nmk_chip->lock, flags); | 211 | spin_lock_irqsave(&nmk_chip->lock, flags); |
189 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg); | 212 | __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg, sleep); |
190 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 213 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
191 | 214 | ||
192 | return 0; | 215 | return 0; |
@@ -207,7 +230,7 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) | |||
207 | int i; | 230 | int i; |
208 | 231 | ||
209 | for (i = 0; i < num; i++) { | 232 | for (i = 0; i < num; i++) { |
210 | int ret = nmk_config_pin(cfgs[i]); | 233 | ret = nmk_config_pin(cfgs[i], false); |
211 | if (ret) | 234 | if (ret) |
212 | break; | 235 | break; |
213 | } | 236 | } |
@@ -216,6 +239,21 @@ int nmk_config_pins(pin_cfg_t *cfgs, int num) | |||
216 | } | 239 | } |
217 | EXPORT_SYMBOL(nmk_config_pins); | 240 | EXPORT_SYMBOL(nmk_config_pins); |
218 | 241 | ||
242 | int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num) | ||
243 | { | ||
244 | int ret = 0; | ||
245 | int i; | ||
246 | |||
247 | for (i = 0; i < num; i++) { | ||
248 | ret = nmk_config_pin(cfgs[i], true); | ||
249 | if (ret) | ||
250 | break; | ||
251 | } | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | EXPORT_SYMBOL(nmk_config_pins_sleep); | ||
256 | |||
219 | /** | 257 | /** |
220 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin | 258 | * nmk_gpio_set_slpm() - configure the sleep mode of a pin |
221 | * @gpio: pin number | 259 | * @gpio: pin number |