in cirrus/pinctrl-madera-core.c [820:944]
static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned int num_configs)
{
struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
u16 conf[2] = {0, 0};
u16 mask[2] = {0, 0};
unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
unsigned int val;
int ret;
while (num_configs) {
dev_dbg(priv->dev, "%s config 0x%lx\n", __func__, *configs);
switch (pinconf_to_config_param(*configs)) {
case PIN_CONFIG_BIAS_BUS_HOLD:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] |= MADERA_GP1_PU | MADERA_GP1_PD;
break;
case PIN_CONFIG_BIAS_DISABLE:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] &= ~(MADERA_GP1_PU | MADERA_GP1_PD);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] |= MADERA_GP1_PD;
conf[1] &= ~MADERA_GP1_PU;
break;
case PIN_CONFIG_BIAS_PULL_UP:
mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
conf[1] |= MADERA_GP1_PU;
conf[1] &= ~MADERA_GP1_PD;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
mask[0] |= MADERA_GP1_OP_CFG_MASK;
conf[0] |= MADERA_GP1_OP_CFG;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
mask[0] |= MADERA_GP1_OP_CFG_MASK;
conf[0] &= ~MADERA_GP1_OP_CFG;
break;
case PIN_CONFIG_DRIVE_STRENGTH:
val = pinconf_to_config_argument(*configs);
mask[1] |= MADERA_GP1_DRV_STR_MASK;
conf[1] &= ~MADERA_GP1_DRV_STR_MASK;
conf[1] |= madera_pin_make_drv_str(priv, val);
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
mask[0] |= MADERA_GP1_DB_MASK;
/*
* we can't configure debounce time per-pin so value
* is just a flag
*/
val = pinconf_to_config_argument(*configs);
if (val)
conf[0] |= MADERA_GP1_DB;
else
conf[0] &= ~MADERA_GP1_DB;
break;
case PIN_CONFIG_INPUT_ENABLE:
val = pinconf_to_config_argument(*configs);
mask[1] |= MADERA_GP1_DIR_MASK;
if (val)
conf[1] |= MADERA_GP1_DIR;
else
conf[1] &= ~MADERA_GP1_DIR;
break;
case PIN_CONFIG_INPUT_SCHMITT:
val = pinconf_to_config_argument(*configs);
mask[0] |= MADERA_GP1_IP_CFG;
if (val)
conf[0] |= MADERA_GP1_IP_CFG;
else
conf[0] &= ~MADERA_GP1_IP_CFG;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] |= MADERA_GP1_DIR;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
mask[0] |= MADERA_GP1_IP_CFG;
conf[0] |= MADERA_GP1_IP_CFG;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] |= MADERA_GP1_DIR;
break;
case PIN_CONFIG_OUTPUT:
val = pinconf_to_config_argument(*configs);
mask[0] |= MADERA_GP1_LVL_MASK;
if (val)
conf[0] |= MADERA_GP1_LVL;
else
conf[0] &= ~MADERA_GP1_LVL;
mask[1] |= MADERA_GP1_DIR_MASK;
conf[1] &= ~MADERA_GP1_DIR;
break;
default:
return -ENOTSUPP;
}
++configs;
--num_configs;
}
dev_dbg(priv->dev,
"%s gpio%d 0x%x:0x%x 0x%x:0x%x\n",
__func__, pin + 1, reg, conf[0], reg + 1, conf[1]);
ret = regmap_update_bits(priv->madera->regmap, reg, mask[0], conf[0]);
if (ret)
goto err;
++reg;
ret = regmap_update_bits(priv->madera->regmap, reg, mask[1], conf[1]);
if (ret)
goto err;
return 0;
err:
dev_err(priv->dev,
"Failed to write GPIO%d conf (%d) reg 0x%x\n",
pin + 1, ret, reg);
return ret;
}