diff options
author | Claudiu Beznea <claudiu.beznea@microchip.com> | 2019-02-07 04:25:05 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-02-08 07:07:03 -0500 |
commit | 64e21add8cd9717f042b523f35ea831eab14261b (patch) | |
tree | cfdba1000f99c63a16068d7055bd5f40034015dd | |
parent | fde84f194aaddc3988e5cdc0c7088e5cd9683061 (diff) |
pinctrl: at91: add slewrate support for SAM9X60
Add slew rate support for SAM9X60 pin controller.
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/pinctrl-at91.c | 48 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-at91.h | 1 | ||||
-rw-r--r-- | include/dt-bindings/pinctrl/at91.h | 4 |
3 files changed, 53 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 128003597f43..cb7c432769a5 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -59,6 +59,9 @@ static int gpio_banks; | |||
59 | #define OUTPUT (1 << 7) | 59 | #define OUTPUT (1 << 7) |
60 | #define OUTPUT_VAL_SHIFT 8 | 60 | #define OUTPUT_VAL_SHIFT 8 |
61 | #define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT) | 61 | #define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT) |
62 | #define SLEWRATE_SHIFT 9 | ||
63 | #define SLEWRATE_MASK 0x1 | ||
64 | #define SLEWRATE (SLEWRATE_MASK << SLEWRATE_SHIFT) | ||
62 | #define DEBOUNCE (1 << 16) | 65 | #define DEBOUNCE (1 << 16) |
63 | #define DEBOUNCE_VAL_SHIFT 17 | 66 | #define DEBOUNCE_VAL_SHIFT 17 |
64 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) | 67 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) |
@@ -82,6 +85,13 @@ enum drive_strength_bit { | |||
82 | #define DRIVE_STRENGTH_BIT_MSK(name) (DRIVE_STRENGTH_BIT_##name << \ | 85 | #define DRIVE_STRENGTH_BIT_MSK(name) (DRIVE_STRENGTH_BIT_##name << \ |
83 | DRIVE_STRENGTH_SHIFT) | 86 | DRIVE_STRENGTH_SHIFT) |
84 | 87 | ||
88 | enum slewrate_bit { | ||
89 | SLEWRATE_BIT_DIS, | ||
90 | SLEWRATE_BIT_ENA, | ||
91 | }; | ||
92 | |||
93 | #define SLEWRATE_BIT_MSK(name) (SLEWRATE_BIT_##name << SLEWRATE_SHIFT) | ||
94 | |||
85 | /** | 95 | /** |
86 | * struct at91_pmx_func - describes AT91 pinmux functions | 96 | * struct at91_pmx_func - describes AT91 pinmux functions |
87 | * @name: the name of this specific function | 97 | * @name: the name of this specific function |
@@ -171,6 +181,8 @@ struct at91_pinctrl_mux_ops { | |||
171 | unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin); | 181 | unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin); |
172 | void (*set_drivestrength)(void __iomem *pio, unsigned pin, | 182 | void (*set_drivestrength)(void __iomem *pio, unsigned pin, |
173 | u32 strength); | 183 | u32 strength); |
184 | unsigned (*get_slewrate)(void __iomem *pio, unsigned pin); | ||
185 | void (*set_slewrate)(void __iomem *pio, unsigned pin, u32 slewrate); | ||
174 | /* irq */ | 186 | /* irq */ |
175 | int (*irq_type)(struct irq_data *d, unsigned type); | 187 | int (*irq_type)(struct irq_data *d, unsigned type); |
176 | }; | 188 | }; |
@@ -585,6 +597,16 @@ static unsigned at91_mux_sam9x60_get_drivestrength(void __iomem *pio, | |||
585 | return DRIVE_STRENGTH_BIT_LOW; | 597 | return DRIVE_STRENGTH_BIT_LOW; |
586 | } | 598 | } |
587 | 599 | ||
600 | static unsigned at91_mux_sam9x60_get_slewrate(void __iomem *pio, unsigned pin) | ||
601 | { | ||
602 | unsigned tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR); | ||
603 | |||
604 | if ((tmp & BIT(pin))) | ||
605 | return SLEWRATE_BIT_ENA; | ||
606 | |||
607 | return SLEWRATE_BIT_DIS; | ||
608 | } | ||
609 | |||
588 | static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength) | 610 | static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength) |
589 | { | 611 | { |
590 | unsigned tmp = readl_relaxed(reg); | 612 | unsigned tmp = readl_relaxed(reg); |
@@ -643,6 +665,24 @@ static void at91_mux_sam9x60_set_drivestrength(void __iomem *pio, unsigned pin, | |||
643 | writel_relaxed(tmp, pio + SAM9X60_PIO_DRIVER1); | 665 | writel_relaxed(tmp, pio + SAM9X60_PIO_DRIVER1); |
644 | } | 666 | } |
645 | 667 | ||
668 | static void at91_mux_sam9x60_set_slewrate(void __iomem *pio, unsigned pin, | ||
669 | u32 setting) | ||
670 | { | ||
671 | unsigned int tmp; | ||
672 | |||
673 | if (setting < SLEWRATE_BIT_DIS || setting > SLEWRATE_BIT_ENA) | ||
674 | return; | ||
675 | |||
676 | tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR); | ||
677 | |||
678 | if (setting == SLEWRATE_BIT_DIS) | ||
679 | tmp &= ~BIT(pin); | ||
680 | else | ||
681 | tmp |= BIT(pin); | ||
682 | |||
683 | writel_relaxed(tmp, pio + SAM9X60_PIO_SLEWR); | ||
684 | } | ||
685 | |||
646 | static struct at91_pinctrl_mux_ops at91rm9200_ops = { | 686 | static struct at91_pinctrl_mux_ops at91rm9200_ops = { |
647 | .get_periph = at91_mux_get_periph, | 687 | .get_periph = at91_mux_get_periph, |
648 | .mux_A_periph = at91_mux_set_A_periph, | 688 | .mux_A_periph = at91_mux_set_A_periph, |
@@ -687,6 +727,8 @@ static const struct at91_pinctrl_mux_ops sam9x60_ops = { | |||
687 | .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, | 727 | .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, |
688 | .get_drivestrength = at91_mux_sam9x60_get_drivestrength, | 728 | .get_drivestrength = at91_mux_sam9x60_get_drivestrength, |
689 | .set_drivestrength = at91_mux_sam9x60_set_drivestrength, | 729 | .set_drivestrength = at91_mux_sam9x60_set_drivestrength, |
730 | .get_slewrate = at91_mux_sam9x60_get_slewrate, | ||
731 | .set_slewrate = at91_mux_sam9x60_set_slewrate, | ||
690 | .irq_type = alt_gpio_irq_type, | 732 | .irq_type = alt_gpio_irq_type, |
691 | 733 | ||
692 | }; | 734 | }; |
@@ -950,6 +992,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, | |||
950 | if (info->ops->get_drivestrength) | 992 | if (info->ops->get_drivestrength) |
951 | *config |= (info->ops->get_drivestrength(pio, pin) | 993 | *config |= (info->ops->get_drivestrength(pio, pin) |
952 | << DRIVE_STRENGTH_SHIFT); | 994 | << DRIVE_STRENGTH_SHIFT); |
995 | if (info->ops->get_slewrate) | ||
996 | *config |= (info->ops->get_slewrate(pio, pin) << SLEWRATE_SHIFT); | ||
953 | if (at91_mux_get_output(pio, pin, &out)) | 997 | if (at91_mux_get_output(pio, pin, &out)) |
954 | *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT); | 998 | *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT); |
955 | 999 | ||
@@ -1001,6 +1045,9 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, | |||
1001 | info->ops->set_drivestrength(pio, pin, | 1045 | info->ops->set_drivestrength(pio, pin, |
1002 | (config & DRIVE_STRENGTH) | 1046 | (config & DRIVE_STRENGTH) |
1003 | >> DRIVE_STRENGTH_SHIFT); | 1047 | >> DRIVE_STRENGTH_SHIFT); |
1048 | if (info->ops->set_slewrate) | ||
1049 | info->ops->set_slewrate(pio, pin, | ||
1050 | (config & SLEWRATE) >> SLEWRATE_SHIFT); | ||
1004 | 1051 | ||
1005 | } /* for each config */ | 1052 | } /* for each config */ |
1006 | 1053 | ||
@@ -1044,6 +1091,7 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, | |||
1044 | DRIVE_STRENGTH_MED); | 1091 | DRIVE_STRENGTH_MED); |
1045 | DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_BIT_MSK(HI), | 1092 | DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_BIT_MSK(HI), |
1046 | DRIVE_STRENGTH_HI); | 1093 | DRIVE_STRENGTH_HI); |
1094 | DBG_SHOW_FLAG(SLEWRATE); | ||
1047 | DBG_SHOW_FLAG(DEBOUNCE); | 1095 | DBG_SHOW_FLAG(DEBOUNCE); |
1048 | if (config & DEBOUNCE) { | 1096 | if (config & DEBOUNCE) { |
1049 | val = config >> DEBOUNCE_VAL_SHIFT; | 1097 | val = config >> DEBOUNCE_VAL_SHIFT; |
diff --git a/drivers/pinctrl/pinctrl-at91.h b/drivers/pinctrl/pinctrl-at91.h index 19fc27e66bfd..223620f14b05 100644 --- a/drivers/pinctrl/pinctrl-at91.h +++ b/drivers/pinctrl/pinctrl-at91.h | |||
@@ -69,6 +69,7 @@ | |||
69 | #define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/ | 69 | #define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/ |
70 | #define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/ | 70 | #define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/ |
71 | 71 | ||
72 | #define SAM9X60_PIO_SLEWR 0x110 /* PIO Slew Rate Control Register */ | ||
72 | #define SAM9X60_PIO_DRIVER1 0x118 /* PIO Driver 1 register offset */ | 73 | #define SAM9X60_PIO_DRIVER1 0x118 /* PIO Driver 1 register offset */ |
73 | 74 | ||
74 | #endif | 75 | #endif |
diff --git a/include/dt-bindings/pinctrl/at91.h b/include/dt-bindings/pinctrl/at91.h index eb81867eac77..8dc10e00c627 100644 --- a/include/dt-bindings/pinctrl/at91.h +++ b/include/dt-bindings/pinctrl/at91.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define AT91_PINCTRL_DIS_SCHMIT (1 << 4) | 17 | #define AT91_PINCTRL_DIS_SCHMIT (1 << 4) |
18 | #define AT91_PINCTRL_OUTPUT (1 << 7) | 18 | #define AT91_PINCTRL_OUTPUT (1 << 7) |
19 | #define AT91_PINCTRL_OUTPUT_VAL(x) ((x & 0x1) << 8) | 19 | #define AT91_PINCTRL_OUTPUT_VAL(x) ((x & 0x1) << 8) |
20 | #define AT91_PINCTRL_SLEWRATE (1 << 9) | ||
20 | #define AT91_PINCTRL_DEBOUNCE (1 << 16) | 21 | #define AT91_PINCTRL_DEBOUNCE (1 << 16) |
21 | #define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17) | 22 | #define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17) |
22 | 23 | ||
@@ -27,6 +28,9 @@ | |||
27 | #define AT91_PINCTRL_DRIVE_STRENGTH_MED (0x2 << 5) | 28 | #define AT91_PINCTRL_DRIVE_STRENGTH_MED (0x2 << 5) |
28 | #define AT91_PINCTRL_DRIVE_STRENGTH_HI (0x3 << 5) | 29 | #define AT91_PINCTRL_DRIVE_STRENGTH_HI (0x3 << 5) |
29 | 30 | ||
31 | #define AT91_PINCTRL_SLEWRATE_DIS (0x0 << 9) | ||
32 | #define AT91_PINCTRL_SLEWRATE_ENA (0x1 << 9) | ||
33 | |||
30 | #define AT91_PIOA 0 | 34 | #define AT91_PIOA 0 |
31 | #define AT91_PIOB 1 | 35 | #define AT91_PIOB 1 |
32 | #define AT91_PIOC 2 | 36 | #define AT91_PIOC 2 |