]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
pinctrl: at91: add slewrate support for SAM9X60
authorClaudiu Beznea <claudiu.beznea@microchip.com>
Thu, 7 Feb 2019 09:25:05 +0000 (09:25 +0000)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 8 Feb 2019 12:07:03 +0000 (13:07 +0100)
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>
drivers/pinctrl/pinctrl-at91.c
drivers/pinctrl/pinctrl-at91.h
include/dt-bindings/pinctrl/at91.h

index 128003597f431829bb619bfb1616fd041df4d845..cb7c432769a5ece3775c31c70d3f13a387313d7b 100644 (file)
@@ -59,6 +59,9 @@ static int gpio_banks;
 #define OUTPUT         (1 << 7)
 #define OUTPUT_VAL_SHIFT       8
 #define OUTPUT_VAL     (0x1 << OUTPUT_VAL_SHIFT)
+#define SLEWRATE_SHIFT 9
+#define SLEWRATE_MASK  0x1
+#define SLEWRATE       (SLEWRATE_MASK << SLEWRATE_SHIFT)
 #define DEBOUNCE       (1 << 16)
 #define DEBOUNCE_VAL_SHIFT     17
 #define DEBOUNCE_VAL   (0x3fff << DEBOUNCE_VAL_SHIFT)
@@ -82,6 +85,13 @@ enum drive_strength_bit {
 #define DRIVE_STRENGTH_BIT_MSK(name)   (DRIVE_STRENGTH_BIT_##name << \
                                         DRIVE_STRENGTH_SHIFT)
 
+enum slewrate_bit {
+       SLEWRATE_BIT_DIS,
+       SLEWRATE_BIT_ENA,
+};
+
+#define SLEWRATE_BIT_MSK(name)         (SLEWRATE_BIT_##name << SLEWRATE_SHIFT)
+
 /**
  * struct at91_pmx_func - describes AT91 pinmux functions
  * @name: the name of this specific function
@@ -171,6 +181,8 @@ struct at91_pinctrl_mux_ops {
        unsigned (*get_drivestrength)(void __iomem *pio, unsigned pin);
        void (*set_drivestrength)(void __iomem *pio, unsigned pin,
                                        u32 strength);
+       unsigned (*get_slewrate)(void __iomem *pio, unsigned pin);
+       void (*set_slewrate)(void __iomem *pio, unsigned pin, u32 slewrate);
        /* irq */
        int (*irq_type)(struct irq_data *d, unsigned type);
 };
@@ -585,6 +597,16 @@ static unsigned at91_mux_sam9x60_get_drivestrength(void __iomem *pio,
        return DRIVE_STRENGTH_BIT_LOW;
 }
 
