in qcom/pinctrl-ssbi-gpio.c [313:434]
static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev,
unsigned int offset,
unsigned long *configs,
unsigned num_configs)
{
struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
unsigned param;
unsigned arg;
unsigned i;
u8 banks = 0;
u8 val;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
pin->bias = PM8XXX_GPIO_BIAS_NP;
banks |= BIT(2);
pin->disable = 0;
banks |= BIT(3);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
pin->bias = PM8XXX_GPIO_BIAS_PD;
banks |= BIT(2);
pin->disable = 0;
banks |= BIT(3);
break;
case PM8XXX_QCOM_PULL_UP_STRENGTH:
if (arg > PM8XXX_GPIO_BIAS_PU_1P5_30) {
dev_err(pctrl->dev, "invalid pull-up strength\n");
return -EINVAL;
}
pin->pull_up_strength = arg;
fallthrough;
case PIN_CONFIG_BIAS_PULL_UP:
pin->bias = pin->pull_up_strength;
banks |= BIT(2);
pin->disable = 0;
banks |= BIT(3);
break;
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
pin->disable = 1;
banks |= BIT(3);
break;
case PIN_CONFIG_INPUT_ENABLE:
pin->mode = PM8XXX_GPIO_MODE_INPUT;
banks |= BIT(0) | BIT(1);
break;
case PIN_CONFIG_OUTPUT:
pin->mode = PM8XXX_GPIO_MODE_OUTPUT;
pin->output_value = !!arg;
banks |= BIT(0) | BIT(1);
break;
case PIN_CONFIG_POWER_SOURCE:
pin->power_source = arg;
banks |= BIT(0);
break;
case PM8XXX_QCOM_DRIVE_STRENGH:
if (arg > PMIC_GPIO_STRENGTH_LOW) {
dev_err(pctrl->dev, "invalid drive strength\n");
return -EINVAL;
}
pin->output_strength = arg;
banks |= BIT(3);
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
pin->open_drain = 0;
banks |= BIT(1);
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
pin->open_drain = 1;
banks |= BIT(1);
break;
default:
dev_err(pctrl->dev,
"unsupported config parameter: %x\n",
param);
return -EINVAL;
}
}
if (banks & BIT(0)) {
val = pin->power_source << 1;
val |= PM8XXX_GPIO_MODE_ENABLED;
pm8xxx_write_bank(pctrl, pin, 0, val);
}
if (banks & BIT(1)) {
val = pin->mode << 2;
val |= pin->open_drain << 1;
val |= pin->output_value;
pm8xxx_write_bank(pctrl, pin, 1, val);
}
if (banks & BIT(2)) {
val = pin->bias << 1;
pm8xxx_write_bank(pctrl, pin, 2, val);
}
if (banks & BIT(3)) {
val = pin->output_strength << 2;
val |= pin->disable;
pm8xxx_write_bank(pctrl, pin, 3, val);
}
if (banks & BIT(4)) {
val = pin->function << 1;
pm8xxx_write_bank(pctrl, pin, 4, val);
}
if (banks & BIT(5)) {
val = 0;
if (!pin->inverted)
val |= BIT(3);
pm8xxx_write_bank(pctrl, pin, 5, val);
}
return 0;
}