[PATCH 01/11] pinctrl: scmi: send the drive strength in microamperes

From: Clément Le Goffic

Date: Fri Oct 30 2026 - 12:00:02 EST


SCMI gives the drive strength in microamperes, but
PIN_CONFIG_DRIVE_STRENGTH is in milliamperes and was sent unchanged.
Convert it on set and on get. It is the only unit that differs: the
debounce is in microseconds and the pull resistances in ohms on both
sides, and every other value is a flag or implementation defined.

Fixes: eb524cb651b7 ("pinctrl: Implementation of the generic scmi-pinctrl driver")
Signed-off-by: Clément Le Goffic <clegoffic@xxxxxxxxxxxx>
---
drivers/pinctrl/pinctrl-scmi.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c
index c93d61dfa282..6bc94c68e89a 100644
--- a/drivers/pinctrl/pinctrl-scmi.c
+++ b/drivers/pinctrl/pinctrl-scmi.c
@@ -14,6 +14,7 @@
#include <linux/scmi_protocol.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <linux/units.h>

#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
@@ -155,6 +156,15 @@ static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param,
return 0;
}

+static u32 pinctrl_scmi_map_pinconf_arg_get(enum pin_config_param param,
+ u32 value)
+{
+ if (param == PIN_CONFIG_DRIVE_STRENGTH)
+ return value / MILLI;
+
+ return value;
+}
+
static int pinctrl_scmi_map_pinconf_type_get(enum pin_config_param param,
enum scmi_pinctrl_conf_type *type)
{
@@ -167,13 +177,17 @@ static int pinctrl_scmi_map_pinconf_type_get(enum pin_config_param param,
}

static int pinctrl_scmi_map_pinconf_type_set(enum pin_config_param param,
- enum scmi_pinctrl_conf_type *type)
+ enum scmi_pinctrl_conf_type *type,
+ u32 *arg)
{
if (param == PIN_CONFIG_LEVEL) {
*type = SCMI_PIN_OUTPUT_VALUE;
return 0;
}

+ if (param == PIN_CONFIG_DRIVE_STRENGTH)
+ *arg *= MILLI;
+
return pinctrl_scmi_map_pinconf_type(param, type);
}

@@ -203,6 +217,7 @@ static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev,
if (ret)
return ret;

+ config_value = pinctrl_scmi_map_pinconf_arg_get(config_type, config_value);
*config = pinconf_to_config_packed(config_type, config_value);

return 0;
@@ -267,12 +282,13 @@ static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev,
param = pinconf_to_config_param(configs[i]);
if (param == PIN_CONFIG_PERSIST_STATE)
continue;
- ret = pinctrl_scmi_map_pinconf_type_set(param, &p_config_type[cnt]);
+ p_config_value[cnt] = pinconf_to_config_argument(configs[i]);
+ ret = pinctrl_scmi_map_pinconf_type_set(param, &p_config_type[cnt],
+ &p_config_value[cnt]);
if (ret) {
dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
goto free_config;
}
- p_config_value[cnt] = pinconf_to_config_argument(configs[i]);
cnt++;
}

@@ -310,13 +326,13 @@ static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev,

for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
- ret = pinctrl_scmi_map_pinconf_type_set(param, &p_config_type[i]);
+ p_config_value[i] = pinconf_to_config_argument(configs[i]);
+ ret = pinctrl_scmi_map_pinconf_type_set(param, &p_config_type[i],
+ &p_config_value[i]);
if (ret) {
dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
goto free_config;
}
-
- p_config_value[i] = pinconf_to_config_argument(configs[i]);
}

ret = pinctrl_ops->settings_conf(pmx->ph, group, GROUP_TYPE,
@@ -359,6 +375,7 @@ static int pinctrl_scmi_pinconf_group_get(struct pinctrl_dev *pctldev,
if (ret)
return ret;

+ config_value = pinctrl_scmi_map_pinconf_arg_get(config_type, config_value);
*config = pinconf_to_config_packed(config_type, config_value);

return 0;

--
2.56.0