static int max77620_pinconf_set()

in pinctrl-max77620.c [394:537]


static int max77620_pinconf_set(struct pinctrl_dev *pctldev,
				unsigned int pin, unsigned long *configs,
				unsigned int num_configs)
{
	struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev);
	struct device *dev = mpci->dev;
	struct max77620_fps_config *fps_config;
	int param;
	u32 param_val;
	unsigned int val;
	unsigned int pu_val;
	unsigned int pd_val;
	int addr, ret;
	int i;

	for (i = 0; i < num_configs; i++) {
		param = pinconf_to_config_param(configs[i]);
		param_val = pinconf_to_config_argument(configs[i]);

		switch (param) {
		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
			val = param_val ? 0 : 1;
			ret = regmap_update_bits(mpci->rmap,
						 MAX77620_REG_GPIO0 + pin,
						 MAX77620_CNFG_GPIO_DRV_MASK,
						 val);
			if (ret)
				goto report_update_failure;

			mpci->pin_info[pin].drv_type = val ?
				MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
			break;

		case PIN_CONFIG_DRIVE_PUSH_PULL:
			val = param_val ? 1 : 0;
			ret = regmap_update_bits(mpci->rmap,
						 MAX77620_REG_GPIO0 + pin,
						 MAX77620_CNFG_GPIO_DRV_MASK,
						 val);
			if (ret)
				goto report_update_failure;

			mpci->pin_info[pin].drv_type = val ?
				MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV;
			break;

		case MAX77620_ACTIVE_FPS_SOURCE:
		case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
		case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
			if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
				return -EINVAL;

			fps_config = &mpci->fps_config[pin];

			if ((param == MAX77620_ACTIVE_FPS_SOURCE) &&
			    (param_val == MAX77620_FPS_SRC_DEF)) {
				addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
				ret = max77620_get_default_fps(
						mpci, addr,
						&fps_config->active_fps_src);
				if (ret < 0)
					return ret;
				break;
			}

			if (param == MAX77620_ACTIVE_FPS_SOURCE)
				fps_config->active_fps_src = param_val;
			else if (param == MAX77620_ACTIVE_FPS_POWER_ON_SLOTS)
				fps_config->active_power_up_slots = param_val;
			else
				fps_config->active_power_down_slots = param_val;

			ret = max77620_set_fps_param(mpci, pin, param);
			if (ret < 0)
				return ret;
			break;

		case MAX77620_SUSPEND_FPS_SOURCE:
		case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
		case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
			if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3))
				return -EINVAL;

			fps_config = &mpci->fps_config[pin];

			if ((param == MAX77620_SUSPEND_FPS_SOURCE) &&
			    (param_val == MAX77620_FPS_SRC_DEF)) {
				addr = MAX77620_REG_FPS_GPIO1 + pin - 1;
				ret = max77620_get_default_fps(
						mpci, addr,
						&fps_config->suspend_fps_src);
				if (ret < 0)
					return ret;
				break;
			}

			if (param == MAX77620_SUSPEND_FPS_SOURCE)
				fps_config->suspend_fps_src = param_val;
			else if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
				fps_config->suspend_power_up_slots = param_val;
			else
				fps_config->suspend_power_down_slots =
								param_val;
			break;

		case PIN_CONFIG_BIAS_PULL_UP:
		case PIN_CONFIG_BIAS_PULL_DOWN:
			pu_val = (param == PIN_CONFIG_BIAS_PULL_UP) ?
							BIT(pin) : 0;
			pd_val = (param == PIN_CONFIG_BIAS_PULL_DOWN) ?
							BIT(pin) : 0;

			ret = regmap_update_bits(mpci->rmap,
						 MAX77620_REG_PUE_GPIO,
						 BIT(pin), pu_val);
			if (ret < 0) {
				dev_err(dev, "PUE_GPIO update failed: %d\n",
					ret);
				return ret;
			}

			ret = regmap_update_bits(mpci->rmap,
						 MAX77620_REG_PDE_GPIO,
						 BIT(pin), pd_val);
			if (ret < 0) {
				dev_err(dev, "PDE_GPIO update failed: %d\n",
					ret);
				return ret;
			}
			break;

		default:
			dev_err(dev, "Properties not supported\n");
			return -ENOTSUPP;
		}
	}

	return 0;

report_update_failure:
	dev_err(dev, "Reg 0x%02x update failed %d\n",
		MAX77620_REG_GPIO0 + pin, ret);
	return ret;
}