|
14 | 14 | * GNU General Public License for more details. |
15 | 15 | */ |
16 | 16 |
|
| 17 | +#include <dt-bindings/pinctrl/at91.h> |
17 | 18 | #include <linux/clk.h> |
18 | 19 | #include <linux/gpio/driver.h> |
19 | 20 | /* FIXME: needed for gpio_to_irq(), get rid of this */ |
|
49 | 50 | #define ATMEL_PIO_IFSCEN_MASK BIT(13) |
50 | 51 | #define ATMEL_PIO_OPD_MASK BIT(14) |
51 | 52 | #define ATMEL_PIO_SCHMITT_MASK BIT(15) |
| 53 | +#define ATMEL_PIO_DRVSTR_MASK GENMASK(17, 16) |
| 54 | +#define ATMEL_PIO_DRVSTR_OFFSET 16 |
52 | 55 | #define ATMEL_PIO_CFGR_EVTSEL_MASK GENMASK(26, 24) |
53 | 56 | #define ATMEL_PIO_CFGR_EVTSEL_FALLING (0 << 24) |
54 | 57 | #define ATMEL_PIO_CFGR_EVTSEL_RISING (1 << 24) |
|
75 | 78 | #define ATMEL_GET_PIN_FUNC(pinfunc) ((pinfunc >> 16) & 0xf) |
76 | 79 | #define ATMEL_GET_PIN_IOSET(pinfunc) ((pinfunc >> 20) & 0xf) |
77 | 80 |
|
| 81 | +/* Custom pinconf parameters */ |
| 82 | +#define ATMEL_PIN_CONFIG_DRIVE_STRENGTH (PIN_CONFIG_END + 1) |
| 83 | + |
78 | 84 | struct atmel_pioctrl_data { |
79 | 85 | unsigned nbanks; |
80 | 86 | }; |
@@ -139,6 +145,10 @@ static const char * const atmel_functions[] = { |
139 | 145 | "GPIO", "A", "B", "C", "D", "E", "F", "G" |
140 | 146 | }; |
141 | 147 |
|
| 148 | +static const struct pinconf_generic_params atmel_custom_bindings[] = { |
| 149 | + {"atmel,drive-strength", ATMEL_PIN_CONFIG_DRIVE_STRENGTH, 0}, |
| 150 | +}; |
| 151 | + |
142 | 152 | /* --- GPIO --- */ |
143 | 153 | static unsigned int atmel_gpio_read(struct atmel_pioctrl *atmel_pioctrl, |
144 | 154 | unsigned int bank, unsigned int reg) |
@@ -692,6 +702,11 @@ static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, |
692 | 702 | return -EINVAL; |
693 | 703 | arg = 1; |
694 | 704 | break; |
| 705 | + case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: |
| 706 | + if (!(res & ATMEL_PIO_DRVSTR_MASK)) |
| 707 | + return -EINVAL; |
| 708 | + arg = (res & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET; |
| 709 | + break; |
695 | 710 | default: |
696 | 711 | return -ENOTSUPP; |
697 | 712 | } |
@@ -777,6 +792,18 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, |
777 | 792 | ATMEL_PIO_SODR); |
778 | 793 | } |
779 | 794 | break; |
| 795 | + case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: |
| 796 | + switch (arg) { |
| 797 | + case ATMEL_PIO_DRVSTR_LO: |
| 798 | + case ATMEL_PIO_DRVSTR_ME: |
| 799 | + case ATMEL_PIO_DRVSTR_HI: |
| 800 | + conf &= (~ATMEL_PIO_DRVSTR_MASK); |
| 801 | + conf |= arg << ATMEL_PIO_DRVSTR_OFFSET; |
| 802 | + break; |
| 803 | + default: |
| 804 | + dev_warn(pctldev->dev, "drive strength not updated (incorrect value)\n"); |
| 805 | + } |
| 806 | + break; |
780 | 807 | default: |
781 | 808 | dev_warn(pctldev->dev, |
782 | 809 | "unsupported configuration parameter: %u\n", |
@@ -816,6 +843,19 @@ static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev, |
816 | 843 | seq_printf(s, "%s ", "open-drain"); |
817 | 844 | if (conf & ATMEL_PIO_SCHMITT_MASK) |
818 | 845 | seq_printf(s, "%s ", "schmitt"); |
| 846 | + if (conf & ATMEL_PIO_DRVSTR_MASK) { |
| 847 | + switch ((conf & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET) { |
| 848 | + case ATMEL_PIO_DRVSTR_ME: |
| 849 | + seq_printf(s, "%s ", "medium-drive"); |
| 850 | + break; |
| 851 | + case ATMEL_PIO_DRVSTR_HI: |
| 852 | + seq_printf(s, "%s ", "high-drive"); |
| 853 | + break; |
| 854 | + /* ATMEL_PIO_DRVSTR_LO and 0 which is the default value at reset */ |
| 855 | + default: |
| 856 | + seq_printf(s, "%s ", "low-drive"); |
| 857 | + } |
| 858 | + } |
819 | 859 | } |
820 | 860 |
|
821 | 861 | static const struct pinconf_ops atmel_confops = { |
@@ -956,6 +996,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) |
956 | 996 | return -ENOMEM; |
957 | 997 | atmel_pinctrl_desc.pins = pin_desc; |
958 | 998 | atmel_pinctrl_desc.npins = atmel_pioctrl->npins; |
| 999 | + atmel_pinctrl_desc.num_custom_params = ARRAY_SIZE(atmel_custom_bindings); |
| 1000 | + atmel_pinctrl_desc.custom_params = atmel_custom_bindings; |
959 | 1001 |
|
960 | 1002 | /* One pin is one group since a pin can achieve all functions. */ |
961 | 1003 | group_names = devm_kzalloc(dev, sizeof(*group_names) |
|
0 commit comments