blob: 308cdb197a924f0ad2046fbae984a372fea549fc [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
28/* Need access to SYSCON registers for PADmuxing */
29#include <mach/syscon.h>
30
31#include "padmux.h"
32
33/* Reference to GPIO block clock */
34static struct clk *clk;
35
36/* Memory resource */
37static struct resource *memres;
38static void __iomem *virtbase;
Linus Walleijf7a9a4d2009-05-08 08:59:51 +010039static struct device *gpiodev;
Linus Walleijbd41b992009-04-23 21:15:04 +010040
41struct u300_gpio_port {
42 const char *name;
43 int irq;
44 int number;
45};
46
47
48static struct u300_gpio_port gpio_ports[] = {
49 {
50 .name = "gpio0",
51 .number = 0,
52 },
53 {
54 .name = "gpio1",
55 .number = 1,
56 },
57 {
58 .name = "gpio2",
59 .number = 2,
60 },
61#ifdef U300_COH901571_3
62 {
63 .name = "gpio3",
64 .number = 3,
65 },
66 {
67 .name = "gpio4",
68 .number = 4,
69 },
70#ifdef CONFIG_MACH_U300_BS335
71 {
72 .name = "gpio5",
73 .number = 5,
74 },
75 {
76 .name = "gpio6",
77 .number = 6,
78 },
79#endif
80#endif
81
82};
83
84
85#ifdef U300_COH901571_3
86
87/* Default input value */
88#define DEFAULT_OUTPUT_LOW 0
89#define DEFAULT_OUTPUT_HIGH 1
90
91/* GPIO Pull-Up status */
92#define DISABLE_PULL_UP 0
93#define ENABLE_PULL_UP 1
94
95#define GPIO_NOT_USED 0
96#define GPIO_IN 1
97#define GPIO_OUT 2
98
99struct u300_gpio_configuration_data {
100 unsigned char pin_usage;
101 unsigned char default_output_value;
102 unsigned char pull_up;
103};
104
105/* Initial configuration */
106const struct u300_gpio_configuration_data
107u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
108#ifdef CONFIG_MACH_U300_BS335
109 /* Port 0, pins 0-7 */
110 {
111 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
112 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
113 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
114 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
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_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
119 },
120 /* Port 1, pins 0-7 */
121 {
122 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
123 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
124 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
125 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
126 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
127 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
128 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
129 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
130 },
131 /* Port 2, pins 0-7 */
132 {
133 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
134 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
135 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
136 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
137 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
138 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
139 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
140 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
141 },
142 /* Port 3, pins 0-7 */
143 {
144 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
145 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
146 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
147 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
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 },
153 /* Port 4, pins 0-7 */
154 {
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 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
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 },
164 /* Port 5, pins 0-7 */
165 {
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 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
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 },
175 /* Port 6, pind 0-7 */
176 {
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 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
181 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
182 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
183 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
184 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
185 }
186#endif
187
188#ifdef CONFIG_MACH_U300_BS365
189 /* Port 0, pins 0-7 */
190 {
191 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
192 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
193 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
194 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
195 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
196 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
197 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
198 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
199 },
200 /* Port 1, pins 0-7 */
201 {
202 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
203 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
204 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
205 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
206 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
207 {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP},
208 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
209 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}
210 },
211 /* Port 2, pins 0-7 */
212 {
213 {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
214 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
215 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
216 {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP},
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 },
222 /* Port 3, pins 0-7 */
223 {
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 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
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 },
233 /* Port 4, pins 0-7 */
234 {
235 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
236 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
237 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
238 {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
239 /* These 4 pins doesn't exist on DB3210 */
240 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
241 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
242 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP},
243 {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}
244 }
245#endif
246};
247#endif
248
249
250/* No users == we can power down GPIO */
251static int gpio_users;
252
253struct gpio_struct {
254 int (*callback)(void *);
255 void *data;
256 int users;
257};
258
259static struct gpio_struct gpio_pin[U300_GPIO_MAX];
260
261/*
262 * Let drivers register callback in order to get notified when there is
263 * an interrupt on the gpio pin
264 */
265int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
266{
267 if (gpio_pin[gpio].callback)
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100268 dev_warn(gpiodev, "%s: WARNING: callback already "
269 "registered for gpio pin#%d\n", __func__, gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100270 gpio_pin[gpio].callback = func;
271 gpio_pin[gpio].data = data;
272
273 return 0;
274}
275EXPORT_SYMBOL(gpio_register_callback);
276
277int gpio_unregister_callback(unsigned gpio)
278{
279 if (!gpio_pin[gpio].callback)
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100280 dev_warn(gpiodev, "%s: WARNING: callback already "
281 "unregistered for gpio pin#%d\n", __func__, gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100282 gpio_pin[gpio].callback = NULL;
283 gpio_pin[gpio].data = NULL;
284
285 return 0;
286}
287EXPORT_SYMBOL(gpio_unregister_callback);
288
289int gpio_request(unsigned gpio, const char *label)
290{
291 if (gpio_pin[gpio].users)
292 return -EINVAL;
293 else
294 gpio_pin[gpio].users++;
295
296 gpio_users++;
297
298 return 0;
299}
300EXPORT_SYMBOL(gpio_request);
301
302void gpio_free(unsigned gpio)
303{
304 gpio_users--;
305 gpio_pin[gpio].users--;
306 if (unlikely(gpio_pin[gpio].users < 0)) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100307 dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
308 gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100309 gpio_pin[gpio].users = 0;
310 }
311
312 return;
313}
314EXPORT_SYMBOL(gpio_free);
315
316/* This returns zero or nonzero */
317int gpio_get_value(unsigned gpio)
318{
319 return readl(virtbase + U300_GPIO_PXPDIR +
320 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
321}
322EXPORT_SYMBOL(gpio_get_value);
323
324/*
325 * We hope that the compiler will optimize away the unused branch
326 * in case "value" is a constant
327 */
328void gpio_set_value(unsigned gpio, int value)
329{
330 u32 val;
331 unsigned long flags;
332
333 local_irq_save(flags);
334 if (value) {
335 /* set */
336 val = readl(virtbase + U300_GPIO_PXPDOR +
337 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
338 & (1 << (gpio & 0x07));
339 writel(val | (1 << (gpio & 0x07)), virtbase +
340 U300_GPIO_PXPDOR +
341 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
342 } else {
343 /* clear */
344 val = readl(virtbase + U300_GPIO_PXPDOR +
345 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
346 & (1 << (gpio & 0x07));
347 writel(val & ~(1 << (gpio & 0x07)), virtbase +
348 U300_GPIO_PXPDOR +
349 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
350 }
351 local_irq_restore(flags);
352}
353EXPORT_SYMBOL(gpio_set_value);
354
355int gpio_direction_input(unsigned gpio)
356{
357 unsigned long flags;
358 u32 val;
359
360 if (gpio > U300_GPIO_MAX)
361 return -EINVAL;
362
363 local_irq_save(flags);
364 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
365 U300_GPIO_PORTX_SPACING);
366 /* Mask out this pin*/
367 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
368 /* This is not needed since it sets the bits to zero.*/
369 /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
370 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
371 U300_GPIO_PORTX_SPACING);
372 local_irq_restore(flags);
373 return 0;
374}
375EXPORT_SYMBOL(gpio_direction_input);
376
377int gpio_direction_output(unsigned gpio, int value)
378{
379 unsigned long flags;
380 u32 val;
381
382 if (gpio > U300_GPIO_MAX)
383 return -EINVAL;
384
385 local_irq_save(flags);
386 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
387 U300_GPIO_PORTX_SPACING);
388 /* Mask out this pin */
389 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
390 /*
391 * FIXME: configure for push/pull, open drain or open source per pin
392 * in setup. The current driver will only support push/pull.
393 */
394 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
395 << ((gpio & 0x07) << 1));
396 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
397 U300_GPIO_PORTX_SPACING);
398 gpio_set_value(gpio, value);
399 local_irq_restore(flags);
400 return 0;
401}
402EXPORT_SYMBOL(gpio_direction_output);
403
404/*
405 * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
406 */
407void enable_irq_on_gpio_pin(unsigned gpio, int edge)
408{
409 u32 val;
410 unsigned long flags;
411 local_irq_save(flags);
412
413 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
414 U300_GPIO_PORTX_SPACING);
415 val |= (1 << (gpio & 0x07));
416 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
417 U300_GPIO_PORTX_SPACING);
418 val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
419 U300_GPIO_PORTX_SPACING);
420 if (edge)
421 val |= (1 << (gpio & 0x07));
422 else
423 val &= ~(1 << (gpio & 0x07));
424 writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
425 U300_GPIO_PORTX_SPACING);
426 local_irq_restore(flags);
427}
428EXPORT_SYMBOL(enable_irq_on_gpio_pin);
429
430void disable_irq_on_gpio_pin(unsigned gpio)
431{
432 u32 val;
433 unsigned long flags;
434
435 local_irq_save(flags);
436 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
437 U300_GPIO_PORTX_SPACING);
438 val &= ~(1 << (gpio & 0x07));
439 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
440 U300_GPIO_PORTX_SPACING);
441 local_irq_restore(flags);
442}
443EXPORT_SYMBOL(disable_irq_on_gpio_pin);
444
445/* Enable (value == 0) or disable (value == 1) internal pullup */
446void gpio_pullup(unsigned gpio, int value)
447{
448 u32 val;
449 unsigned long flags;
450
451 local_irq_save(flags);
452 if (value) {
453 val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
454 U300_GPIO_PORTX_SPACING);
455 writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
456 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
457 } else {
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 }
463 local_irq_restore(flags);
464}
465EXPORT_SYMBOL(gpio_pullup);
466
467static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
468{
469 struct u300_gpio_port *port = dev_id;
470 u32 val;
471 int pin;
472
473 /* Read event register */
474 val = readl(virtbase + U300_GPIO_PXIEV + port->number *
475 U300_GPIO_PORTX_SPACING);
476 /* Mask with enable register */
477 val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
478 U300_GPIO_PORTX_SPACING);
479 /* Mask relevant bits */
480 val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
481 /* ACK IRQ (clear event) */
482 writel(val, virtbase + U300_GPIO_PXIEV + port->number *
483 U300_GPIO_PORTX_SPACING);
484 /* Print message */
485 while (val != 0) {
486 unsigned gpio;
487
488 pin = __ffs(val);
489 /* mask off this pin */
490 val &= ~(1 << pin);
491 gpio = (port->number << 3) + pin;
492
493 if (gpio_pin[gpio].callback)
494 (void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
495 else
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100496 dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
Linus Walleijbd41b992009-04-23 21:15:04 +0100497 gpio);
498 }
499 return IRQ_HANDLED;
500}
501
502static void gpio_set_initial_values(void)
503{
504#ifdef U300_COH901571_3
505 int i, j;
506 unsigned long flags;
507 u32 val;
508
509 /* Write default values to all pins */
510 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
511 val = 0;
512 for (j = 0; j < 8; j++)
513 val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
514 local_irq_save(flags);
515 writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
516 local_irq_restore(flags);
517 }
518
519 /*
520 * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
521 * to output and 'GPIO_IN' to input for each port. And initalize
522 * default value on outputs.
523 */
524 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
525 for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
526 local_irq_save(flags);
527 val = readl(virtbase + U300_GPIO_PXPCR +
528 i * U300_GPIO_PORTX_SPACING);
529 /* Mask out this pin */
530 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
531
532 if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
533 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
534 writel(val, virtbase + U300_GPIO_PXPCR +
535 i * U300_GPIO_PORTX_SPACING);
536 local_irq_restore(flags);
537 }
538 }
539
540 /* Enable or disable the internal pull-ups in the GPIO ASIC block */
541 for (i = 0; i < U300_GPIO_MAX; i++) {
542 val = 0;
543 for (j = 0; j < 8; j++)
544 val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j;
545 local_irq_save(flags);
546 writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
547 local_irq_restore(flags);
548 }
549#endif
550}
551
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100552static int __init gpio_probe(struct platform_device *pdev)
Linus Walleijbd41b992009-04-23 21:15:04 +0100553{
554 u32 val;
555 int err = 0;
556 int i;
557 int num_irqs;
558
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100559 gpiodev = &pdev->dev;
Linus Walleijbd41b992009-04-23 21:15:04 +0100560 memset(gpio_pin, 0, sizeof(gpio_pin));
561
562 /* Get GPIO clock */
563 clk = clk_get(&pdev->dev, NULL);
564 if (IS_ERR(clk)) {
565 err = PTR_ERR(clk);
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100566 dev_err(gpiodev, "could not get GPIO clock\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100567 goto err_no_clk;
568 }
569 err = clk_enable(clk);
570 if (err) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100571 dev_err(gpiodev, "could not enable GPIO clock\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100572 goto err_no_clk_enable;
573 }
574
575 memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
576 if (!memres)
577 goto err_no_resource;
578
579 if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller")
580 == NULL) {
581 err = -ENODEV;
582 goto err_no_ioregion;
583 }
584
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100585 virtbase = ioremap(memres->start, resource_size(memres));
Linus Walleijbd41b992009-04-23 21:15:04 +0100586 if (!virtbase) {
587 err = -ENOMEM;
588 goto err_no_ioremap;
589 }
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100590 dev_info(gpiodev, "remapped 0x%08x to %p\n",
591 memres->start, virtbase);
Linus Walleijbd41b992009-04-23 21:15:04 +0100592
593#ifdef U300_COH901335
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100594 dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100595 /* Turn on the GPIO block */
596 writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
597#endif
598
599#ifdef U300_COH901571_3
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100600 dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100601 val = readl(virtbase + U300_GPIO_CR);
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100602 dev_info(gpiodev, "COH901571/3 block version: %d, " \
Linus Walleijbd41b992009-04-23 21:15:04 +0100603 "number of cores: %d\n",
604 ((val & 0x0000FE00) >> 9),
605 ((val & 0x000001FC) >> 2));
606 writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
607#endif
608
609 /* Set up some padmuxing here */
610#ifdef CONFIG_MMC
611 pmx_set_mission_mode_mmc();
612#endif
613#ifdef CONFIG_SPI_PL022
614 pmx_set_mission_mode_spi();
615#endif
616
617 gpio_set_initial_values();
618
619 for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
620
621 gpio_ports[num_irqs].irq =
622 platform_get_irq_byname(pdev,
623 gpio_ports[num_irqs].name);
624
625 err = request_irq(gpio_ports[num_irqs].irq,
626 gpio_irq_handler, IRQF_DISABLED,
627 gpio_ports[num_irqs].name,
628 &gpio_ports[num_irqs]);
629 if (err) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100630 dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
631 gpio_ports[num_irqs].name);
Linus Walleijbd41b992009-04-23 21:15:04 +0100632 goto err_no_irq;
633 }
634 /* Turns off PortX_irq_force */
635 writel(0x0, virtbase + U300_GPIO_PXIFR +
636 num_irqs * U300_GPIO_PORTX_SPACING);
637 }
Linus Walleijbd41b992009-04-23 21:15:04 +0100638
639 return 0;
640
641 err_no_irq:
642 for (i = 0; i < num_irqs; i++)
643 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
644 iounmap(virtbase);
645 err_no_ioremap:
646 release_mem_region(memres->start, memres->end - memres->start);
647 err_no_ioregion:
648 err_no_resource:
649 clk_disable(clk);
650 err_no_clk_enable:
651 clk_put(clk);
652 err_no_clk:
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100653 dev_info(gpiodev, "module ERROR:%d\n", err);
Linus Walleijbd41b992009-04-23 21:15:04 +0100654 return err;
655}
656
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100657static int __exit gpio_remove(struct platform_device *pdev)
Linus Walleijbd41b992009-04-23 21:15:04 +0100658{
659 int i;
660
661 /* Turn off the GPIO block */
662 writel(0x00000000U, virtbase + U300_GPIO_CR);
663 for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
664 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
665 iounmap(virtbase);
666 release_mem_region(memres->start, memres->end - memres->start);
667 clk_disable(clk);
668 clk_put(clk);
669 return 0;
670}
671
672static struct platform_driver gpio_driver = {
673 .driver = {
674 .name = "u300-gpio",
675 },
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100676 .remove = __exit_p(gpio_remove),
Linus Walleijbd41b992009-04-23 21:15:04 +0100677};
678
679
680static int __init u300_gpio_init(void)
681{
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100682 return platform_driver_probe(&gpio_driver, gpio_probe);
Linus Walleijbd41b992009-04-23 21:15:04 +0100683}
684
685static void __exit u300_gpio_exit(void)
686{
687 platform_driver_unregister(&gpio_driver);
688}
689
690arch_initcall(u300_gpio_init);
691module_exit(u300_gpio_exit);
692
693MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
694
695#ifdef U300_COH901571_3
696MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
697#endif
698
699#ifdef U300_COH901335
700MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
701#endif
702
703MODULE_LICENSE("GPL");