aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2010-12-03 10:05:37 -0500
committerLinus Walleij <linus.walleij@stericsson.com>2010-12-08 07:14:52 -0500
commitdacdc96cd33dee876c704aaed78f41515abe8a81 (patch)
treed7e3b08e16dbf4eacca1415b0ff88d593ce28763
parentedaa86a4142474c99e4741efb6a916067978a1ee (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>
-rw-r--r--arch/arm/plat-nomadik/gpio.c50
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h70
2 files changed, 99 insertions, 21 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
121static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, 121static 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 */
178int nmk_config_pin(pin_cfg_t cfg) 201int 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}
217EXPORT_SYMBOL(nmk_config_pins); 240EXPORT_SYMBOL(nmk_config_pins);
218 241
242int 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}
255EXPORT_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
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 8c5ae3f2acf8..05a3936ae6d1 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -19,16 +19,22 @@
19 * bit 9..10 - Alternate Function Selection 19 * bit 9..10 - Alternate Function Selection
20 * bit 11..12 - Pull up/down state 20 * bit 11..12 - Pull up/down state
21 * bit 13 - Sleep mode behaviour 21 * bit 13 - Sleep mode behaviour
22 * bit 14 - (sleep mode) Direction 22 * bit 14 - Direction
23 * bit 15 - (sleep mode) Value (if output) 23 * bit 15 - Value (if output)
24 * bit 16..18 - SLPM pull up/down state
25 * bit 19..20 - SLPM direction
26 * bit 21..22 - SLPM Value (if output)
24 * 27 *
25 * to facilitate the definition, the following macros are provided 28 * to facilitate the definition, the following macros are provided
26 * 29 *
27 * PIN_CFG_DEFAULT - default config (0): 30 * PIN_CFG_DEFAULT - default config (0):
28 * pull up/down = disabled 31 * pull up/down = disabled
29 * sleep mode = input/wakeup 32 * sleep mode = input/wakeup
30 * (sleep mode) direction = input 33 * direction = input
31 * (sleep mode) value = low 34 * value = low
35 * SLPM direction = same as normal
36 * SLPM pull = same as normal
37 * SLPM value = same as normal
32 * 38 *
33 * PIN_CFG - default config with alternate function 39 * PIN_CFG - default config with alternate function
34 * PIN_CFG_PULL - default config with alternate function and pull up/down 40 * PIN_CFG_PULL - default config with alternate function and pull up/down
@@ -75,30 +81,64 @@ typedef unsigned long pin_cfg_t;
75#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) 81#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
76#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) 82#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
77 83
78/* Shortcuts. Use these instead of separate DIR and VAL. */ 84#define PIN_SLPM_PULL_SHIFT 16
79#define PIN_INPUT PIN_DIR_INPUT 85#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
86#define PIN_SLPM_PULL(x) \
87 (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
88#define PIN_SLPM_PULL_NONE \
89 ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
90#define PIN_SLPM_PULL_UP \
91 ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
92#define PIN_SLPM_PULL_DOWN \
93 ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
94
95#define PIN_SLPM_DIR_SHIFT 19
96#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
97#define PIN_SLPM_DIR(x) \
98 (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
99#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
100#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
101
102#define PIN_SLPM_VAL_SHIFT 21
103#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
104#define PIN_SLPM_VAL(x) \
105 (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
106#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
107#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
108
109/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
110#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
111#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
112#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
80#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) 113#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
81#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) 114#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
82 115
83/* 116#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
84 * These are the same as the ones above, but should make more sense to the 117#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
85 * reader when seen along with a setting a pin to AF mode. 118#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
86 */ 119#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
87#define PIN_SLPM_INPUT PIN_INPUT 120#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
88#define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW
89#define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH
90 121
91#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) 122#define PIN_CFG_DEFAULT (0)
92 123
93#define PIN_CFG(num, alt) \ 124#define PIN_CFG(num, alt) \
94 (PIN_CFG_DEFAULT |\ 125 (PIN_CFG_DEFAULT |\
95 (PIN_NUM(num) | PIN_##alt)) 126 (PIN_NUM(num) | PIN_##alt))
96 127
128#define PIN_CFG_INPUT(num, alt, pull) \
129 (PIN_CFG_DEFAULT |\
130 (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
131
132#define PIN_CFG_OUTPUT(num, alt, val) \
133 (PIN_CFG_DEFAULT |\
134 (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
135
97#define PIN_CFG_PULL(num, alt, pull) \ 136#define PIN_CFG_PULL(num, alt, pull) \
98 ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ 137 ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
99 (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) 138 (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
100 139
101extern int nmk_config_pin(pin_cfg_t cfg); 140extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
102extern int nmk_config_pins(pin_cfg_t *cfgs, int num); 141extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
142extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num);
103 143
104#endif 144#endif