in mediatek/pinctrl-paris.c [77:188]
static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long *config)
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
int pullup, err, reg, ret = 1;
const struct mtk_pin_desc *desc;
if (pin >= hw->soc->npins) {
err = -EINVAL;
goto out;
}
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN:
if (hw->soc->bias_get_combo) {
err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
if (err)
goto out;
if (param == PIN_CONFIG_BIAS_DISABLE) {
if (ret == MTK_PUPD_SET_R1R0_00)
ret = MTK_DISABLE;
} else if (param == PIN_CONFIG_BIAS_PULL_UP) {
/* When desire to get pull-up value, return
* error if current setting is pull-down
*/
if (!pullup)
err = -EINVAL;
} else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
/* When desire to get pull-down value, return
* error if current setting is pull-up
*/
if (pullup)
err = -EINVAL;
}
} else {
err = -ENOTSUPP;
}
break;
case PIN_CONFIG_SLEW_RATE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
goto out;
/* CONFIG Current direction return value
* ------------- ----------------- ----------------------
* OUTPUT_ENABLE output 1 (= HW value)
* input 0 (= HW value)
* INPUT_ENABLE output 0 (= reverse HW value)
* input 1 (= reverse HW value)
*/
if (param == PIN_CONFIG_INPUT_ENABLE)
ret = !ret;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
goto out;
/* return error when in output mode
* because schmitt trigger only work in input mode
*/
if (ret) {
err = -EINVAL;
goto out;
}
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
if (hw->soc->drive_get)
err = hw->soc->drive_get(hw, desc, &ret);
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_get_value(hw, desc, reg, &ret);
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
if (hw->soc->adv_pull_get) {
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
} else
err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
if (hw->soc->adv_drive_get)
err = hw->soc->adv_drive_get(hw, desc, &ret);
else
err = -ENOTSUPP;
break;
default:
err = -ENOTSUPP;
}
out:
if (!err)
*config = pinconf_to_config_packed(param, ret);
return err;
}