aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-at91.c
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-09-26 02:57:45 -0400
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-11-18 17:35:55 -0500
commit7ebd7a3ae0dd6e826767df504f7850d935fc3ee9 (patch)
treefae32ddae5f6228afc1750a65d7a79729cf8dbc2 /drivers/pinctrl/pinctrl-at91.c
parent32b01a366eb5d7d480570fe05d1dc18170387f5f (diff)
pinctrl: at91 add deglitch, debounce, pull down and schmitt trigger mux option support
add : set_deglitch: enable/disable deglitch set_debounce: enable/disable debounce set_pulldown: enable/disable pulldown disable_schmitt_trig: disable schmitt trigger Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'drivers/pinctrl/pinctrl-at91.c')
-rw-r--r--drivers/pinctrl/pinctrl-at91.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 401fc96f577e..0d7e6c3c33a7 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -59,6 +59,12 @@ static int gpio_banks;
59 59
60#define PULL_UP (1 << 0) 60#define PULL_UP (1 << 0)
61#define MULTI_DRIVE (1 << 1) 61#define MULTI_DRIVE (1 << 1)
62#define DEGLITCH (1 << 2)
63#define PULL_DOWN (1 << 3)
64#define DIS_SCHMIT (1 << 4)
65#define DEBOUNCE (1 << 16)
66#define DEBOUNCE_VAL_SHIFT 17
67#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
62 68
63/** 69/**
64 * struct at91_pmx_func - describes AT91 pinmux functions 70 * struct at91_pmx_func - describes AT91 pinmux functions
@@ -122,6 +128,14 @@ struct at91_pin_group {
122 * @mux_B_periph: mux as periph B 128 * @mux_B_periph: mux as periph B
123 * @mux_C_periph: mux as periph C 129 * @mux_C_periph: mux as periph C
124 * @mux_D_periph: mux as periph D 130 * @mux_D_periph: mux as periph D
131 * @get_deglitch: get deglitch status
132 * @set_deglitch: enable/disable deglitch
133 * @get_debounce: get debounce status
134 * @set_debounce: enable/disable debounce
135 * @get_pulldown: get pulldown status
136 * @set_pulldown: enable/disable pulldown
137 * @get_schmitt_trig: get schmitt trigger status
138 * @disable_schmitt_trig: disable schmitt trigger
125 * @irq_type: return irq type 139 * @irq_type: return irq type
126 */ 140 */
127struct at91_pinctrl_mux_ops { 141struct at91_pinctrl_mux_ops {
@@ -130,6 +144,14 @@ struct at91_pinctrl_mux_ops {
130 void (*mux_B_periph)(void __iomem *pio, unsigned mask); 144 void (*mux_B_periph)(void __iomem *pio, unsigned mask);
131 void (*mux_C_periph)(void __iomem *pio, unsigned mask); 145 void (*mux_C_periph)(void __iomem *pio, unsigned mask);
132 void (*mux_D_periph)(void __iomem *pio, unsigned mask); 146 void (*mux_D_periph)(void __iomem *pio, unsigned mask);
147 bool (*get_deglitch)(void __iomem *pio, unsigned pin);
148 void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on);
149 bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
150 void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div);
151 bool (*get_pulldown)(void __iomem *pio, unsigned pin);
152 void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on);
153 bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
154 void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask);
133 /* irq */ 155 /* irq */
134 int (*irq_type)(struct irq_data *d, unsigned type); 156 int (*irq_type)(struct irq_data *d, unsigned type);
135}; 157};
@@ -386,10 +408,68 @@ static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask)
386 return select + 1; 408 return select + 1;
387} 409}
388 410
411static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin)
412{
413 return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1;
414}
415
416static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
417{
418 __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
419}
420
421static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
422{
423 if (is_on)
424 __raw_writel(mask, pio + PIO_IFSCDR);
425 at91_mux_set_deglitch(pio, mask, is_on);
426}
427
428static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div)
429{
430 *div = __raw_readl(pio + PIO_SCDR);
431
432 return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1;
433}
434
435static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
436 bool is_on, u32 div)
437{
438 if (is_on) {
439 __raw_writel(mask, pio + PIO_IFSCER);
440 __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
441 __raw_writel(mask, pio + PIO_IFER);
442 } else {
443 __raw_writel(mask, pio + PIO_IFDR);
444 }
445}
446
447static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
448{
449 return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1;
450}
451
452static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on)
453{
454 __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
455}
456
457static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask)
458{
459 __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
460}
461
462static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin)
463{
464 return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1;
465}
466
389static struct at91_pinctrl_mux_ops at91rm9200_ops = { 467static struct at91_pinctrl_mux_ops at91rm9200_ops = {
390 .get_periph = at91_mux_get_periph, 468 .get_periph = at91_mux_get_periph,
391 .mux_A_periph = at91_mux_set_A_periph, 469 .mux_A_periph = at91_mux_set_A_periph,
392 .mux_B_periph = at91_mux_set_B_periph, 470 .mux_B_periph = at91_mux_set_B_periph,
471 .get_deglitch = at91_mux_get_deglitch,
472 .set_deglitch = at91_mux_set_deglitch,
393 .irq_type = gpio_irq_type, 473 .irq_type = gpio_irq_type,
394}; 474};
395 475
@@ -399,6 +479,14 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
399 .mux_B_periph = at91_mux_pio3_set_B_periph, 479 .mux_B_periph = at91_mux_pio3_set_B_periph,
400 .mux_C_periph = at91_mux_pio3_set_C_periph, 480 .mux_C_periph = at91_mux_pio3_set_C_periph,
401 .mux_D_periph = at91_mux_pio3_set_D_periph, 481 .mux_D_periph = at91_mux_pio3_set_D_periph,
482 .get_deglitch = at91_mux_get_deglitch,
483 .set_deglitch = at91_mux_pio3_set_deglitch,
484 .get_debounce = at91_mux_pio3_get_debounce,
485 .set_debounce = at91_mux_pio3_set_debounce,
486 .get_pulldown = at91_mux_pio3_get_pulldown,
487 .set_pulldown = at91_mux_pio3_set_pulldown,
488 .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig,
489 .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
402 .irq_type = alt_gpio_irq_type, 490 .irq_type = alt_gpio_irq_type,
403}; 491};
404 492
@@ -624,6 +712,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
624 struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 712 struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
625 void __iomem *pio; 713 void __iomem *pio;
626 unsigned pin; 714 unsigned pin;
715 int div;
627 716
628 dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); 717 dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config);
629 pio = pin_to_controller(info, pin_to_bank(pin_id)); 718 pio = pin_to_controller(info, pin_to_bank(pin_id));
@@ -635,6 +724,15 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
635 if (at91_mux_get_pullup(pio, pin)) 724 if (at91_mux_get_pullup(pio, pin))
636 *config |= PULL_UP; 725 *config |= PULL_UP;
637 726
727 if (info->ops->get_deglitch && info->ops->get_deglitch(pio, pin))
728 *config |= DEGLITCH;
729 if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div))
730 *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT);
731 if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin))
732 *config |= PULL_DOWN;
733 if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin))
734 *config |= DIS_SCHMIT;
735
638 return 0; 736 return 0;
639} 737}
640 738
@@ -649,8 +747,21 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
649 pio = pin_to_controller(info, pin_to_bank(pin_id)); 747 pio = pin_to_controller(info, pin_to_bank(pin_id));
650 mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); 748 mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK);
651 749
750 if (config & PULL_UP && config & PULL_DOWN)
751 return -EINVAL;
752
652 at91_mux_set_pullup(pio, mask, config & PULL_UP); 753 at91_mux_set_pullup(pio, mask, config & PULL_UP);
653 at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); 754 at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
755 if (info->ops->set_deglitch)
756 info->ops->set_deglitch(pio, mask, config & DEGLITCH);
757 if (info->ops->set_debounce)
758 info->ops->set_debounce(pio, mask, config & DEBOUNCE,
759 (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT);
760 if (info->ops->set_pulldown)
761 info->ops->set_pulldown(pio, mask, config & PULL_DOWN);
762 if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT)
763 info->ops->disable_schmitt_trig(pio, mask);
764
654 return 0; 765 return 0;
655} 766}
656 767