pinctrl: at91-pio4: add support for slew-rate

SAMA7G5 supports slew rate configuration. Adapt the driver for this.
For switching frequencies lower than 50MHz the slew rate needs to
be enabled. Since most of the pins on SAMA7G5 fall into this category
enabled the slew rate by default.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
diff --git a/arch/arm/mach-at91/include/mach/atmel_pio4.h b/arch/arm/mach-at91/include/mach/atmel_pio4.h
index 35ac7b2..c3bd914 100644
--- a/arch/arm/mach-at91/include/mach/atmel_pio4.h
+++ b/arch/arm/mach-at91/include/mach/atmel_pio4.h
@@ -44,6 +44,7 @@
 #define ATMEL_PIO_DIR_MASK		BIT(8)
 #define ATMEL_PIO_PUEN_MASK		BIT(9)
 #define ATMEL_PIO_PDEN_MASK		BIT(10)
+#define ATMEL_PIO_SR			BIT(11)
 #define ATMEL_PIO_IFEN_MASK		BIT(12)
 #define ATMEL_PIO_IFSCEN_MASK		BIT(13)
 #define ATMEL_PIO_OPD_MASK		BIT(14)
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
index b7ae2f6..26fb5d6 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -25,6 +25,7 @@
 
 struct atmel_pio4_plat {
 	struct atmel_pio4_port *reg_base;
+	unsigned int slew_rate_support;
 };
 
 static const struct pinconf_param conf_params[] = {
@@ -36,9 +37,11 @@
 	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
 	{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
 	{ "atmel,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0},
 };
 
-static u32 atmel_pinctrl_get_pinconf(struct udevice *config)
+static u32 atmel_pinctrl_get_pinconf(struct udevice *config,
+				     struct atmel_pio4_plat *plat)
 {
 	const struct pinconf_param *params;
 	u32 param, arg, conf = 0;
@@ -53,6 +56,10 @@
 		param = params->param;
 		arg = params->default_value;
 
+		/* Keep slew rate enabled by default. */
+		if (plat->slew_rate_support)
+			conf |= ATMEL_PIO_SR;
+
 		switch (param) {
 		case PIN_CONFIG_BIAS_DISABLE:
 			conf &= (~ATMEL_PIO_PUEN_MASK);
@@ -91,6 +98,15 @@
 			conf |= (val << ATMEL_PIO_DRVSTR_OFFSET)
 				& ATMEL_PIO_DRVSTR_MASK;
 			break;
+		case PIN_CONFIG_SLEW_RATE:
+			if (!plat->slew_rate_support)
+				break;
+
+			dev_read_u32(config, params->property, &val);
+			/* And disable it if requested. */
+			if (val == 0)
+				conf &= ~ATMEL_PIO_SR;
+			break;
 		default:
 			printf("%s: Unsupported configuration parameter: %u\n",
 			       __func__, param);
@@ -116,6 +132,7 @@
 
 static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 {
+	struct atmel_pio4_plat *plat = dev_get_plat(dev);
 	struct atmel_pio4_port *bank_base;
 	const void *blob = gd->fdt_blob;
 	int node = dev_of_offset(config);
@@ -124,7 +141,7 @@
 	u32 i, conf;
 	int count;
 
-	conf = atmel_pinctrl_get_pinconf(config);
+	conf = atmel_pinctrl_get_pinconf(config, plat);
 
 	count = fdtdec_get_int_array_count(blob, node, "pinmux",
 					   cells, ARRAY_SIZE(cells));
@@ -164,6 +181,7 @@
 static int atmel_pinctrl_probe(struct udevice *dev)
 {
 	struct atmel_pio4_plat *plat = dev_get_plat(dev);
+	ulong priv = dev_get_driver_data(dev);
 	fdt_addr_t addr_base;
 
 	dev = dev_get_parent(dev);
@@ -172,13 +190,15 @@
 		return -EINVAL;
 
 	plat->reg_base = (struct atmel_pio4_port *)addr_base;
+	plat->slew_rate_support = priv;
 
 	return 0;
 }
 
 static const struct udevice_id atmel_pinctrl_match[] = {
 	{ .compatible = "atmel,sama5d2-pinctrl" },
-	{ .compatible = "microchip,sama7g5-pinctrl" },
+	{ .compatible = "microchip,sama7g5-pinctrl",
+	  .data = (ulong)1, },
 	{}
 };