xref: /openbmc/linux/arch/arm/mach-pxa/mfp-pxa2xx.c (revision 545e4006)
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 */
278