On Sat, Oct 26, 2024 at 4:14 AM Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx> wrote: > > Currently the set_config callback in the gpio_chip registered by the > pinctrl_moore driver only supports configuring a single parameter on > specific pins (the input debounce of the EINT controller, on pins that > support it), even though many other configurations are already > implemented and available through the pinctrl API for configuration of > pins by the Devicetree and other drivers. > > Expose all configurations currently implemented through the GPIO API so > they can also be set from userspace, which is particularly useful to > allow testing them from userspace. > > Signed-off-by: Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx> Reviewed-by: Chen-Yu Tsai <wenst@xxxxxxxxxxxx> > --- > drivers/pinctrl/mediatek/pinctrl-moore.c | 283 ++++++++++++++++--------------- > 1 file changed, 144 insertions(+), 139 deletions(-) > > diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c > index aad4891223d3e060431a990bfabb6bd2cbb82087..de3494e9f228cef7f2eadf6a6ea2b3b708f1fb25 100644 > --- a/drivers/pinctrl/mediatek/pinctrl-moore.c > +++ b/drivers/pinctrl/mediatek/pinctrl-moore.c > @@ -246,156 +246,160 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev, > return 0; > } > > -static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, > - unsigned long *configs, unsigned int num_configs) > +static int mtk_moore_pin_config_set(struct mtk_pinctrl *hw, unsigned int pin, > + enum pin_config_param param, u32 arg) > { > - struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); > const struct mtk_pin_desc *desc; > - u32 reg, param, arg; > - int cfg, err = 0; > + u32 reg; > + int err = 0; > > desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; > if (!desc->name) > return -ENOTSUPP; > > - for (cfg = 0; cfg < num_configs; cfg++) { > - param = pinconf_to_config_param(configs[cfg]); > - arg = pinconf_to_config_argument(configs[cfg]); > - > - switch (param) { > - case PIN_CONFIG_BIAS_DISABLE: > - if (hw->soc->bias_set_combo) { > - err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); > - if (err) > - return err; > - } else if (hw->soc->bias_disable_set) { > - err = hw->soc->bias_disable_set(hw, desc); > - if (err) > - return err; > - } else { > - return -ENOTSUPP; > - } > - break; > - case PIN_CONFIG_BIAS_PULL_UP: > - if (hw->soc->bias_set_combo) { > - err = hw->soc->bias_set_combo(hw, desc, 1, arg); > - if (err) > - return err; > - } else if (hw->soc->bias_set) { > - err = hw->soc->bias_set(hw, desc, 1); > - if (err) > - return err; > - } else { > - return -ENOTSUPP; > - } > - break; > - case PIN_CONFIG_BIAS_PULL_DOWN: > - if (hw->soc->bias_set_combo) { > - err = hw->soc->bias_set_combo(hw, desc, 0, arg); > - if (err) > - return err; > - } else if (hw->soc->bias_set) { > - err = hw->soc->bias_set(hw, desc, 0); > - if (err) > - return err; > - } else { > - return -ENOTSUPP; > - } > - break; > - case PIN_CONFIG_OUTPUT_ENABLE: > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, > - MTK_DISABLE); > - if (err) > - goto err; > - > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, > - MTK_OUTPUT); > + switch ((u32)param) { > + case PIN_CONFIG_BIAS_DISABLE: > + if (hw->soc->bias_set_combo) { > + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); > if (err) > - goto err; > - break; > - case PIN_CONFIG_INPUT_ENABLE: > - > - if (hw->soc->ies_present) { > - mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, > - MTK_ENABLE); > - } > - > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, > - MTK_INPUT); > + return err; > + } else if (hw->soc->bias_disable_set) { > + err = hw->soc->bias_disable_set(hw, desc); > if (err) > - goto err; > - break; > - case PIN_CONFIG_SLEW_RATE: > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, > - arg); > + return err; > + } else { > + return -ENOTSUPP; > + } > + break; > + case PIN_CONFIG_BIAS_PULL_UP: > + if (hw->soc->bias_set_combo) { > + err = hw->soc->bias_set_combo(hw, desc, 1, arg); > if (err) > - goto err; > - > - break; > - case PIN_CONFIG_OUTPUT: > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, > - MTK_OUTPUT); > + return err; > + } else if (hw->soc->bias_set) { > + err = hw->soc->bias_set(hw, desc, 1); > if (err) > - goto err; > - > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, > - arg); > + return err; > + } else { > + return -ENOTSUPP; > + } > + break; > + case PIN_CONFIG_BIAS_PULL_DOWN: > + if (hw->soc->bias_set_combo) { > + err = hw->soc->bias_set_combo(hw, desc, 0, arg); > if (err) > - goto err; > - break; > - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: > - /* arg = 1: Input mode & SMT enable ; > - * arg = 0: Output mode & SMT disable > - */ > - arg = arg ? 2 : 1; > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, > - arg & 1); > + return err; > + } else if (hw->soc->bias_set) { > + err = hw->soc->bias_set(hw, desc, 0); > if (err) > - goto err; > + return err; > + } else { > + return -ENOTSUPP; > + } > + break; > + case PIN_CONFIG_OUTPUT_ENABLE: > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, MTK_DISABLE); > + if (err) > + return err; > + > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); > + if (err) > + return err; > + break; > + case PIN_CONFIG_INPUT_ENABLE: > + > + if (hw->soc->ies_present) { > + mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, MTK_ENABLE); > + } > + > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_INPUT); > + if (err) > + return err; > + break; > + case PIN_CONFIG_SLEW_RATE: > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, arg); > + if (err) > + return err; > + > + break; > + case PIN_CONFIG_OUTPUT: > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); > + if (err) > + return err; > + > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, arg); > + if (err) > + return err; > + break; > + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: > + /* arg = 1: Input mode & SMT enable ; > + * arg = 0: Output mode & SMT disable > + */ > + arg = arg ? 2 : 1; > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, arg & 1); > + if (err) > + return err; > > - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, > - !!(arg & 2)); > + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!(arg & 2)); > + if (err) > + return err; > + break; > + case PIN_CONFIG_DRIVE_STRENGTH: > + if (hw->soc->drive_set) { > + err = hw->soc->drive_set(hw, desc, arg); > if (err) > - goto err; > - break; > - case PIN_CONFIG_DRIVE_STRENGTH: > - if (hw->soc->drive_set) { > - err = hw->soc->drive_set(hw, desc, arg); > - if (err) > - return err; > - } else { > - err = -ENOTSUPP; > - } > - break; > - case MTK_PIN_CONFIG_TDSEL: > - case MTK_PIN_CONFIG_RDSEL: > - reg = (param == MTK_PIN_CONFIG_TDSEL) ? > - PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; > - > - err = mtk_hw_set_value(hw, desc, reg, arg); > + return err; > + } else { > + return -ENOTSUPP; > + } > + break; > + case MTK_PIN_CONFIG_TDSEL: > + case MTK_PIN_CONFIG_RDSEL: > + reg = (param == MTK_PIN_CONFIG_TDSEL) ? > + PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; > + > + err = mtk_hw_set_value(hw, desc, reg, arg); > + if (err) > + return err; > + break; > + case MTK_PIN_CONFIG_PU_ADV: > + case MTK_PIN_CONFIG_PD_ADV: > + if (hw->soc->adv_pull_set) { > + bool pullup; > + > + pullup = param == MTK_PIN_CONFIG_PU_ADV; > + err = hw->soc->adv_pull_set(hw, desc, pullup, arg); > if (err) > - goto err; > - break; > - case MTK_PIN_CONFIG_PU_ADV: > - case MTK_PIN_CONFIG_PD_ADV: > - if (hw->soc->adv_pull_set) { > - bool pullup; > - > - pullup = param == MTK_PIN_CONFIG_PU_ADV; > - err = hw->soc->adv_pull_set(hw, desc, pullup, > - arg); > - if (err) > - return err; > - } else { > - return -ENOTSUPP; > - } > - break; > - default: > - err = -ENOTSUPP; > + return err; > + } else { > + return -ENOTSUPP; > } > + break; > + default: > + return -ENOTSUPP; > + } > + > + return 0; > +} > + > +static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, > + unsigned long *configs, unsigned int num_configs) > +{ > + struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); > + enum pin_config_param param; > + int cfg, err = 0; > + u32 arg; > + > + for (cfg = 0; cfg < num_configs; cfg++) { > + param = pinconf_to_config_param(configs[cfg]); > + arg = pinconf_to_config_argument(configs[cfg]); > + > + err = mtk_moore_pin_config_set(hw, pin, param, arg); > + if (err) > + return err; > } > -err: > - return err; > + > + return 0; > } > > static int mtk_pinconf_group_get(struct pinctrl_dev *pctldev, > @@ -539,20 +543,21 @@ static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset, > { > struct mtk_pinctrl *hw = gpiochip_get_data(chip); > const struct mtk_pin_desc *desc; > - u32 debounce; > + enum pin_config_param param = pinconf_to_config_param(config); > + u32 arg = pinconf_to_config_argument(config); > > desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset]; > if (!desc->name) > return -ENOTSUPP; > > - if (!hw->eint || > - pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE || > - desc->eint.eint_n == (u16)EINT_NA) > - return -ENOTSUPP; > + if (param == PIN_CONFIG_INPUT_DEBOUNCE) { > + if (!hw->eint || desc->eint.eint_n == (u16)EINT_NA) > + return -ENOTSUPP; > > - debounce = pinconf_to_config_argument(config); > + return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, arg); > + } > > - return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, debounce); > + return mtk_moore_pin_config_set(hw, offset, param, arg); > } > > static int mtk_build_gpiochip(struct mtk_pinctrl *hw) > > -- > 2.47.0 > >