blob: 63c8f27fb15a3bc6a5eba1ec4bb8742f02275081 [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
284int gpio_request(unsigned gpio, const char *label)
285{
286 if (gpio_pin[gpio].users)
287 return -EINVAL;
288 else
289 gpio_pin[gpio].users++;
290
291 gpio_users++;
292
293 return 0;
294}
295EXPORT_SYMBOL(gpio_request);
296
297void gpio_free(unsigned gpio)
298{
299 gpio_users--;
300 gpio_pin[gpio].users--;
301 if (unlikely(gpio_pin[gpio].users < 0)) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100302 dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
303 gpio);
Linus Walleijbd41b992009-04-23 21:15:04 +0100304 gpio_pin[gpio].users = 0;
305 }
306
307 return;
308}
309EXPORT_SYMBOL(gpio_free);
310
311/* This returns zero or nonzero */
312int gpio_get_value(unsigned gpio)
313{
314 return readl(virtbase + U300_GPIO_PXPDIR +
315 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
316}
317EXPORT_SYMBOL(gpio_get_value);
318
319/*
320 * We hope that the compiler will optimize away the unused branch
321 * in case "value" is a constant
322 */
323void gpio_set_value(unsigned gpio, int value)
324{
325 u32 val;
326 unsigned long flags;
327
328 local_irq_save(flags);
329 if (value) {
330 /* set */
331 val = readl(virtbase + U300_GPIO_PXPDOR +
332 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
333 & (1 << (gpio & 0x07));
334 writel(val | (1 << (gpio & 0x07)), virtbase +
335 U300_GPIO_PXPDOR +
336 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
337 } else {
338 /* clear */
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 }
346 local_irq_restore(flags);
347}
348EXPORT_SYMBOL(gpio_set_value);
349
350int gpio_direction_input(unsigned gpio)
351{
352 unsigned long flags;
353 u32 val;
354
355 if (gpio > U300_GPIO_MAX)
356 return -EINVAL;
357
358 local_irq_save(flags);
359 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
360 U300_GPIO_PORTX_SPACING);
361 /* Mask out this pin*/
362 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
363 /* This is not needed since it sets the bits to zero.*/
364 /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
365 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
366 U300_GPIO_PORTX_SPACING);
367 local_irq_restore(flags);
368 return 0;
369}
370EXPORT_SYMBOL(gpio_direction_input);
371
372int gpio_direction_output(unsigned gpio, int value)
373{
374 unsigned long flags;
375 u32 val;
376
377 if (gpio > U300_GPIO_MAX)
378 return -EINVAL;
379
380 local_irq_save(flags);
381 val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
382 U300_GPIO_PORTX_SPACING);
383 /* Mask out this pin */
384 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
385 /*
386 * FIXME: configure for push/pull, open drain or open source per pin
387 * in setup. The current driver will only support push/pull.
388 */
389 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
390 << ((gpio & 0x07) << 1));
391 writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
392 U300_GPIO_PORTX_SPACING);
393 gpio_set_value(gpio, value);
394 local_irq_restore(flags);
395 return 0;
396}
397EXPORT_SYMBOL(gpio_direction_output);
398
399/*
400 * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
401 */
402void enable_irq_on_gpio_pin(unsigned gpio, int edge)
403{
404 u32 val;
405 unsigned long flags;
406 local_irq_save(flags);
407
408 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
409 U300_GPIO_PORTX_SPACING);
410 val |= (1 << (gpio & 0x07));
411 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
412 U300_GPIO_PORTX_SPACING);
413 val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
414 U300_GPIO_PORTX_SPACING);
415 if (edge)
416 val |= (1 << (gpio & 0x07));
417 else
418 val &= ~(1 << (gpio & 0x07));
419 writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
420 U300_GPIO_PORTX_SPACING);
421 local_irq_restore(flags);
422}
423EXPORT_SYMBOL(enable_irq_on_gpio_pin);
424
425void disable_irq_on_gpio_pin(unsigned gpio)
426{
427 u32 val;
428 unsigned long flags;
429
430 local_irq_save(flags);
431 val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
432 U300_GPIO_PORTX_SPACING);
433 val &= ~(1 << (gpio & 0x07));
434 writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
435 U300_GPIO_PORTX_SPACING);
436 local_irq_restore(flags);
437}
438EXPORT_SYMBOL(disable_irq_on_gpio_pin);
439
440/* Enable (value == 0) or disable (value == 1) internal pullup */
441void gpio_pullup(unsigned gpio, int value)
442{
443 u32 val;
444 unsigned long flags;
445
446 local_irq_save(flags);
447 if (value) {
448 val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
449 U300_GPIO_PORTX_SPACING);
450 writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
451 PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
452 } else {
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 }
458 local_irq_restore(flags);
459}
460EXPORT_SYMBOL(gpio_pullup);
461
462static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
463{
464 struct u300_gpio_port *port = dev_id;
465 u32 val;
466 int pin;
467
468 /* Read event register */
469 val = readl(virtbase + U300_GPIO_PXIEV + port->number *
470 U300_GPIO_PORTX_SPACING);
471 /* Mask with enable register */
472 val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
473 U300_GPIO_PORTX_SPACING);
474 /* Mask relevant bits */
475 val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
476 /* ACK IRQ (clear event) */
477 writel(val, virtbase + U300_GPIO_PXIEV + port->number *
478 U300_GPIO_PORTX_SPACING);
479 /* Print message */
480 while (val != 0) {
481 unsigned gpio;
482
483 pin = __ffs(val);
484 /* mask off this pin */
485 val &= ~(1 << pin);
486 gpio = (port->number << 3) + pin;
487
488 if (gpio_pin[gpio].callback)
489 (void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
490 else
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100491 dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
Linus Walleijbd41b992009-04-23 21:15:04 +0100492 gpio);
493 }
494 return IRQ_HANDLED;
495}
496
497static void gpio_set_initial_values(void)
498{
499#ifdef U300_COH901571_3
500 int i, j;
501 unsigned long flags;
502 u32 val;
503
504 /* Write default values to all pins */
505 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
506 val = 0;
507 for (j = 0; j < 8; j++)
508 val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
509 local_irq_save(flags);
510 writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
511 local_irq_restore(flags);
512 }
513
514 /*
515 * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
516 * to output and 'GPIO_IN' to input for each port. And initalize
517 * default value on outputs.
518 */
519 for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
520 for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
521 local_irq_save(flags);
522 val = readl(virtbase + U300_GPIO_PXPCR +
523 i * U300_GPIO_PORTX_SPACING);
524 /* Mask out this pin */
525 val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
526
527 if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
528 val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
529 writel(val, virtbase + U300_GPIO_PXPCR +
530 i * U300_GPIO_PORTX_SPACING);
531 local_irq_restore(flags);
532 }
533 }
534
535 /* Enable or disable the internal pull-ups in the GPIO ASIC block */
536 for (i = 0; i < U300_GPIO_MAX; i++) {
537 val = 0;
538 for (j = 0; j < 8; j++)
539 val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j;
540 local_irq_save(flags);
541 writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
542 local_irq_restore(flags);
543 }
544#endif
545}
546
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100547static int __init gpio_probe(struct platform_device *pdev)
Linus Walleijbd41b992009-04-23 21:15:04 +0100548{
549 u32 val;
550 int err = 0;
551 int i;
552 int num_irqs;
553
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100554 gpiodev = &pdev->dev;
Linus Walleijbd41b992009-04-23 21:15:04 +0100555 memset(gpio_pin, 0, sizeof(gpio_pin));
556
557 /* Get GPIO clock */
558 clk = clk_get(&pdev->dev, NULL);
559 if (IS_ERR(clk)) {
560 err = PTR_ERR(clk);
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100561 dev_err(gpiodev, "could not get GPIO clock\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100562 goto err_no_clk;
563 }
564 err = clk_enable(clk);
565 if (err) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100566 dev_err(gpiodev, "could not enable GPIO clock\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100567 goto err_no_clk_enable;
568 }
569
570 memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
571 if (!memres)
572 goto err_no_resource;
573
574 if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller")
575 == NULL) {
576 err = -ENODEV;
577 goto err_no_ioregion;
578 }
579
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100580 virtbase = ioremap(memres->start, resource_size(memres));
Linus Walleijbd41b992009-04-23 21:15:04 +0100581 if (!virtbase) {
582 err = -ENOMEM;
583 goto err_no_ioremap;
584 }
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100585 dev_info(gpiodev, "remapped 0x%08x to %p\n",
586 memres->start, virtbase);
Linus Walleijbd41b992009-04-23 21:15:04 +0100587
588#ifdef U300_COH901335
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100589 dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100590 /* Turn on the GPIO block */
591 writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
592#endif
593
594#ifdef U300_COH901571_3
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100595 dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
Linus Walleijbd41b992009-04-23 21:15:04 +0100596 val = readl(virtbase + U300_GPIO_CR);
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100597 dev_info(gpiodev, "COH901571/3 block version: %d, " \
Linus Walleijbd41b992009-04-23 21:15:04 +0100598 "number of cores: %d\n",
599 ((val & 0x0000FE00) >> 9),
600 ((val & 0x000001FC) >> 2));
601 writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
602#endif
603
Linus Walleijbd41b992009-04-23 21:15:04 +0100604 gpio_set_initial_values();
605
606 for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
607
608 gpio_ports[num_irqs].irq =
609 platform_get_irq_byname(pdev,
610 gpio_ports[num_irqs].name);
611
612 err = request_irq(gpio_ports[num_irqs].irq,
613 gpio_irq_handler, IRQF_DISABLED,
614 gpio_ports[num_irqs].name,
615 &gpio_ports[num_irqs]);
616 if (err) {
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100617 dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
618 gpio_ports[num_irqs].name);
Linus Walleijbd41b992009-04-23 21:15:04 +0100619 goto err_no_irq;
620 }
621 /* Turns off PortX_irq_force */
622 writel(0x0, virtbase + U300_GPIO_PXIFR +
623 num_irqs * U300_GPIO_PORTX_SPACING);
624 }
Linus Walleijbd41b992009-04-23 21:15:04 +0100625
626 return 0;
627
628 err_no_irq:
629 for (i = 0; i < num_irqs; i++)
630 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
631 iounmap(virtbase);
632 err_no_ioremap:
633 release_mem_region(memres->start, memres->end - memres->start);
634 err_no_ioregion:
635 err_no_resource:
636 clk_disable(clk);
637 err_no_clk_enable:
638 clk_put(clk);
639 err_no_clk:
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100640 dev_info(gpiodev, "module ERROR:%d\n", err);
Linus Walleijbd41b992009-04-23 21:15:04 +0100641 return err;
642}
643
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100644static int __exit gpio_remove(struct platform_device *pdev)
Linus Walleijbd41b992009-04-23 21:15:04 +0100645{
646 int i;
647
648 /* Turn off the GPIO block */
649 writel(0x00000000U, virtbase + U300_GPIO_CR);
650 for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
651 free_irq(gpio_ports[i].irq, &gpio_ports[i]);
652 iounmap(virtbase);
653 release_mem_region(memres->start, memres->end - memres->start);
654 clk_disable(clk);
655 clk_put(clk);
656 return 0;
657}
658
659static struct platform_driver gpio_driver = {
660 .driver = {
661 .name = "u300-gpio",
662 },
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100663 .remove = __exit_p(gpio_remove),
Linus Walleijbd41b992009-04-23 21:15:04 +0100664};
665
666
667static int __init u300_gpio_init(void)
668{
Linus Walleijf7a9a4d2009-05-08 08:59:51 +0100669 return platform_driver_probe(&gpio_driver, gpio_probe);
Linus Walleijbd41b992009-04-23 21:15:04 +0100670}
671
672static void __exit u300_gpio_exit(void)
673{
674 platform_driver_unregister(&gpio_driver);
675}
676
677arch_initcall(u300_gpio_init);
678module_exit(u300_gpio_exit);
679
680MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
681
682#ifdef U300_COH901571_3
683MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
684#endif
685
686#ifdef U300_COH901335
687MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
688#endif
689
690MODULE_LICENSE("GPL");