aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2017-04-07 08:59:01 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-04-24 08:49:53 -0400
commit5ae4cb94b3133d00857bb2909dae779782db40cb (patch)
treedb147b3a31d25174bc443168db106511b9a4b5ab
parent9d7163f5167fa60e71071ab6dcb60da0f7230beb (diff)
gpio: aspeed: Add debounce support
Each GPIO in the Aspeed GPIO controller can choose one of four input debounce states: to disable debouncing for an input, or select from one of three programmable debounce timer values. Each GPIO in a four-bank-set is assigned one bit in each of two debounce configuration registers dedicated to the set, and selects a debounce state by configuring the two bits to select one of the four options. The limitation on debounce timer values is managed by mapping offsets onto a configured timer value and keeping count of the number of users a timer has. Timer values are configured on a first-come-first-served basis. A small twist in the hardware design is that the debounce configuration register numbering is reversed with respect to the binary representation of the debounce timer of interest (i.e. debounce register 1 represents bit 1, and debounce register 2 represents bit 0 of the timer numbering). Tested on an AST2500EVB with additional inspection under QEMU's romulus-bmc machine. Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/gpio-aspeed.c281
1 files changed, 276 insertions, 5 deletions
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index fb16cc771c0d..3327a48df862 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -9,14 +9,18 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <asm/div64.h>
13#include <linux/kernel.h> 13#include <linux/clk.h>
14#include <linux/gpio/driver.h>
15#include <linux/hashtable.h>
14#include <linux/init.h> 16#include <linux/init.h>
15#include <linux/io.h> 17#include <linux/io.h>
16#include <linux/spinlock.h> 18#include <linux/kernel.h>
17#include <linux/platform_device.h> 19#include <linux/module.h>
18#include <linux/gpio/driver.h>
19#include <linux/pinctrl/consumer.h> 20#include <linux/pinctrl/consumer.h>
21#include <linux/platform_device.h>
22#include <linux/spinlock.h>
23#include <linux/string.h>
20 24
21struct aspeed_bank_props { 25struct aspeed_bank_props {
22 unsigned int bank; 26 unsigned int bank;
@@ -29,59 +33,85 @@ struct aspeed_gpio_config {
29 const struct aspeed_bank_props *props; 33 const struct aspeed_bank_props *props;
30}; 34};
31 35
36/*
37 * @offset_timer: Maps an offset to an @timer_users index, or zero if disabled
38 * @timer_users: Tracks the number of users for each timer
39 *
40 * The @timer_users has four elements but the first element is unused. This is
41 * to simplify accounting and indexing, as a zero value in @offset_timer
42 * represents disabled debouncing for the GPIO. Any other value for an element
43 * of @offset_timer is used as an index into @timer_users. This behaviour of
44 * the zero value aligns with the behaviour of zero built from the timer
45 * configuration registers (i.e. debouncing is disabled).
46 */
32struct aspeed_gpio { 47struct aspeed_gpio {
33 struct gpio_chip chip; 48 struct gpio_chip chip;
34 spinlock_t lock; 49 spinlock_t lock;
35 void __iomem *base; 50 void __iomem *base;
36 int irq; 51 int irq;
37 const struct aspeed_gpio_config *config; 52 const struct aspeed_gpio_config *config;
53
54 u8 *offset_timer;
55 unsigned int timer_users[4];
56 struct clk *clk;
38}; 57};
39 58
40struct aspeed_gpio_bank { 59struct aspeed_gpio_bank {
41 uint16_t val_regs; 60 uint16_t val_regs;
42 uint16_t irq_regs; 61 uint16_t irq_regs;
62 uint16_t debounce_regs;
43 const char names[4][3]; 63 const char names[4][3];
44}; 64};
45 65
66static const int debounce_timers[4] = { 0x00, 0x50, 0x54, 0x58 };
67
46static const struct aspeed_gpio_bank aspeed_gpio_banks[] = { 68static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
47 { 69 {
48 .val_regs = 0x0000, 70 .val_regs = 0x0000,
49 .irq_regs = 0x0008, 71 .irq_regs = 0x0008,
72 .debounce_regs = 0x0040,
50 .names = { "A", "B", "C", "D" }, 73 .names = { "A", "B", "C", "D" },
51 }, 74 },
52 { 75 {
53 .val_regs = 0x0020, 76 .val_regs = 0x0020,
54 .irq_regs = 0x0028, 77 .irq_regs = 0x0028,
78 .debounce_regs = 0x0048,
55 .names = { "E", "F", "G", "H" }, 79 .names = { "E", "F", "G", "H" },
56 }, 80 },
57 { 81 {
58 .val_regs = 0x0070, 82 .val_regs = 0x0070,
59 .irq_regs = 0x0098, 83 .irq_regs = 0x0098,
84 .debounce_regs = 0x00b0,
60 .names = { "I", "J", "K", "L" }, 85 .names = { "I", "J", "K", "L" },
61 }, 86 },
62 { 87 {
63 .val_regs = 0x0078, 88 .val_regs = 0x0078,
64 .irq_regs = 0x00e8, 89 .irq_regs = 0x00e8,
90 .debounce_regs = 0x0100,
65 .names = { "M", "N", "O", "P" }, 91 .names = { "M", "N", "O", "P" },
66 }, 92 },
67 { 93 {
68 .val_regs = 0x0080, 94 .val_regs = 0x0080,
69 .irq_regs = 0x0118, 95 .irq_regs = 0x0118,
96 .debounce_regs = 0x0130,
70 .names = { "Q", "R", "S", "T" }, 97 .names = { "Q", "R", "S", "T" },
71 }, 98 },
72 { 99 {
73 .val_regs = 0x0088, 100 .val_regs = 0x0088,
74 .irq_regs = 0x0148, 101 .irq_regs = 0x0148,
102 .debounce_regs = 0x0160,
75 .names = { "U", "V", "W", "X" }, 103 .names = { "U", "V", "W", "X" },
76 }, 104 },
77 { 105 {
78 .val_regs = 0x01E0, 106 .val_regs = 0x01E0,
79 .irq_regs = 0x0178, 107 .irq_regs = 0x0178,
108 .debounce_regs = 0x0190,
80 .names = { "Y", "Z", "AA", "AB" }, 109 .names = { "Y", "Z", "AA", "AB" },
81 }, 110 },
82 { 111 {
83 .val_regs = 0x01E8, 112 .val_regs = 0x01E8,
84 .irq_regs = 0x01A8, 113 .irq_regs = 0x01A8,
114 .debounce_regs = 0x01c0,
85 .names = { "AC", "", "", "" }, 115 .names = { "AC", "", "", "" },
86 }, 116 },
87}; 117};
@@ -99,6 +129,13 @@ static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
99#define GPIO_IRQ_TYPE2 0x0c 129#define GPIO_IRQ_TYPE2 0x0c
100#define GPIO_IRQ_STATUS 0x10 130#define GPIO_IRQ_STATUS 0x10
101 131
132#define GPIO_DEBOUNCE_SEL1 0x00
133#define GPIO_DEBOUNCE_SEL2 0x04
134
135#define _GPIO_SET_DEBOUNCE(t, o, i) ((!!((t) & BIT(i))) << GPIO_OFFSET(o))
136#define GPIO_SET_DEBOUNCE1(t, o) _GPIO_SET_DEBOUNCE(t, o, 1)
137#define GPIO_SET_DEBOUNCE2(t, o) _GPIO_SET_DEBOUNCE(t, o, 0)
138
102static const struct aspeed_gpio_bank *to_bank(unsigned int offset) 139static const struct aspeed_gpio_bank *to_bank(unsigned int offset)
103{ 140{
104 unsigned int bank = GPIO_BANK(offset); 141 unsigned int bank = GPIO_BANK(offset);
@@ -144,6 +181,7 @@ static inline bool have_input(struct aspeed_gpio *gpio, unsigned int offset)
144} 181}
145 182
146#define have_irq(g, o) have_input((g), (o)) 183#define have_irq(g, o) have_input((g), (o))
184#define have_debounce(g, o) have_input((g), (o))
147 185
148static inline bool have_output(struct aspeed_gpio *gpio, unsigned int offset) 186static inline bool have_output(struct aspeed_gpio *gpio, unsigned int offset)
149{ 187{
@@ -506,6 +544,227 @@ static void aspeed_gpio_free(struct gpio_chip *chip, unsigned int offset)
506 pinctrl_free_gpio(chip->base + offset); 544 pinctrl_free_gpio(chip->base + offset);
507} 545}
508 546
547static inline void __iomem *bank_debounce_reg(struct aspeed_gpio *gpio,
548 const struct aspeed_gpio_bank *bank,
549 unsigned int reg)
550{
551 return gpio->base + bank->debounce_regs + reg;
552}
553
554static int usecs_to_cycles(struct aspeed_gpio *gpio, unsigned long usecs,
555 u32 *cycles)
556{
557 u64 rate;
558 u64 n;
559 u32 r;
560
561 rate = clk_get_rate(gpio->clk);
562 if (!rate)
563 return -ENOTSUPP;
564
565 n = rate * usecs;
566 r = do_div(n, 1000000);
567
568 if (n >= U32_MAX)
569 return -ERANGE;
570
571 /* At least as long as the requested time */
572 *cycles = n + (!!r);
573
574 return 0;
575}
576
577/* Call under gpio->lock */
578static int register_allocated_timer(struct aspeed_gpio *gpio,
579 unsigned int offset, unsigned int timer)
580{
581 if (WARN(gpio->offset_timer[offset] != 0,
582 "Offset %d already allocated timer %d\n",
583 offset, gpio->offset_timer[offset]))
584 return -EINVAL;
585
586 if (WARN(gpio->timer_users[timer] == UINT_MAX,
587 "Timer user count would overflow\n"))
588 return -EPERM;
589
590 gpio->offset_timer[offset] = timer;
591 gpio->timer_users[timer]++;
592
593 return 0;
594}
595
596/* Call under gpio->lock */
597static int unregister_allocated_timer(struct aspeed_gpio *gpio,
598 unsigned int offset)
599{
600 if (WARN(gpio->offset_timer[offset] == 0,
601 "No timer allocated to offset %d\n", offset))
602 return -EINVAL;
603
604 if (WARN(gpio->timer_users[gpio->offset_timer[offset]] == 0,
605 "No users recorded for timer %d\n",
606 gpio->offset_timer[offset]))
607 return -EINVAL;
608
609 gpio->timer_users[gpio->offset_timer[offset]]--;
610 gpio->offset_timer[offset] = 0;
611
612 return 0;
613}
614
615/* Call under gpio->lock */
616static inline bool timer_allocation_registered(struct aspeed_gpio *gpio,
617 unsigned int offset)
618{
619 return gpio->offset_timer[offset] > 0;
620}
621
622/* Call under gpio->lock */
623static void configure_timer(struct aspeed_gpio *gpio, unsigned int offset,
624 unsigned int timer)
625{
626 const struct aspeed_gpio_bank *bank = to_bank(offset);
627 const u32 mask = GPIO_BIT(offset);
628 void __iomem *addr;
629 u32 val;
630
631 addr = bank_debounce_reg(gpio, bank, GPIO_DEBOUNCE_SEL1);
632 val = ioread32(addr);
633 iowrite32((val & ~mask) | GPIO_SET_DEBOUNCE1(timer, offset), addr);
634
635 addr = bank_debounce_reg(gpio, bank, GPIO_DEBOUNCE_SEL2);
636 val = ioread32(addr);
637 iowrite32((val & ~mask) | GPIO_SET_DEBOUNCE2(timer, offset), addr);
638}
639
640static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
641 unsigned long usecs)
642{
643 struct aspeed_gpio *gpio = gpiochip_get_data(chip);
644 u32 requested_cycles;
645 unsigned long flags;
646 int rc;
647 int i;
648
649 rc = usecs_to_cycles(gpio, usecs, &requested_cycles);
650 if (rc < 0) {
651 dev_warn(chip->parent, "Failed to convert %luus to cycles at %luHz: %d\n",
652 usecs, clk_get_rate(gpio->clk), rc);
653 return rc;
654 }
655
656 spin_lock_irqsave(&gpio->lock, flags);
657
658 if (timer_allocation_registered(gpio, offset)) {
659 rc = unregister_allocated_timer(gpio, offset);
660 if (rc < 0)
661 goto out;
662 }
663
664 /* Try to find a timer already configured for the debounce period */
665 for (i = 1; i < ARRAY_SIZE(debounce_timers); i++) {
666 u32 cycles;
667
668 cycles = ioread32(gpio->base + debounce_timers[i]);
669 if (requested_cycles == cycles)
670 break;
671 }
672
673 if (i == ARRAY_SIZE(debounce_timers)) {
674 int j;
675
676 /*
677 * As there are no timers configured for the requested debounce
678 * period, find an unused timer instead
679 */
680 for (j = 1; j < ARRAY_SIZE(gpio->timer_users); j++) {
681 if (gpio->timer_users[j] == 0)
682 break;
683 }
684
685 if (j == ARRAY_SIZE(gpio->timer_users)) {
686 dev_warn(chip->parent,
687 "Debounce timers exhausted, cannot debounce for period %luus\n",
688 usecs);
689
690 rc = -EPERM;
691
692 /*
693 * We already adjusted the accounting to remove @offset
694 * as a user of its previous timer, so also configure
695 * the hardware so @offset has timers disabled for
696 * consistency.
697 */
698 configure_timer(gpio, offset, 0);
699 goto out;
700 }
701
702 i = j;
703
704 iowrite32(requested_cycles, gpio->base + debounce_timers[i]);
705 }
706
707 if (WARN(i == 0, "Cannot register index of disabled timer\n")) {
708 rc = -EINVAL;
709 goto out;
710 }
711
712 register_allocated_timer(gpio, offset, i);
713 configure_timer(gpio, offset, i);
714
715out:
716 spin_unlock_irqrestore(&gpio->lock, flags);
717
718 return rc;
719}
720
721static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
722{
723 struct aspeed_gpio *gpio = gpiochip_get_data(chip);
724 unsigned long flags;
725 int rc;
726
727 spin_lock_irqsave(&gpio->lock, flags);
728
729 rc = unregister_allocated_timer(gpio, offset);
730 if (!rc)
731 configure_timer(gpio, offset, 0);
732
733 spin_unlock_irqrestore(&gpio->lock, flags);
734
735 return rc;
736}
737
738static int set_debounce(struct gpio_chip *chip, unsigned int offset,
739 unsigned long usecs)
740{
741 struct aspeed_gpio *gpio = gpiochip_get_data(chip);
742
743 if (!have_debounce(gpio, offset))
744 return -ENOTSUPP;
745
746 if (usecs)
747 return enable_debounce(chip, offset, usecs);
748
749 return disable_debounce(chip, offset);
750}
751
752static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
753 unsigned long config)
754{
755 unsigned long param = pinconf_to_config_param(config);
756 u32 arg = pinconf_to_config_argument(config);
757
758 if (param == PIN_CONFIG_INPUT_DEBOUNCE)
759 return set_debounce(chip, offset, arg);
760 else if (param == PIN_CONFIG_BIAS_DISABLE ||
761 param == PIN_CONFIG_BIAS_PULL_DOWN ||
762 param == PIN_CONFIG_DRIVE_STRENGTH)
763 return pinctrl_gpio_set_config(offset, config);
764
765 return -ENOTSUPP;
766}
767
509/* 768/*
510 * Any banks not specified in a struct aspeed_bank_props array are assumed to 769 * Any banks not specified in a struct aspeed_bank_props array are assumed to
511 * have the properties: 770 * have the properties:
@@ -565,8 +824,16 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
565 if (!gpio_id) 824 if (!gpio_id)
566 return -EINVAL; 825 return -EINVAL;
567 826
827 gpio->clk = of_clk_get(pdev->dev.of_node, 0);
828 if (IS_ERR(gpio->clk)) {
829 dev_warn(&pdev->dev,
830 "No HPLL clock phandle provided, debouncing disabled\n");
831 gpio->clk = NULL;
832 }
833
568 gpio->config = gpio_id->data; 834 gpio->config = gpio_id->data;
569 835
836 gpio->chip.parent = &pdev->dev;
570 gpio->chip.ngpio = gpio->config->nr_gpios; 837 gpio->chip.ngpio = gpio->config->nr_gpios;
571 gpio->chip.parent = &pdev->dev; 838 gpio->chip.parent = &pdev->dev;
572 gpio->chip.direction_input = aspeed_gpio_dir_in; 839 gpio->chip.direction_input = aspeed_gpio_dir_in;
@@ -576,6 +843,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
576 gpio->chip.free = aspeed_gpio_free; 843 gpio->chip.free = aspeed_gpio_free;
577 gpio->chip.get = aspeed_gpio_get; 844 gpio->chip.get = aspeed_gpio_get;
578 gpio->chip.set = aspeed_gpio_set; 845 gpio->chip.set = aspeed_gpio_set;
846 gpio->chip.set_config = aspeed_gpio_set_config;
579 gpio->chip.label = dev_name(&pdev->dev); 847 gpio->chip.label = dev_name(&pdev->dev);
580 gpio->chip.base = -1; 848 gpio->chip.base = -1;
581 gpio->chip.irq_need_valid_mask = true; 849 gpio->chip.irq_need_valid_mask = true;
@@ -584,6 +852,9 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
584 if (rc < 0) 852 if (rc < 0)
585 return rc; 853 return rc;
586 854
855 gpio->offset_timer =
856 devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL);
857
587 return aspeed_gpio_setup_irqs(gpio, pdev); 858 return aspeed_gpio_setup_irqs(gpio, pdev);
588} 859}
589 860