Merge branch 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6
[pandora-kernel.git] / arch / arm / mach-pxa / mfp-pxa2xx.c
1 /*
2  *  linux/arch/arm/mach-pxa/mfp-pxa2xx.c
3  *
4  *  PXA2xx pin mux configuration support
5  *
6  *  The GPIOs on PXA2xx can be configured as one of many alternate
7  *  functions, this is by concept samilar to the MFP configuration
8  *  on PXA3xx,  what's more important, the low power pin state and
9  *  wakeup detection are also supported by the same framework.
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License version 2 as
13  *  published by the Free Software Foundation.
14  */
15
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/sysdev.h>
20
21 #include <asm/arch/hardware.h>
22 #include <asm/arch/pxa-regs.h>
23 #include <asm/arch/pxa2xx-regs.h>
24 #include <asm/arch/mfp-pxa2xx.h>
25
26 #include "generic.h"
27
28 #define PGSR(x)         __REG2(0x40F00020, ((x) & 0x60) >> 3)
29
30 #define PWER_WE35       (1 << 24)
31
32 struct gpio_desc {
33         unsigned        valid           : 1;
34         unsigned        can_wakeup      : 1;
35         unsigned        keypad_gpio     : 1;
36         unsigned int    mask; /* bit mask in PWER or PKWR */
37         unsigned long   config;
38 };
39
40 static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
41
42 static int __mfp_config_lpm(unsigned gpio, unsigned long lpm)
43 {
44         unsigned mask = GPIO_bit(gpio);
45
46         /* low power state */
47         switch (lpm) {
48         case MFP_LPM_DRIVE_HIGH:
49                 PGSR(gpio) |= mask;
50                 break;
51         case MFP_LPM_DRIVE_LOW:
52                 PGSR(gpio) &= ~mask;
53                 break;
54         case MFP_LPM_INPUT:
55                 break;
56         default:
57                 pr_warning("%s: invalid low power state for GPIO%d\n",
58                                 __func__, gpio);
59                 return -EINVAL;
60         }
61         return 0;
62 }
63
64 static int __mfp_config_gpio(unsigned gpio, unsigned long c)
65 {
66         unsigned long gafr, mask = GPIO_bit(gpio);
67         int fn;
68
69         fn = MFP_AF(c);
70         if (fn > 3)
71                 return -EINVAL;
72
73         /* alternate function and direction */
74         gafr = GAFR(gpio) & ~(0x3 << ((gpio & 0xf) * 2));
75         GAFR(gpio) = gafr |  (fn  << ((gpio & 0xf) * 2));
76
77         if (c & MFP_DIR_OUT)
78                 GPDR(gpio) |= mask;
79         else
80                 GPDR(gpio) &= ~mask;
81
82         if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
83                 return -EINVAL;
84
85         /* give early warning if MFP_LPM_CAN_WAKEUP is set on the
86          * configurations of those pins not able to wakeup
87          */
88         if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
89                 pr_warning("%s: GPIO%d unable to wakeup\n",
90                                 __func__, gpio);
91                 return -EINVAL;
92         }
93
94         if ((c & MFP_LPM_CAN_WAKEUP) && (c & MFP_DIR_OUT)) {
95                 pr_warning("%s: output GPIO%d unable to wakeup\n",
96                                 __func__, gpio);
97                 return -EINVAL;
98         }
99
100         return 0;
101 }
102
103 static inline int __mfp_validate(int mfp)
104 {
105         int gpio = mfp_to_gpio(mfp);
106
107         if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
108                 pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
109                 return -1;
110         }
111
112         return gpio;
113 }
114
115 void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
116 {
117         unsigned long flags;
118         unsigned long *c;
119         int i, gpio;
120
121         for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
122
123                 gpio = __mfp_validate(MFP_PIN(*c));
124                 if (gpio < 0)
125                         continue;
126
127                 local_irq_save(flags);
128
129                 gpio_desc[gpio].config = *c;
130                 __mfp_config_gpio(gpio, *c);
131
132                 local_irq_restore(flags);
133         }
134 }
135
136 void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
137 {
138         unsigned long flags;
139         int gpio;
140
141         gpio = __mfp_validate(mfp);
142         if (gpio < 0)
143                 return;
144
145         local_irq_save(flags);
146         __mfp_config_lpm(gpio, lpm);
147         local_irq_restore(flags);
148 }
149
150 int gpio_set_wake(unsigned int gpio, unsigned int on)
151 {
152         struct gpio_desc *d;
153         unsigned long c;
154
155         if (gpio > mfp_to_gpio(MFP_PIN_GPIO127))
156                 return -EINVAL;
157
158         d = &gpio_desc[gpio];
159         c = d->config;
160
161         if (!d->valid)
162                 return -EINVAL;
163
164         if (d->keypad_gpio)
165                 return -EINVAL;
166
167         if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
168                 if (on) {
169                         PWER |= d->mask;
170
171                         if (c & MFP_LPM_EDGE_RISE)
172                                 PRER |= d->mask;
173                         else
174                                 PRER &= ~d->mask;
175
176                         if (c & MFP_LPM_EDGE_FALL)
177                                 PFER |= d->mask;
178                         else
179                                 PFER &= ~d->mask;
180                 } else {
181                         PWER &= ~d->mask;
182                         PRER &= ~d->mask;
183                         PFER &= ~d->mask;
184                 }
185         }
186         return 0;
187 }
188
189 #ifdef CONFIG_PXA25x
190 static int __init pxa25x_mfp_init(void)
191 {
192         int i;
193
194         if (cpu_is_pxa25x()) {
195                 for (i = 0; i <= 84; i++)
196                         gpio_desc[i].valid = 1;
197
198                 for (i = 0; i <= 15; i++) {
199                         gpio_desc[i].can_wakeup = 1;
200                         gpio_desc[i].mask = GPIO_bit(i);
201                 }
202         }
203
204         return 0;
205 }
206 postcore_initcall(pxa25x_mfp_init);
207 #endif /* CONFIG_PXA25x */
208
209 #ifdef CONFIG_PXA27x
210 static int pxa27x_pkwr_gpio[] = {
211         13, 16, 17, 34, 36, 37, 38, 39, 90, 91, 93, 94,
212         95, 96, 97, 98, 99, 100, 101, 102
213 };
214
215 int keypad_set_wake(unsigned int on)
216 {
217         unsigned int i, gpio, mask = 0;
218
219         if (!on) {
220                 PKWR = 0;
221                 return 0;
222         }
223
224         for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
225
226                 gpio = pxa27x_pkwr_gpio[i];
227
228                 if (gpio_desc[gpio].config & MFP_LPM_CAN_WAKEUP)
229                         mask |= gpio_desc[gpio].mask;
230         }
231
232         PKWR = mask;
233         return 0;
234 }
235
236 static int __init pxa27x_mfp_init(void)
237 {
238         int i, gpio;
239
240         if (cpu_is_pxa27x()) {
241                 for (i = 0; i <= 120; i++) {
242                         /* skip GPIO2, 5, 6, 7, 8, they are not
243                          * valid pins allow configuration
244                          */
245                         if (i == 2 || i == 5 || i == 6 ||
246                             i == 7 || i == 8)
247                                 continue;
248
249                         gpio_desc[i].valid = 1;
250                 }
251
252                 /* Keypad GPIOs */
253                 for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
254                         gpio = pxa27x_pkwr_gpio[i];
255                         gpio_desc[gpio].can_wakeup = 1;
256                         gpio_desc[gpio].keypad_gpio = 1;
257                         gpio_desc[gpio].mask = 1 << i;
258                 }
259
260                 /* Overwrite GPIO13 as a PWER wakeup source */
261                 for (i = 0; i <= 15; i++) {
262                         /* skip GPIO2, 5, 6, 7, 8 */
263                         if (GPIO_bit(i) & 0x1e4)
264                                 continue;
265
266                         gpio_desc[i].can_wakeup = 1;
267                         gpio_desc[i].mask = GPIO_bit(i);
268                 }
269
270                 gpio_desc[35].can_wakeup = 1;
271                 gpio_desc[35].mask = PWER_WE35;
272         }
273
274         return 0;
275 }
276 postcore_initcall(pxa27x_mfp_init);
277 #endif /* CONFIG_PXA27x */