aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91/gpio.c
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2010-07-20 13:18:51 -0400
committerNicolas Ferre <nicolas.ferre@atmel.com>2012-03-01 07:38:50 -0500
commit582d5fbd4e81e7debe5f3a0e6ce1a0bcdf636c6e (patch)
treedd51bedcd86e887b44d85b79b9d506a79599af0f /arch/arm/mach-at91/gpio.c
parent9a9fe01ecf68c9b100499908122944597c63f21f (diff)
ARM: at91/pio: add new PIO3 features
This patch adds the support for new PIO controller found on some at91sam SOCs. - more peripheral multiplexing - more features to configure on a PIO (pull-down, Schmitt trigger, debouncer) - support for several IRQ triggering features (type and polarity) Support for those new features are retrieved from the device tree compatibility string. Debugfs at91_gpio file is updated to monitor configuration. Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'arch/arm/mach-at91/gpio.c')
-rw-r--r--arch/arm/mach-at91/gpio.c262
1 files changed, 246 insertions, 16 deletions
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 567df654a2e1..325837a264c9 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -76,6 +76,14 @@ static struct at91_gpio_chip gpio_chip[] = {
76}; 76};
77 77
78static int gpio_banks; 78static int gpio_banks;
79static unsigned long at91_gpio_caps;
80
81/* All PIO controllers support PIO3 features */
82#define AT91_GPIO_CAP_PIO3 (1 << 0)
83
84#define has_pio3() (at91_gpio_caps & AT91_GPIO_CAP_PIO3)
85
86/*--------------------------------------------------------------------------*/
79 87
80static inline void __iomem *pin_to_controller(unsigned pin) 88static inline void __iomem *pin_to_controller(unsigned pin)
81{ 89{
@@ -92,6 +100,25 @@ static inline unsigned pin_to_mask(unsigned pin)
92} 100}
93 101
94 102
103static char peripheral_function(void __iomem *pio, unsigned mask)
104{
105 char ret = 'X';
106 u8 select;
107
108 if (pio) {
109 if (has_pio3()) {
110 select = !!(__raw_readl(pio + PIO_ABCDSR1) & mask);
111 select |= (!!(__raw_readl(pio + PIO_ABCDSR2) & mask) << 1);
112 ret = 'A' + select;
113 } else {
114 ret = __raw_readl(pio + PIO_ABSR) & mask ?
115 'B' : 'A';
116 }
117 }
118
119 return ret;
120}
121
95/*--------------------------------------------------------------------------*/ 122/*--------------------------------------------------------------------------*/
96 123
97/* Not all hardware capabilities are exposed through these calls; they 124/* Not all hardware capabilities are exposed through these calls; they
@@ -139,7 +166,14 @@ int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup)
139 166
140 __raw_writel(mask, pio + PIO_IDR); 167 __raw_writel(mask, pio + PIO_IDR);
141 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); 168 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
142 __raw_writel(mask, pio + PIO_ASR); 169 if (has_pio3()) {
170 __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask,
171 pio + PIO_ABCDSR1);
172 __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
173 pio + PIO_ABCDSR2);
174 } else {
175 __raw_writel(mask, pio + PIO_ASR);
176 }
143 __raw_writel(mask, pio + PIO_PDR); 177 __raw_writel(mask, pio + PIO_PDR);
144 return 0; 178 return 0;
145} 179}
@@ -159,7 +193,14 @@ int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup)
159 193
160 __raw_writel(mask, pio + PIO_IDR); 194 __raw_writel(mask, pio + PIO_IDR);
161 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); 195 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
162 __raw_writel(mask, pio + PIO_BSR); 196 if (has_pio3()) {
197 __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask,
198 pio + PIO_ABCDSR1);
199 __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
200 pio + PIO_ABCDSR2);
201 } else {
202 __raw_writel(mask, pio + PIO_BSR);
203 }
163 __raw_writel(mask, pio + PIO_PDR); 204 __raw_writel(mask, pio + PIO_PDR);
164 return 0; 205 return 0;
165} 206}
@@ -167,8 +208,50 @@ EXPORT_SYMBOL(at91_set_B_periph);
167 208
168 209
169/* 210/*
170 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and 211 * mux the pin to the "C" internal peripheral role.
171 * configure it for an input. 212 */
213int __init_or_module at91_set_C_periph(unsigned pin, int use_pullup)
214{
215 void __iomem *pio = pin_to_controller(pin);
216 unsigned mask = pin_to_mask(pin);
217
218 if (!pio || !has_pio3())
219 return -EINVAL;
220
221 __raw_writel(mask, pio + PIO_IDR);
222 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
223 __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1);
224 __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
225 __raw_writel(mask, pio + PIO_PDR);
226 return 0;
227}
228EXPORT_SYMBOL(at91_set_C_periph);
229
230
231/*
232 * mux the pin to the "D" internal peripheral role.
233 */
234int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup)
235{
236 void __iomem *pio = pin_to_controller(pin);
237 unsigned mask = pin_to_mask(pin);
238
239 if (!pio || !has_pio3())
240 return -EINVAL;
241
242 __raw_writel(mask, pio + PIO_IDR);
243 __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
244 __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1);
245 __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
246 __raw_writel(mask, pio + PIO_PDR);
247 return 0;
248}
249EXPORT_SYMBOL(at91_set_D_periph);
250
251
252/*
253 * mux the pin to the gpio controller (instead of "A", "B", "C"
254 * or "D" peripheral), and configure it for an input.
172 */ 255 */
173int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) 256int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup)
174{ 257{
@@ -188,8 +271,8 @@ EXPORT_SYMBOL(at91_set_gpio_input);
188 271
189 272
190/* 273/*
191 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), 274 * mux the pin to the gpio controller (instead of "A", "B", "C"
192 * and configure it for an output. 275 * or "D" peripheral), and configure it for an output.
193 */ 276 */
194int __init_or_module at91_set_gpio_output(unsigned pin, int value) 277int __init_or_module at91_set_gpio_output(unsigned pin, int value)
195{ 278{
@@ -219,12 +302,37 @@ int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
219 302
220 if (!pio) 303 if (!pio)
221 return -EINVAL; 304 return -EINVAL;
305
306 if (has_pio3() && is_on)
307 __raw_writel(mask, pio + PIO_IFSCDR);
222 __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); 308 __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
223 return 0; 309 return 0;
224} 310}
225EXPORT_SYMBOL(at91_set_deglitch); 311EXPORT_SYMBOL(at91_set_deglitch);
226 312
227/* 313/*
314 * enable/disable the debounce filter;
315 */
316int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div)
317{
318 void __iomem *pio = pin_to_controller(pin);
319 unsigned mask = pin_to_mask(pin);
320
321 if (!pio || !has_pio3())
322 return -EINVAL;
323
324 if (is_on) {
325 __raw_writel(mask, pio + PIO_IFSCER);
326 __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
327 __raw_writel(mask, pio + PIO_IFER);
328 } else {
329 __raw_writel(mask, pio + PIO_IFDR);
330 }
331 return 0;
332}
333EXPORT_SYMBOL(at91_set_debounce);
334
335/*
228 * enable/disable the multi-driver; This is only valid for output and 336 * enable/disable the multi-driver; This is only valid for output and
229 * allows the output pin to run as an open collector output. 337 * allows the output pin to run as an open collector output.
230 */ 338 */
@@ -242,6 +350,41 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on)
242EXPORT_SYMBOL(at91_set_multi_drive); 350EXPORT_SYMBOL(at91_set_multi_drive);
243 351
244/* 352/*
353 * enable/disable the pull-down.
354 * If pull-up already enabled while calling the function, we disable it.
355 */
356int __init_or_module at91_set_pulldown(unsigned pin, int is_on)
357{
358 void __iomem *pio = pin_to_controller(pin);
359 unsigned mask = pin_to_mask(pin);
360
361 if (!pio || !has_pio3())
362 return -EINVAL;
363
364 /* Disable pull-up anyway */
365 __raw_writel(mask, pio + PIO_PUDR);
366 __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
367 return 0;
368}
369EXPORT_SYMBOL(at91_set_pulldown);
370
371/*
372 * disable Schmitt trigger
373 */
374int __init_or_module at91_disable_schmitt_trig(unsigned pin)
375{
376 void __iomem *pio = pin_to_controller(pin);
377 unsigned mask = pin_to_mask(pin);
378
379 if (!pio || !has_pio3())
380 return -EINVAL;
381
382 __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
383 return 0;
384}
385EXPORT_SYMBOL(at91_disable_schmitt_trig);
386
387/*
245 * assuming the pin is muxed as a gpio output, set its value. 388 * assuming the pin is muxed as a gpio output, set its value.
246 */ 389 */
247int at91_set_gpio_value(unsigned pin, int value) 390int at91_set_gpio_value(unsigned pin, int value)
@@ -347,7 +490,10 @@ void at91_gpio_resume(void)
347 * To use any AT91_PIN_* as an externally triggered IRQ, first call 490 * To use any AT91_PIN_* as an externally triggered IRQ, first call
348 * at91_set_gpio_input() then maybe enable its glitch filter. 491 * at91_set_gpio_input() then maybe enable its glitch filter.
349 * Then just request_irq() with the pin ID; it works like any ARM IRQ 492 * Then just request_irq() with the pin ID; it works like any ARM IRQ
350 * handler, though it always triggers on rising and falling edges. 493 * handler.
494 * First implementation always triggers on rising and falling edges
495 * whereas the newer PIO3 can be additionally configured to trigger on
496 * level, edge with any polarity.
351 * 497 *
352 * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after 498 * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
353 * configuring them with at91_set_a_periph() or at91_set_b_periph(). 499 * configuring them with at91_set_a_periph() or at91_set_b_periph().
@@ -385,12 +531,55 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
385 } 531 }
386} 532}
387 533
534/* Alternate irq type for PIO3 support */
535static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
536{
537 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
538 void __iomem *pio = at91_gpio->regbase;
539 unsigned mask = 1 << d->hwirq;
540
541 switch (type) {
542 case IRQ_TYPE_EDGE_RISING:
543 __raw_writel(mask, pio + PIO_ESR);
544 __raw_writel(mask, pio + PIO_REHLSR);
545 break;
546 case IRQ_TYPE_EDGE_FALLING:
547 __raw_writel(mask, pio + PIO_ESR);
548 __raw_writel(mask, pio + PIO_FELLSR);
549 break;
550 case IRQ_TYPE_LEVEL_LOW:
551 __raw_writel(mask, pio + PIO_LSR);
552 __raw_writel(mask, pio + PIO_FELLSR);
553 break;
554 case IRQ_TYPE_LEVEL_HIGH:
555 __raw_writel(mask, pio + PIO_LSR);
556 __raw_writel(mask, pio + PIO_REHLSR);
557 break;
558 case IRQ_TYPE_EDGE_BOTH:
559 /*
560 * disable additional interrupt modes:
561 * fall back to default behavior
562 */
563 __raw_writel(mask, pio + PIO_AIMDR);
564 return 0;
565 case IRQ_TYPE_NONE:
566 default:
567 pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq));
568 return -EINVAL;
569 }
570
571 /* enable additional interrupt modes */
572 __raw_writel(mask, pio + PIO_AIMER);
573
574 return 0;
575}
576
388static struct irq_chip gpio_irqchip = { 577static struct irq_chip gpio_irqchip = {
389 .name = "GPIO", 578 .name = "GPIO",
390 .irq_disable = gpio_irq_mask, 579 .irq_disable = gpio_irq_mask,
391 .irq_mask = gpio_irq_mask, 580 .irq_mask = gpio_irq_mask,
392 .irq_unmask = gpio_irq_unmask, 581 .irq_unmask = gpio_irq_unmask,
393 .irq_set_type = gpio_irq_type, 582 /* .irq_set_type is set dynamically */
394 .irq_set_wake = gpio_irq_set_wake, 583 .irq_set_wake = gpio_irq_set_wake,
395}; 584};
396 585
@@ -433,6 +622,33 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
433 622
434#ifdef CONFIG_DEBUG_FS 623#ifdef CONFIG_DEBUG_FS
435 624
625static void gpio_printf(struct seq_file *s, void __iomem *pio, unsigned mask)
626{
627 char *trigger = NULL;
628 char *polarity = NULL;
629
630 if (__raw_readl(pio + PIO_IMR) & mask) {
631 if (!has_pio3() || !(__raw_readl(pio + PIO_AIMMR) & mask )) {
632 trigger = "edge";
633 polarity = "both";
634 } else {
635 if (__raw_readl(pio + PIO_ELSR) & mask) {
636 trigger = "level";
637 polarity = __raw_readl(pio + PIO_FRLHSR) & mask ?
638 "high" : "low";
639 } else {
640 trigger = "edge";
641 polarity = __raw_readl(pio + PIO_FRLHSR) & mask ?
642 "rising" : "falling";
643 }
644 }
645 seq_printf(s, "IRQ:%s-%s\t", trigger, polarity);
646 } else {
647 seq_printf(s, "GPIO:%s\t\t",
648 __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
649 }
650}
651
436static int at91_gpio_show(struct seq_file *s, void *unused) 652static int at91_gpio_show(struct seq_file *s, void *unused)
437{ 653{
438 int bank, j; 654 int bank, j;
@@ -440,7 +656,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused)
440 /* print heading */ 656 /* print heading */
441 seq_printf(s, "Pin\t"); 657 seq_printf(s, "Pin\t");
442 for (bank = 0; bank < gpio_banks; bank++) { 658 for (bank = 0; bank < gpio_banks; bank++) {
443 seq_printf(s, "PIO%c\t", 'A' + bank); 659 seq_printf(s, "PIO%c\t\t", 'A' + bank);
444 }; 660 };
445 seq_printf(s, "\n\n"); 661 seq_printf(s, "\n\n");
446 662
@@ -454,11 +670,10 @@ static int at91_gpio_show(struct seq_file *s, void *unused)
454 unsigned mask = pin_to_mask(pin); 670 unsigned mask = pin_to_mask(pin);
455 671
456 if (__raw_readl(pio + PIO_PSR) & mask) 672 if (__raw_readl(pio + PIO_PSR) & mask)
457 seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0"); 673 gpio_printf(s, pio, mask);
458 else 674 else
459 seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A"); 675 seq_printf(s, "%c\t\t",
460 676 peripheral_function(pio, mask));
461 seq_printf(s, "\t");
462 } 677 }
463 678
464 seq_printf(s, "\n"); 679 seq_printf(s, "\n");
@@ -529,6 +744,12 @@ int __init at91_gpio_of_irq_setup(struct device_node *node,
529 int alias_idx = of_alias_get_id(node, "gpio"); 744 int alias_idx = of_alias_get_id(node, "gpio");
530 struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx]; 745 struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx];
531 746
747 /* Setup proper .irq_set_type function */
748 if (has_pio3())
749 gpio_irqchip.irq_set_type = alt_gpio_irq_type;
750 else
751 gpio_irqchip.irq_set_type = gpio_irq_type;
752
532 /* Disable irqs of this PIO controller */ 753 /* Disable irqs of this PIO controller */
533 __raw_writel(~0, at91_gpio->regbase + PIO_IDR); 754 __raw_writel(~0, at91_gpio->regbase + PIO_IDR);
534 755
@@ -593,6 +814,12 @@ void __init at91_gpio_irq_setup(void)
593 int gpio_irqnbr = 0; 814 int gpio_irqnbr = 0;
594 struct at91_gpio_chip *this, *prev; 815 struct at91_gpio_chip *this, *prev;
595 816
817 /* Setup proper .irq_set_type function */
818 if (has_pio3())
819 gpio_irqchip.irq_set_type = alt_gpio_irq_type;
820 else
821 gpio_irqchip.irq_set_type = gpio_irq_type;
822
596 for (pioc = 0, this = gpio_chip, prev = NULL; 823 for (pioc = 0, this = gpio_chip, prev = NULL;
597 pioc++ < gpio_banks; 824 pioc++ < gpio_banks;
598 prev = this, this++) { 825 prev = this, this++) {
@@ -696,9 +923,8 @@ static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
696 at91_get_gpio_value(pin) ? 923 at91_get_gpio_value(pin) ?
697 "set" : "clear"); 924 "set" : "clear");
698 else 925 else
699 seq_printf(s, "[periph %s]\n", 926 seq_printf(s, "[periph %c]\n",
700 __raw_readl(pio + PIO_ABSR) & 927 peripheral_function(pio, mask));
701 mask ? "B" : "A");
702 } 928 }
703 } 929 }
704} 930}
@@ -781,6 +1007,10 @@ static void __init of_at91_gpio_init_one(struct device_node *np)
781 goto ioremap_err; 1007 goto ioremap_err;
782 } 1008 }
783 1009
1010 /* Get capabilities from compatibility property */
1011 if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio"))
1012 at91_gpio_caps |= AT91_GPIO_CAP_PIO3;
1013
784 /* Setup clock */ 1014 /* Setup clock */
785 if (at91_gpio_setup_clk(alias_idx)) 1015 if (at91_gpio_setup_clk(alias_idx))
786 goto ioremap_err; 1016 goto ioremap_err;