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