diff options
-rw-r--r-- | Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt | 2 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-at91.c | 21 | ||||
-rw-r--r-- | include/dt-bindings/pinctrl/at91.h | 2 |
3 files changed, 25 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt index b7a93e80a302..9a8a45d9d8ab 100644 --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt | |||
@@ -98,6 +98,8 @@ DRIVE_STRENGTH (3 << 5): indicate the drive strength of the pin using the | |||
98 | 01 - Low | 98 | 01 - Low |
99 | 10 - Medium | 99 | 10 - Medium |
100 | 11 - High | 100 | 11 - High |
101 | OUTPUT (1 << 7): indicate this pin need to be configured as an output. | ||
102 | OUTPUT_VAL (1 << 8): output val (1 = high, 0 = low) | ||
101 | DEBOUNCE (1 << 16): indicate this pin needs debounce. | 103 | DEBOUNCE (1 << 16): indicate this pin needs debounce. |
102 | DEBOUNCE_VAL (0x3fff << 17): debounce value. | 104 | DEBOUNCE_VAL (0x3fff << 17): debounce value. |
103 | 105 | ||
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 9f0904185909..569bc28cb909 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -56,6 +56,9 @@ static int gpio_banks; | |||
56 | #define DRIVE_STRENGTH_SHIFT 5 | 56 | #define DRIVE_STRENGTH_SHIFT 5 |
57 | #define DRIVE_STRENGTH_MASK 0x3 | 57 | #define DRIVE_STRENGTH_MASK 0x3 |
58 | #define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT) | 58 | #define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT) |
59 | #define OUTPUT (1 << 7) | ||
60 | #define OUTPUT_VAL_SHIFT 8 | ||
61 | #define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT) | ||
59 | #define DEBOUNCE (1 << 16) | 62 | #define DEBOUNCE (1 << 16) |
60 | #define DEBOUNCE_VAL_SHIFT 17 | 63 | #define DEBOUNCE_VAL_SHIFT 17 |
61 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) | 64 | #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) |
@@ -375,6 +378,19 @@ static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) | |||
375 | writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR)); | 378 | writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR)); |
376 | } | 379 | } |
377 | 380 | ||
381 | static bool at91_mux_get_output(void __iomem *pio, unsigned int pin, bool *val) | ||
382 | { | ||
383 | *val = (readl_relaxed(pio + PIO_ODSR) >> pin) & 0x1; | ||
384 | return (readl_relaxed(pio + PIO_OSR) >> pin) & 0x1; | ||
385 | } | ||
386 | |||
387 | static void at91_mux_set_output(void __iomem *pio, unsigned int mask, | ||
388 | bool is_on, bool val) | ||
389 | { | ||
390 | writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); | ||
391 | writel_relaxed(mask, pio + (is_on ? PIO_OER : PIO_ODR)); | ||
392 | } | ||
393 | |||
378 | static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) | 394 | static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) |
379 | { | 395 | { |
380 | return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1; | 396 | return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1; |
@@ -848,6 +864,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, | |||
848 | void __iomem *pio; | 864 | void __iomem *pio; |
849 | unsigned pin; | 865 | unsigned pin; |
850 | int div; | 866 | int div; |
867 | bool out; | ||
851 | 868 | ||
852 | *config = 0; | 869 | *config = 0; |
853 | dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id); | 870 | dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id); |
@@ -875,6 +892,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, | |||
875 | if (info->ops->get_drivestrength) | 892 | if (info->ops->get_drivestrength) |
876 | *config |= (info->ops->get_drivestrength(pio, pin) | 893 | *config |= (info->ops->get_drivestrength(pio, pin) |
877 | << DRIVE_STRENGTH_SHIFT); | 894 | << DRIVE_STRENGTH_SHIFT); |
895 | if (at91_mux_get_output(pio, pin, &out)) | ||
896 | *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT); | ||
878 | 897 | ||
879 | return 0; | 898 | return 0; |
880 | } | 899 | } |
@@ -907,6 +926,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, | |||
907 | if (config & PULL_UP && config & PULL_DOWN) | 926 | if (config & PULL_UP && config & PULL_DOWN) |
908 | return -EINVAL; | 927 | return -EINVAL; |
909 | 928 | ||
929 | at91_mux_set_output(pio, mask, config & OUTPUT, | ||
930 | (config & OUTPUT_VAL) >> OUTPUT_VAL_SHIFT); | ||
910 | at91_mux_set_pullup(pio, mask, config & PULL_UP); | 931 | at91_mux_set_pullup(pio, mask, config & PULL_UP); |
911 | at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); | 932 | at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); |
912 | if (info->ops->set_deglitch) | 933 | if (info->ops->set_deglitch) |
diff --git a/include/dt-bindings/pinctrl/at91.h b/include/dt-bindings/pinctrl/at91.h index bbca3d038900..2732d6c0fb39 100644 --- a/include/dt-bindings/pinctrl/at91.h +++ b/include/dt-bindings/pinctrl/at91.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #define AT91_PINCTRL_DEGLITCH (1 << 2) | 15 | #define AT91_PINCTRL_DEGLITCH (1 << 2) |
16 | #define AT91_PINCTRL_PULL_DOWN (1 << 3) | 16 | #define AT91_PINCTRL_PULL_DOWN (1 << 3) |
17 | #define AT91_PINCTRL_DIS_SCHMIT (1 << 4) | 17 | #define AT91_PINCTRL_DIS_SCHMIT (1 << 4) |
18 | #define AT91_PINCTRL_OUTPUT (1 << 7) | ||
19 | #define AT91_PINCTRL_OUTPUT_VAL(x) ((x & 0x1) << 8) | ||
18 | #define AT91_PINCTRL_DEBOUNCE (1 << 16) | 20 | #define AT91_PINCTRL_DEBOUNCE (1 << 16) |
19 | #define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17) | 21 | #define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17) |
20 | 22 | ||