blob: 92f2b8c06de11e4953de02e38245c5c144eff13b [file] [log] [blame]
Linus Walleijbd41b992009-04-23 21:15:04 +01001/*
Grant Likelyc103de22011-06-04 18:38:28 -06002 * U300 GPIO module.
Linus Walleijbd41b992009-04-23 21:15:04 +01003 *
4 * Copyright (C) 2007-2009 ST-Ericsson AB
5 * License terms: GNU General Public License (GPL) version 2
Linus Walleijbd41b992009-04-23 21:15:04 +01006 * This can driver either of the two basic GPIO cores
7 * available in the U300 platforms:
8 * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
9 * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
10 * Notice that you also have inline macros in <asm-arch/gpio.h>
11 * Author: Linus Walleij <linus.walleij@stericsson.com>
12 * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
13 *
14 */
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/delay.h>
18#include <linux/errno.h>
19#include <linux/io.h>
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <linux/platform_device.h>
23#include <linux/gpio.h>
Linus Walleijeb3cf182011-08-22 08:34:26 +010024#include <mach/gpio-u300.h>
Linus Walleijbd41b992009-04-23 21:15:04 +010025
Linus Walleijbd41b992009-04-23 21:15:04 +010026/* Reference to GPIO block clock */
27static struct clk *clk;
28
29/* Memory resource */
30static struct resource *memres;
31static void __iomem *virtbase;
Linus Walleijf7a9a4d2009-05-08 08:59:51 +010032static struct device *gpiodev;
Linus Walleijbd41b992009-04-23 21:15:04 +010033
34struct u300_gpio_port {
35 const char *name;
36 int irq;
37 int number;
38};
39
40
41static struct u300_gpio_port gpio_ports[] = {
42 {
43 .name = "gpio0",
44 .number = 0,
45 },
46 {
47 .name = "gpio1",
48 .number = 1,
49 },
50 {
51 .name = "gpio2",
52 .number = 2,
53 },
54#ifdef U300_COH901571_3
55 {
56 .name = "gpio3",
57 .number = 3,
58 },
59 {
60 .name = "gpio4",
61 .number = 4,
62 },
63#ifdef CONFIG_MACH_U300_BS335
64 {
65 .name = "gpio5",
66 .number = 5,
67 },
68 {
69 .name = "gpio6",
70 .number = 6,
71 },
72#endif
73#endif
74
75};
76
77
78#ifdef U300_COH901571_3
79
80/* Default input value */
81#define DEFAULT_OUTPUT_LOW 0
82#define DEFAULT_OUTPUT_HIGH 1
83
84/* GPIO Pull-Up status */
85#define DISABLE_PULL_UP 0
86#define ENABLE_PULL_UP 1
87
88#define GPIO_NOT_USED 0
89#define GPIO_IN 1
90#define GPIO_OUT 2
91
92struct u300_gpio_configuration_data {
93 unsigned char pin_usage;
94 unsigned char default_output_value;
95 unsigned char pull_up;
96};
97
98/* Initial configuration */
99const struct u300_gpio_configuration_data
100u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
101#ifdef CONFIG_MACH_U300_BS335
102 /* Port 0, pins 0-7 */
103 {
104 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
105 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
106 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
107 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
108 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
109 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
110 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
111 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
112 },
113 /* Port 1, pins 0-7 */
114 {
115 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
116 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
117 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
118 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
119 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
120 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
121 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
122 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
123 },
124 /* Port 2, pins 0-7 */
125 {
126 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
127 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
128 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
129 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
130 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
131 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
132 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
133 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
134 },
135 /* Port 3, pins 0-7 */
136 {
137 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
138 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
139 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
140 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
141 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
142 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
143 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
144 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
145 },
146 /* Port 4, pins 0-7 */
147 {
148 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
149 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
150 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
151 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
152 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
153 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
154 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
155 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
156 },
157 /* Port 5, pins 0-7 */
158 {
159 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
160 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
161 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
162 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
163 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
164 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
165 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
166 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
167 },
168 /* Port 6, pind 0-7 */
169 {
170 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
171 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
172 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
173 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
174 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
175 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
176 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
177 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
178 }
179#endif
180
181#ifdef CONFIG_MACH_U300_BS365
182 /* Port 0, pins 0-7 */
183 {
184 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
185 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
186 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
187 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
188 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
189 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
190 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
191 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
192 },
193 /* Port 1, pins 0-7 */
194 {
195 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
196 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
197 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
198 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
199 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
200 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
201 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
202 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
203 },
204 /* Port 2, pins 0-7 */
205 {
206 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
207 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
208 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
209 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
210 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
211 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
212 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
213 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
214 },
215 /* Port 3, pins 0-7 */
216 {
217 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
218 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
219 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
220 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
221 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
222 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
223 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
224 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
225 },
226 /* Port 4, pins 0-7 */
227 {
228 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
229 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
230 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
231 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
232 /* These 4 pins doesn't exist on DB3210 */
233 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
234 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
235 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
236 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
237 }
238#endif
239};
240#endif
241
242
243/* No users == we can power down GPIO */
244static int gpio_users;
245
246struct gpio_struct {
247 int (*callback)(void *);
248 void *data;
249 int users;
250};
251
252static struct gpio_struct gpio_pin[U300_GPIO_MAX];
253
254/*
255 * Let drivers register callback in order to get notified when there is
256 * an interrupt on the gpio pin
257 */
258int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
259{
260 if (gpio_pin[gpio].callback)
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100261 dev_warn(gpiodev, "%s: WARNING: callback already "
262 "registered for gpio pin#%d\n", __func__, gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100263 gpio_pin[gpio].callback = func;
264 gpio_pin[gpio].data = data;
265
266 return 0;
267}
268EXPORT_SYMBOL(gpio_register_callback);
269
270int gpio_unregister_callback(unsigned gpio)
271{
272 if (!gpio_pin[gpio].callback)
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100273 dev_warn(gpiodev, "%s: WARNING: callback already "
274 "unregistered for gpio pin#%d\n", __func__, gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100275 gpio_pin[gpio].callback = NULL;
276 gpio_pin[gpio].data = NULL;
277
278 return 0;
279}
280EXPORT_SYMBOL(gpio_unregister_callback);
281
Linus Walleijee179622009-09-28 12:36:18 +0100282/* Non-zero means valid */
283int gpio_is_valid(int number)
284{
285 if (number >= 0 &&
286 number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
287 return 1;
288 return 0;
289}
290EXPORT_SYMBOL(gpio_is_valid);
291
Linus Walleijbd41b992009-04-23 21:15:04 +0100292int gpio_request(unsigned gpio, const char *label)
293{
294 if (gpio_pin[gpio].users)
295 return -EINVAL;
296 else
297 gpio_pin[gpio].users++;
298
299 gpio_users++;
300
301 return 0;
302}
303EXPORT_SYMBOL(gpio_request);
304
305void gpio_free(unsigned gpio)
306{
307 gpio_users--;
308 gpio_pin[gpio].users--;
309 if (unlikely(gpio_pin[gpio].users < 0)) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100310 dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
311 gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100312 gpio_pin[gpio].users = 0;
313 }
314
315 return;
316}
317EXPORT_SYMBOL(gpio_free);
318
319/* This returns zero or nonzero */
320int gpio_get_value(unsigned gpio)
321{
322 return readl(virtbase + U300_GPIO_PXPDIR +
323 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
324}
325EXPORT_SYMBOL(gpio_get_value);
326
327/*
328 * We hope that the compiler will optimize away the unused branch
329 * in case "value" is a constant
330 */
331void gpio_set_value(unsigned gpio, int value)
332{
333 u32 val;
334 unsigned long flags;
335
336 local_irq_save(flags);
337 if (value) {
338 /* set */
339 val = readl(virtbase + U300_GPIO_PXPDOR +
340 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
341 & (1 << (gpio & 0x07));
342 writel(val | (1 << (gpio & 0x07)), virtbase +
343 U300_GPIO_PXPDOR +
344 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
345 } else {
346 /* clear */
347 val = readl(virtbase + U300_GPIO_PXPDOR +
348 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
349 & (1 << (gpio & 0x07));
350 writel(val & ~(1 << (gpio & 0x07)), virtbase +
351 U300_GPIO_PXPDOR +
352 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
353 }
354 local_irq_restore(flags);
355}
356EXPORT_SYMBOL(gpio_set_value);
357
358int gpio_direction_input(unsigned gpio)
359{
360 unsigned long flags;
361 u32 val;
362
363 if (gpio > U300_GPIO_MAX)
364 return -EINVAL;
365
366 local_irq_save(flags);
367 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
368 U300_GPIO_PORTX_SPACING);
369 /* Mask out this pin*/
370 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
371 /* This is not needed since it sets the bits to zero.*/
372 /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
373 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
374 U300_GPIO_PORTX_SPACING);
375 local_irq_restore(flags);
376 return 0;
377}
378EXPORT_SYMBOL(gpio_direction_input);
379
380int gpio_direction_output(unsigned gpio, int value)
381{
382 unsigned long flags;
383 u32 val;
384
385 if (gpio > U300_GPIO_MAX)
386 return -EINVAL;
387
388 local_irq_save(flags);
389 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
390 U300_GPIO_PORTX_SPACING);
391 /* Mask out this pin */
392 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
393 /*
394 * FIXME: configure for push/pull, open drain or open source per pin
395 * in setup. The current driver will only support push/pull.
396 */
397 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
398 << ((gpio & 0x07) << 1));
399 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
400 U300_GPIO_PORTX_SPACING);
401 gpio_set_value(gpio, value);
402 local_irq_restore(flags);
403 return 0;
404}
405EXPORT_SYMBOL(gpio_direction_output);
406
407/*
408 * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
409 */
410void enable_irq_on_gpio_pin(unsigned gpio, int edge)
411{
412 u32 val;
413 unsigned long flags;
414 local_irq_save(flags);
415
416 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
417 U300_GPIO_PORTX_SPACING);
418 val |= (1 << (gpio & 0x07));
419 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
420 U300_GPIO_PORTX_SPACING);
421 val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
422 U300_GPIO_PORTX_SPACING);
423 if (edge)
424 val |= (1 << (gpio & 0x07));
425 else
426 val &= ~(1 << (gpio & 0x07));
427 writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
428 U300_GPIO_PORTX_SPACING);
429 local_irq_restore(flags);
430}
431EXPORT_SYMBOL(enable_irq_on_gpio_pin);
432
433void disable_irq_on_gpio_pin(unsigned gpio)
434{
435 u32 val;
436 unsigned long flags;
437
438 local_irq_save(flags);
439 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
440 U300_GPIO_PORTX_SPACING);
441 val &= ~(1 << (gpio & 0x07));
442 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
443 U300_GPIO_PORTX_SPACING);
444 local_irq_restore(flags);
445}
446EXPORT_SYMBOL(disable_irq_on_gpio_pin);
447
448/* Enable (value == 0) or disable (value == 1) internal pullup */
449void gpio_pullup(unsigned gpio, int value)
450{
451 u32 val;
452 unsigned long flags;
453
454 local_irq_save(flags);
455 if (value) {
456 val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
457 U300_GPIO_PORTX_SPACING);
458 writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
459 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
460 } else {
461 val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
462 U300_GPIO_PORTX_SPACING);
463 writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
464 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
465 }
466 local_irq_restore(flags);
467}
468EXPORT_SYMBOL(gpio_pullup);
469
470static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
471{
472 struct u300_gpio_port *port = dev_id;
473 u32 val;
474 int pin;
475
476 /* Read event register */
477 val = readl(virtbase + U300_GPIO_PXIEV + port->number *
478 U300_GPIO_PORTX_SPACING);
479 /* Mask with enable register */
480 val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
481 U300_GPIO_PORTX_SPACING);
482 /* Mask relevant bits */
483 val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
484 /* ACK IRQ (clear event) */
485 writel(val, virtbase + U300_GPIO_PXIEV + port->number *
486 U300_GPIO_PORTX_SPACING);
487 /* Print message */
488 while (val != 0) {
489 unsigned gpio;
490
491 pin = __ffs(val);
492 /* mask off this pin */
493 val &= ~(1 << pin);
494 gpio = (port->number << 3) + pin;
495
496 if (gpio_pin[gpio].callback)
497 (void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
498 else
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100499 dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
Linus Walleijbd41b992009-04-23 21:15:04 +0100500 gpio);
501 }
502 return IRQ_HANDLED;
503}
504
505static void gpio_set_initial_values(void)
506{
507#ifdef U300_COH901571_3
508 int i, j;
509 unsigned long flags;
510 u32 val;
511
512 /* Write default values to all pins */
513 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
514 val = 0;
515 for (j = 0; j < 8; j++)
516 val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
517 local_irq_save(flags);
518 writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
519 local_irq_restore(flags);
520 }
521
522 /*
523 * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
Uwe Kleine-König421f91d2010-06-11 12:17:00 +0200524 * to output and 'GPIO_IN' to input for each port. And initialize
Linus Walleijbd41b992009-04-23 21:15:04 +0100525 * default value on outputs.
526 */
527 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
528 for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
529 local_irq_save(flags);
530 val = readl(virtbase + U300_GPIO_PXPCR +
531 i * U300_GPIO_PORTX_SPACING);
532 /* Mask out this pin */
533 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
534
535 if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
536 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
537 writel(val, virtbase + U300_GPIO_PXPCR +
538 i * U300_GPIO_PORTX_SPACING);
539 local_irq_restore(flags);
540 }
541 }
542
543 /* Enable or disable the internal pull-ups in the GPIO ASIC block */
544 for (i = 0; i < U300_GPIO_MAX; i++) {
545 val = 0;
546 for (j = 0; j < 8; j++)
Roel Kluinfcfadca2010-02-23 23:37:22 +0100547 val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j);
Linus Walleijbd41b992009-04-23 21:15:04 +0100548 local_irq_save(flags);
549 writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
550 local_irq_restore(flags);
551 }
552#endif
553}
554
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100555static int __init gpio_probe(struct platform_device *pdev)
Linus Walleijbd41b992009-04-23 21:15:04 +0100556{
557 u32 val;
558 int err = 0;
559 int i;
560 int num_irqs;
561
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100562 gpiodev = &pdev->dev;
Linus Walleijbd41b992009-04-23 21:15:04 +0100563 memset(gpio_pin, 0, sizeof(gpio_pin));
564
565 /* Get GPIO clock */
566 clk = clk_get(&pdev->dev, NULL);
567 if (IS_ERR(clk)) {
568 err = PTR_ERR(clk);
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100569 dev_err(gpiodev, "could not get GPIO clock\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100570 goto err_no_clk;
571 }
572 err = clk_enable(clk);
573 if (err) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100574 dev_err(gpiodev, "could not enable GPIO clock\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100575 goto err_no_clk_enable;
576 }
577
578 memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
579 if (!memres)
580 goto err_no_resource;
581
Joe Perches28f65c112011-06-09 09:13:32 -0700582 if (!request_mem_region(memres->start, resource_size(memres),
583 "GPIO Controller")) {
Linus Walleijbd41b992009-04-23 21:15:04 +0100584 err = -ENODEV;
585 goto err_no_ioregion;
586 }
587
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100588 virtbase = ioremap(memres->start, resource_size(memres));
Linus Walleijbd41b992009-04-23 21:15:04 +0100589 if (!virtbase) {
590 err = -ENOMEM;
591 goto err_no_ioremap;
592 }
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100593 dev_info(gpiodev, "remapped 0x%08x to %p\n",
594 memres->start, virtbase);
Linus Walleijbd41b992009-04-23 21:15:04 +0100595
596#ifdef U300_COH901335
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100597 dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100598 /* Turn on the GPIO block */
599 writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
600#endif
601
602#ifdef U300_COH901571_3
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100603 dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100604 val = readl(virtbase + U300_GPIO_CR);
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100605 dev_info(gpiodev, "COH901571/3 block version: %d, " \
Linus Walleijbd41b992009-04-23 21:15:04 +0100606 "number of cores: %d\n",
607 ((val & 0x0000FE00) >> 9),
608 ((val & 0x000001FC) >> 2));
609 writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
610#endif
611
Linus Walleijbd41b992009-04-23 21:15:04 +0100612 gpio_set_initial_values();
613
614 for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
615
616 gpio_ports[num_irqs].irq =
617 platform_get_irq_byname(pdev,
618 gpio_ports[num_irqs].name);
619
620 err = request_irq(gpio_ports[num_irqs].irq,
621 gpio_irq_handler, IRQF_DISABLED,
622 gpio_ports[num_irqs].name,
623 &gpio_ports[num_irqs]);
624 if (err) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100625 dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
626 gpio_ports[num_irqs].name);
Linus Walleijbd41b992009-04-23 21:15:04 +0100627 goto err_no_irq;
628 }
629 /* Turns off PortX_irq_force */
630 writel(0x0, virtbase + U300_GPIO_PXIFR +
631 num_irqs * U300_GPIO_PORTX_SPACING);
632 }
Linus Walleijbd41b992009-04-23 21:15:04 +0100633
634 return 0;
635
636 err_no_irq:
637 for (i = 0; i < num_irqs; i++)
638 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
639 iounmap(virtbase);
640 err_no_ioremap:
Joe Perches28f65c112011-06-09 09:13:32 -0700641 release_mem_region(memres->start, resource_size(memres));
Linus Walleijbd41b992009-04-23 21:15:04 +0100642 err_no_ioregion:
643 err_no_resource:
644 clk_disable(clk);
645 err_no_clk_enable:
646 clk_put(clk);
647 err_no_clk:
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100648 dev_info(gpiodev, "module ERROR:%d\n", err);
Linus Walleijbd41b992009-04-23 21:15:04 +0100649 return err;
650}
651
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100652static int __exit gpio_remove(struct platform_device *pdev)
Linus Walleijbd41b992009-04-23 21:15:04 +0100653{
654 int i;
655
656 /* Turn off the GPIO block */
657 writel(0x00000000U, virtbase + U300_GPIO_CR);
658 for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
659 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
660 iounmap(virtbase);
Joe Perches28f65c112011-06-09 09:13:32 -0700661 release_mem_region(memres->start, resource_size(memres));
Linus Walleijbd41b992009-04-23 21:15:04 +0100662 clk_disable(clk);
663 clk_put(clk);
664 return 0;
665}
666
667static struct platform_driver gpio_driver = {
668 .driver = {
669 .name = "u300-gpio",
670 },
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100671 .remove = __exit_p(gpio_remove),
Linus Walleijbd41b992009-04-23 21:15:04 +0100672};
673
674
675static int __init u300_gpio_init(void)
676{
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100677 return platform_driver_probe(&gpio_driver, gpio_probe);
Linus Walleijbd41b992009-04-23 21:15:04 +0100678}
679
680static void __exit u300_gpio_exit(void)
681{
682 platform_driver_unregister(&gpio_driver);
683}
684
685arch_initcall(u300_gpio_init);
686module_exit(u300_gpio_exit);
687
688MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
689
690#ifdef U300_COH901571_3
691MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
692#endif
693
694#ifdef U300_COH901335
695MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
696#endif
697
698MODULE_LICENSE("GPL");