+static unsigned at91_mux_sam9x60_get_slewrate(void __iomem *pio, unsigned pin)
+{
+       unsigned tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR);
+
+       if ((tmp & BIT(pin)))
+               return SLEWRATE_BIT_ENA;
+
+       return SLEWRATE_BIT_DIS;
+}
+
 static void set_drive_strength(void __iomem *reg, unsigned pin, u32 strength)
 {
        unsigned tmp = readl_relaxed(reg);
@@ -643,6 +665,24 @@ static void at91_mux_sam9x60_set_drivestrength(void __iomem *pio, unsigned pin,
        writel_relaxed(tmp, pio + SAM9X60_PIO_DRIVER1);
 }
 
+static void at91_mux_sam9x60_set_slewrate(void __iomem *pio, unsigned pin,
+                                         u32 setting)
+{
+       unsigned int tmp;
+
+       if (setting < SLEWRATE_BIT_DIS || setting > SLEWRATE_BIT_ENA)
+               return;
+
+       tmp = readl_relaxed(pio + SAM9X60_PIO_SLEWR);
+
+       if (setting == SLEWRATE_BIT_DIS)
+               tmp &= ~BIT(pin);
+       else
+               tmp |= BIT(pin);
+
+       writel_relaxed(tmp, pio + SAM9X60_PIO_SLEWR);
+}
+
 static struct at91_pinctrl_mux_ops at91rm9200_ops = {
        .get_periph     = at91_mux_get_periph,
        .mux_A_periph   = at91_mux_set_A_periph,
@@ -687,6 +727,8 @@ static const struct at91_pinctrl_mux_ops sam9x60_ops = {
        .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
        .get_drivestrength = at91_mux_sam9x60_get_drivestrength,
        .set_drivestrength = at91_mux_sam9x60_set_drivestrength,
+       .get_slewrate   = at91_mux_sam9x60_get_slewrate,
+       .set_slewrate   = at91_mux_sam9x60_set_slewrate,
        .irq_type       = alt_gpio_irq_type,
 
 };
@@ -950,6 +992,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
        if (info->ops->get_drivestrength)
                *config |= (info->ops->get_drivestrength(pio, pin)
                                << DRIVE_STRENGTH_SHIFT);
+       if (info->ops->get_slewrate)
+               *config |= (info->ops->get_slewrate(pio, pin) << SLEWRATE_SHIFT);
        if (at91_mux_get_output(pio, pin, &out))
                *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT);
 
@@ -1001,6 +1045,9 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
                        info->ops->set_drivestrength(pio, pin,
                                (config & DRIVE_STRENGTH)
                                        >> DRIVE_STRENGTH_SHIFT);
+               if (info->ops->set_slewrate)
+                       info->ops->set_slewrate(pio, pin,
+                               (config & SLEWRATE) >> SLEWRATE_SHIFT);
 
        } /* for each config */
 
@@ -1044,6 +1091,7 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
                             DRIVE_STRENGTH_MED);
        DBG_SHOW_FLAG_MASKED(DRIVE_STRENGTH, DRIVE_STRENGTH_BIT_MSK(HI),
                             DRIVE_STRENGTH_HI);
+       DBG_SHOW_FLAG(SLEWRATE);
        DBG_SHOW_FLAG(DEBOUNCE);
        if (config & DEBOUNCE) {
                val = config >> DEBOUNCE_VAL_SHIFT;
index 19fc27e66bfde40753b138e8362ae5ce57dce64d..223620f14b05ee31cee7f187e38c213b7c30a41d 100644 (file)
@@ -69,6 +69,7 @@
 #define AT91SAM9X5_PIO_DRIVER1 0x114  /*PIO Driver 1 register offset*/
 #define AT91SAM9X5_PIO_DRIVER2 0x118  /*PIO Driver 2 register offset*/
 
+#define SAM9X60_PIO_SLEWR      0x110   /* PIO Slew Rate Control Register */
 #define SAM9X60_PIO_DRIVER1    0x118   /* PIO Driver 1 register offset */
 
 #endif
index eb81867eac77eda6901aa1c7bdbdc0bc3a0313a2..8dc10e00c62729505f61e01f31a29dc61a2f8d29 100644 (file)
@@ -17,6 +17,7 @@
 #define AT91_PINCTRL_DIS_SCHMIT                (1 << 4)
 #define AT91_PINCTRL_OUTPUT            (1 << 7)
 #define AT91_PINCTRL_OUTPUT_VAL(x)     ((x & 0x1) << 8)
+#define AT91_PINCTRL_SLEWRATE          (1 << 9)
 #define AT91_PINCTRL_DEBOUNCE          (1 << 16)
 #define AT91_PINCTRL_DEBOUNCE_VAL(x)   (x << 17)
 
@@ -27,6 +28,9 @@
 #define AT91_PINCTRL_DRIVE_STRENGTH_MED                        (0x2 << 5)
 #define AT91_PINCTRL_DRIVE_STRENGTH_HI                 (0x3 << 5)
 
+#define AT91_PINCTRL_SLEWRATE_DIS      (0x0 << 9)
+#define AT91_PINCTRL_SLEWRATE_ENA      (0x1 << 9)
+
 #define AT91_PIOA      0
 #define AT91_PIOB      1
 #define AT91_PIOC      2