summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudiu Beznea <claudiu.beznea@microchip.com>2019-02-07 04:25:05 -0500
committerLinus Walleij <linus.walleij@linaro.org>2019-02-08 07:07:03 -0500
commit64e21add8cd9717f042b523f35ea831eab14261b (patch)
treecfdba1000f99c63a16068d7055bd5f40034015dd
parentfde84f194aaddc3988e5cdc0c7088e5cd9683061 (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.c48
-rw-r--r--drivers/pinctrl/pinctrl-at91.h1
-rw-r--r--include/dt-bindings/pinctrl/at91.h4
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
88enum 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
600static 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
588static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength) 610static 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
668static 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
646static struct at91_pinctrl_mux_ops at91rm9200_ops = { 686static 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