in mediatek/pinctrl-paris.c [190:304]
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
enum pin_config_param param,
enum pin_config_param arg)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
const struct mtk_pin_desc *desc;
int err = 0;
u32 reg;
if (pin >= hw->soc->npins) {
err = -EINVAL;
goto err;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
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);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
if (hw->soc->bias_set_combo)
err = hw->soc->bias_set_combo(hw, desc, 1, arg);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
if (hw->soc->bias_set_combo)
err = hw->soc->bias_set_combo(hw, desc, 0, arg);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
MTK_DISABLE);
/* Keep set direction to consider the case that a GPIO pin
* does not have SMT control
*/
if (err != -ENOTSUPP)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
break;
case PIN_CONFIG_INPUT_ENABLE:
/* regard all non-zero value as enable */
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_INPUT);
break;
case PIN_CONFIG_SLEW_RATE:
/* regard all non-zero value as enable */
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
break;
case PIN_CONFIG_OUTPUT:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
arg);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
break;
case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
/* arg = 1: Input mode & SMT enable ;
* arg = 0: Output mode & SMT disable
*/
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
if (err)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_set)
err = hw->soc->drive_set(hw, desc, arg);
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);
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);
} else
err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
if (hw->soc->adv_drive_set)
err = hw->soc->adv_drive_set(hw, desc, arg);
else
err = -ENOTSUPP;
break;
default:
err = -ENOTSUPP;
}
err:
return err;
}