Exemple #1
0
void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
				 struct seq_file *s, unsigned long config)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(conf_items); i++) {
		if (pinconf_to_config_param(config) != conf_items[i].param)
			continue;
		seq_printf(s, "%s: 0x%x", conf_items[i].display,
			   pinconf_to_config_argument(config));
	}

	if (!pctldev->desc->num_custom_params ||
	    !pctldev->desc->custom_conf_items)
		return;

	for (i = 0; i < pctldev->desc->num_custom_params; i++) {
		if (pinconf_to_config_param(config) !=
		    pctldev->desc->custom_conf_items[i].param)
			continue;
		seq_printf(s, "%s: 0x%x",
				pctldev->desc->custom_conf_items[i].display,
				pinconf_to_config_argument(config));
	}
}
Exemple #2
0
static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
			     unsigned long *config)
{
	struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
	struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
	unsigned int param = pinconf_to_config_param(*config);
	u32 mask = BIT(pin - bank->gpio_chip.base);
	int ret;
	u32 arg;

	switch (param) {
	case PIN_CONFIG_BIAS_PULL_UP:
		ret = regmap_read(pctl->regmap,
				  (bank->id ?
					PINMUX_PULLUP_CTRL1 :
					PINMUX_PULLUP_CTRL0),
				  &arg);
		if (ret)
			return ret;

		arg = !!(arg & mask);
		break;
	default:
		return -ENOTSUPP;
	}

	*config = pinconf_to_config_packed(param, arg);

	return 0;
}
Exemple #3
0
static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin,
			     unsigned long *config)
{
	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	u16 arg;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
	case PIN_CONFIG_BIAS_PULL_DOWN:
	case PIN_CONFIG_BIAS_PULL_UP:
		if (meson_pinconf_get_pull(pc, pin) == param)
			arg = 1;
		else
			return -EINVAL;
		break;
	default:
		return -ENOTSUPP;
	}

	*config = pinconf_to_config_packed(param, arg);
	dev_dbg(pc->dev, "pinconf for pin %u is %lu\n", pin, *config);

	return 0;
}
Exemple #4
0
static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
			    unsigned long *configs, unsigned int nconfigs)
{
	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
	unsigned int i;
	int ret;

	for (i = 0; i < nconfigs; i++) {
		switch (pinconf_to_config_param(configs[i])) {
		case PIN_CONFIG_BIAS_DISABLE:
		case PIN_CONFIG_BIAS_PULL_UP:
		case PIN_CONFIG_BIAS_PULL_DOWN:
		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		case PIN_CONFIG_SLEW_RATE:
			ret = mrfld_config_set_pin(mp, pin, configs[i]);
			if (ret)
				return ret;
			break;

		default:
			return -ENOTSUPP;
		}
	}

	return 0;
}
Exemple #5
0
static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
			unsigned int pin, unsigned long *config)
{
	struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
	unsigned int param = pinconf_to_config_param(*config);
	u32 val;
	u16 arg = 0;

	rtc->type->unlock(rtc);
	val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
	rtc->type->lock(rtc);

	switch (param) {
	case PIN_CONFIG_INPUT_ENABLE:
		if (!(val & OMAP_RTC_PMIC_EXT_WKUP_EN(pin)))
			return -EINVAL;
		break;
	case PIN_CONFIG_ACTIVE_HIGH:
		if (val & OMAP_RTC_PMIC_EXT_WKUP_POL(pin))
			return -EINVAL;
		break;
	default:
		return -ENOTSUPP;
	};

	*config = pinconf_to_config_packed(param, arg);

	return 0;
}
static int lpc18xx_pconf_get(struct pinctrl_dev *pctldev, unsigned pin,
			     unsigned long *config)
{
	struct lpc18xx_scu_data *scu = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	struct lpc18xx_pin_caps *pin_cap;
	int ret, arg = 0;
	u32 reg;

	pin_cap = lpc18xx_get_pin_caps(pin);
	if (!pin_cap)
		return -EINVAL;

	reg = readl(scu->base + pin_cap->offset);

	if (pin_cap->type == TYPE_I2C0)
		ret = lpc18xx_pconf_get_i2c0(param, &arg, reg, pin);
	else if (pin_cap->type == TYPE_USB1)
		ret = lpc18xx_pconf_get_usb1(param, &arg, reg);
	else
		ret = lpc18xx_pconf_get_pin(param, &arg, reg, pin_cap);

	if (ret < 0)
		return ret;

	*config = pinconf_to_config_packed(param, (u16)arg);

	return 0;
}
Exemple #7
0
static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
			      unsigned long config)
{
	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
	struct sh_pfc *pfc = pmx->pfc;
	enum pin_config_param param = pinconf_to_config_param(config);
	unsigned long flags;

	if (!sh_pfc_pinconf_validate(pfc, _pin, param))
		return -ENOTSUPP;

	switch (param) {
	case PIN_CONFIG_BIAS_PULL_UP:
	case PIN_CONFIG_BIAS_PULL_DOWN:
	case PIN_CONFIG_BIAS_DISABLE:
		if (!pfc->info->ops || !pfc->info->ops->set_bias)
			return -ENOTSUPP;

		spin_lock_irqsave(&pfc->lock, flags);
		pfc->info->ops->set_bias(pfc, _pin, param);
		spin_unlock_irqrestore(&pfc->lock, flags);

		break;

	default:
		return -ENOTSUPP;
	}

	return 0;
}
static int hi6402_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
				unsigned long *config)
{
	struct hi6402_pinctrl_device *pindev = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param;
	const struct hi6402_pinctrl_function *func;
	unsigned data, data1;
	int i, j, ret;

	ret = hi6402_get_function(pctldev, pin, &func);
	if (ret)
		return ret;

	for (i = 0; i < func->confs->nconfs; i++) {
		param = pinconf_to_config_param(*config);
		if (param == PIN_CONFIG_BIAS_DISABLE) {
			if (hi6402_pinconf_bias_disable(pctldev, pin)) {
				*config = 0;
				return 0;
			} else {
				return -ENOTSUPP;
			}
		} else if (param != func->confs->configs[i].val) {
			continue;
		}

		data = pindev->read(pindev, func->confs->reg) & func->confs->configs[i].mask;

		switch (func->confs->configs[i].param) {
		case PIN_CONFIG_BIAS_PULL_DOWN:
		case PIN_CONFIG_BIAS_PULL_UP:
		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
		case PIN_CONFIG_DRIVE_STRENGTH:
		case PIN_CONFIG_SLEW_RATE:
			*config = data;
			break;
		case PIN_CONFIG_INPUT_SCHMITT:
			for (j = 0; j < func->confs->nconfs; j++) {
				switch (func->confs->configs[j].param) {
				case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
					data1 = pindev->read(pindev, func->confs->reg) & func->confs->configs[j].mask;
					if (!data1)
						return -ENOTSUPP;
					break;
				default:
					break;
				}
			}
		default:
			*config = data;
			break;
		}
		return 0;
	}

	return -ENOTSUPP;
}
Exemple #9
0
static int zynq_pinconf_cfg_get(struct pinctrl_dev *pctldev,
				unsigned pin,
				unsigned long *config)
{
	u32 reg;
	int ret;
	unsigned int arg = 0;
	unsigned int param = pinconf_to_config_param(*config);
	struct zynq_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);

	if (pin >= ZYNQ_NUM_MIOS)
		return -ENOTSUPP;

	ret = regmap_read(pctrl->syscon, pctrl->pctrl_offset + (4 * pin), &reg);
	if (ret)
		return -EIO;

	switch (param) {
	case PIN_CONFIG_BIAS_PULL_UP:
		if (!(reg & ZYNQ_PINCONF_PULLUP))
			return -EINVAL;
		arg = 1;
		break;
	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
		if (!(reg & ZYNQ_PINCONF_TRISTATE))
			return -EINVAL;
		arg = 1;
		break;
	case PIN_CONFIG_BIAS_DISABLE:
		if (reg & ZYNQ_PINCONF_PULLUP || reg & ZYNQ_PINCONF_TRISTATE)
			return -EINVAL;
		break;
	case PIN_CONFIG_SLEW_RATE:
		arg = !!(reg & ZYNQ_PINCONF_SPEED);
		break;
	case PIN_CONFIG_LOW_POWER_MODE:
	{
		enum zynq_io_standards iostd = zynq_pinconf_iostd_get(reg);

		if (iostd != zynq_iostd_hstl)
			return -EINVAL;
		if (!(reg & ZYNQ_PINCONF_DISABLE_RECVR))
			return -EINVAL;
		arg = !!(reg & ZYNQ_PINCONF_DISABLE_RECVR);
		break;
	}
	case PIN_CONFIG_IOSTANDARD:
		arg = zynq_pinconf_iostd_get(reg);
		break;
	default:
		return -ENOTSUPP;
	}

	*config = pinconf_to_config_packed(param, arg);
	return 0;
}
Exemple #10
0
static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset,
			       unsigned long config)
{
	u32 debounce;

	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
		return -ENOTSUPP;

	debounce = pinconf_to_config_argument(config);
	return amd_gpio_set_debounce(gc, offset, debounce);
}
Exemple #11
0
static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
			    unsigned long *config)
{
	struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
	struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
	unsigned int param = pinconf_to_config_param(*config);
	unsigned int reg, arg;

	if (!pin)
		return -EINVAL;

	if (pin->type == GLOBAL_CTRL_PIN) {
		reg = (readl((void __iomem *)pin->reg) >>
			   pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
	} else {
Exemple #12
0
static int gb_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
			      unsigned long config)
{
	struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
	u32 debounce;

	if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
		return -ENOTSUPP;

	debounce = pinconf_to_config_argument(config);
	if (debounce > U16_MAX)
		return -EINVAL;

	return gb_gpio_set_debounce_operation(ggc, (u8)offset, (u16)debounce);
}
Exemple #13
0
static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
			   unsigned long *configs, unsigned num_configs)
{
	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param;
	u16 arg;
	u32 bank = WMT_BANK_FROM_PIN(pin);
	u32 bit = WMT_BIT_FROM_PIN(pin);
	u32 reg_pull_en = data->banks[bank].reg_pull_en;
	u32 reg_pull_cfg = data->banks[bank].reg_pull_cfg;
	int i;

	if ((reg_pull_en == NO_REG) || (reg_pull_cfg == NO_REG)) {
		dev_err(data->dev, "bias functions not supported on pin %d\n",
			pin);
		return -EINVAL;
	}

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

		if ((param == PIN_CONFIG_BIAS_PULL_DOWN) ||
		    (param == PIN_CONFIG_BIAS_PULL_UP)) {
			if (arg == 0)
				param = PIN_CONFIG_BIAS_DISABLE;
		}

		switch (param) {
		case PIN_CONFIG_BIAS_DISABLE:
			wmt_clearbits(data, reg_pull_en, BIT(bit));
			break;
		case PIN_CONFIG_BIAS_PULL_DOWN:
			wmt_clearbits(data, reg_pull_cfg, BIT(bit));
			wmt_setbits(data, reg_pull_en, BIT(bit));
			break;
		case PIN_CONFIG_BIAS_PULL_UP:
			wmt_setbits(data, reg_pull_cfg, BIT(bit));
			wmt_setbits(data, reg_pull_en, BIT(bit));
			break;
		default:
			dev_err(data->dev, "unknown pinconf param\n");
			return -EINVAL;
		}
	} /* for each config */

	return 0;
}
Exemple #14
0
static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
                               unsigned long *configs, unsigned num_configs)
{
    struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
    struct mtk_pinctrl_group *g = &pctl->groups[group];
    int i;

    for (i = 0; i < num_configs; i++) {
        mtk_pconf_parse_conf(pctldev, g->pin,
                             pinconf_to_config_param(configs[i]),
                             pinconf_to_config_argument(configs[i]));

        g->config = configs[i];
    }

    return 0;
}
Exemple #15
0
static int as3722_pinconf_set(struct pinctrl_dev *pctldev,
			unsigned pin, unsigned long *configs,
			unsigned num_configs)
{
	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param;
	int mode_prop;
	int i;

	for (i = 0; i < num_configs; i++) {
		param = pinconf_to_config_param(configs[i]);
		mode_prop = as_pci->gpio_control[pin].mode_prop;

		switch (param) {
		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
			break;

		case PIN_CONFIG_BIAS_DISABLE:
			mode_prop &= ~(AS3722_GPIO_MODE_PULL_UP |
					AS3722_GPIO_MODE_PULL_DOWN);
			break;
		case PIN_CONFIG_BIAS_PULL_UP:
			mode_prop |= AS3722_GPIO_MODE_PULL_UP;
			break;

		case PIN_CONFIG_BIAS_PULL_DOWN:
			mode_prop |= AS3722_GPIO_MODE_PULL_DOWN;
			break;

		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
			mode_prop |= AS3722_GPIO_MODE_HIGH_IMPED;
			break;

		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
			mode_prop |= AS3722_GPIO_MODE_OPEN_DRAIN;
			break;

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

		as_pci->gpio_control[pin].mode_prop = mode_prop;
	}
	return 0;
}
Exemple #16
0
static int rtc_pinconf_set(struct pinctrl_dev *pctldev,
			unsigned int pin, unsigned long *configs,
			unsigned int num_configs)
{
	struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
	u32 val;
	unsigned int param;
	u16 param_val;
	int i;

	rtc->type->unlock(rtc);
	val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
	rtc->type->lock(rtc);

	/* active low by default */
	val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin);

	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_INPUT_ENABLE:
			if (param_val)
				val |= OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
			else
				val &= ~OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
			break;
		case PIN_CONFIG_ACTIVE_HIGH:
			val &= ~OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
			break;
		default:
			dev_err(&rtc->rtc->dev, "Property %u not supported\n",
				param);
			return -ENOTSUPP;
		}
	}

	rtc->type->unlock(rtc);
	rtc_writel(rtc, OMAP_RTC_PMIC_REG, val);
	rtc->type->lock(rtc);

	return 0;
}
Exemple #17
0
static int as3722_pinconf_get(struct pinctrl_dev *pctldev,
			unsigned pin, unsigned long *config)
{
	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	int arg = 0;
	u16 prop;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		prop = AS3722_GPIO_MODE_PULL_UP |
				AS3722_GPIO_MODE_PULL_DOWN;
		if (!(as_pci->gpio_control[pin].mode_prop & prop))
			arg = 1;
		prop = 0;
		break;

	case PIN_CONFIG_BIAS_PULL_UP:
		prop = AS3722_GPIO_MODE_PULL_UP;
		break;

	case PIN_CONFIG_BIAS_PULL_DOWN:
		prop = AS3722_GPIO_MODE_PULL_DOWN;
		break;

	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		prop = AS3722_GPIO_MODE_OPEN_DRAIN;
		break;

	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
		prop = AS3722_GPIO_MODE_HIGH_IMPED;
		break;

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

	if (as_pci->gpio_control[pin].mode_prop & prop)
		arg = 1;

	*config = pinconf_to_config_packed(param, (u16)arg);
	return 0;
}
/* get the pin config settings for a specified pin */
static int hi6402_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
					unsigned long config)
{
	struct hi6402_pinctrl_device *pindev = pinctrl_dev_get_drvdata(pctldev);
	const struct hi6402_pinctrl_function *func;
	unsigned data;
	int i, ret;
	u16 arg;

	ret = hi6402_get_function(pctldev, pin, &func);
	if (ret)
		return ret;

	for (i = 0; i < func->confs->nconfs; i++) {
		if (pinconf_to_config_param(config) == func->confs->configs[i].param) {
			data = pindev->read(pindev, func->confs->reg);
			arg = pinconf_to_config_argument(config);
			switch (func->confs->configs[i].param) {
			case PIN_CONFIG_BIAS_DISABLE:
				hi6402_pinconf_clear_bias(pctldev, pin);
				break;
			case PIN_CONFIG_BIAS_PULL_DOWN:
			case PIN_CONFIG_BIAS_PULL_UP:
				if (arg)
					hi6402_pinconf_clear_bias(pctldev, pin);
			case PIN_CONFIG_INPUT_SCHMITT:
			case PIN_CONFIG_DRIVE_STRENGTH:
			case PIN_CONFIG_SLEW_RATE:
			case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
				data &= ~func->confs->configs[i].mask;
				if (arg)
					data |= arg;
				break;
			default:
				return -ENOTSUPP;
			}

			pindev->write(pindev, data, func->confs->reg);
			return 0;
		}
	}
	return -ENOTSUPP;
}
Exemple #19
0
static int wm831x_set_config(struct gpio_chip *chip, unsigned int offset,
			     unsigned long config)
{
	struct wm831x_gpio *wm831x_gpio = gpiochip_get_data(chip);
	struct wm831x *wm831x = wm831x_gpio->wm831x;
	int reg = WM831X_GPIO1_CONTROL + offset;

	switch (pinconf_to_config_param(config)) {
	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		return wm831x_set_bits(wm831x, reg,
				       WM831X_GPN_OD_MASK, WM831X_GPN_OD);
	case PIN_CONFIG_DRIVE_PUSH_PULL:
		return wm831x_set_bits(wm831x, reg,
				       WM831X_GPN_OD_MASK, 0);
	case PIN_CONFIG_INPUT_DEBOUNCE:
		return wm831x_gpio_set_debounce(wm831x, offset,
			pinconf_to_config_argument(config));
	default:
		break;
	}

	return -ENOTSUPP;
}
Exemple #20
0
static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
			     unsigned long *configs, unsigned int num_configs)
{
	struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
	struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin);
	unsigned int param;
	u32 arg;
	unsigned int i;
	u32 offset = pin - bank->gpio_chip.base;
	u32 mask = BIT(offset);

	dev_dbg(pctl->dev, "setting pin %d bank %d mask 0x%x\n",
		pin, bank->gpio_chip.base, mask);

	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_PULL_UP:
			dev_dbg(pctl->dev, "   pullup\n");
			regmap_write_bits(pctl->regmap,
					  (bank->id ?
						PINMUX_PULLUP_CTRL1 :
						PINMUX_PULLUP_CTRL0),
					  mask, mask);
			break;
		default:
			dev_err(pctl->dev, "Property %u not supported\n",
				param);
			return -ENOTSUPP;
		}
	}

	return 0;
}
Exemple #21
0
static int lpc18xx_pconf_set(struct pinctrl_dev *pctldev, unsigned pin,
			     unsigned long *configs, unsigned num_configs)
{
	struct lpc18xx_scu_data *scu = pinctrl_dev_get_drvdata(pctldev);
	struct lpc18xx_pin_caps *pin_cap;
	enum pin_config_param param;
	u16 param_val;
	u32 reg;
	int ret;
	int i;

	pin_cap = lpc18xx_get_pin_caps(pin);
	if (!pin_cap)
		return -EINVAL;

	reg = readl(scu->base + pin_cap->offset);

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

		if (pin_cap->type == TYPE_I2C0)
			ret = lpc18xx_pconf_set_i2c0(pctldev, param, param_val, &reg, pin);
		else if (pin_cap->type == TYPE_USB1)
			ret = lpc18xx_pconf_set_usb1(pctldev, param, param_val, &reg);
		else
			ret = lpc18xx_pconf_set_pin(pctldev, param, param_val, &reg, pin_cap);

		if (ret)
			return ret;
	}

	writel(reg, scu->base + pin_cap->offset);

	return 0;
}
Exemple #22
0
static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
			       unsigned long *configs, unsigned nconfs)
{
	struct pmic_mpp_state *state = pinctrl_dev_get_drvdata(pctldev);
	struct pmic_mpp_pad *pad;
	unsigned param, arg;
	unsigned int val;
	int i, ret;

	pad = pctldev->desc->pins[pin].drv_data;

	/* Make it possible to enable the pin, by not setting high impedance */
	pad->is_enabled = true;

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

		switch (param) {
		case PIN_CONFIG_BIAS_DISABLE:
			pad->pullup = PMIC_MPP_PULL_UP_OPEN;
			break;
		case PIN_CONFIG_BIAS_PULL_UP:
			switch (arg) {
			case 600:
				pad->pullup = PMIC_MPP_PULL_UP_0P6KOHM;
				break;
			case 10000:
				pad->pullup = PMIC_MPP_PULL_UP_10KOHM;
				break;
			case 30000:
				pad->pullup = PMIC_MPP_PULL_UP_30KOHM;
				break;
			default:
				return -EINVAL;
			}
			break;
		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
			pad->is_enabled = false;
			break;
		case PIN_CONFIG_POWER_SOURCE:
			if (arg >= pad->num_sources)
				return -EINVAL;
			pad->power_source = arg;
			break;
		case PIN_CONFIG_INPUT_ENABLE:
			pad->input_enabled = arg ? true : false;
			break;
		case PIN_CONFIG_OUTPUT:
			pad->output_enabled = true;
			pad->out_value = arg;
			break;
		case PMIC_MPP_CONF_DTEST_SELECTOR:
			pad->dtest = arg;
			break;
		case PIN_CONFIG_DRIVE_STRENGTH:
			arg = pad->drive_strength;
			break;
		case PMIC_MPP_CONF_AMUX_ROUTE:
			if (arg >= PMIC_MPP_AMUX_ROUTE_ABUS4)
				return -EINVAL;
			pad->amux_input = arg;
			break;
		case PMIC_MPP_CONF_ANALOG_LEVEL:
			pad->aout_level = arg;
			break;
		case PMIC_MPP_CONF_PAIRED:
			pad->paired = !!arg;
			break;
		default:
			return -EINVAL;
		}
	}

	val = pad->power_source << PMIC_MPP_REG_VIN_SHIFT;

	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_VIN_CTL, val);
	if (ret < 0)
		return ret;

	val = pad->pullup << PMIC_MPP_REG_PULL_SHIFT;

	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_PULL_CTL, val);
	if (ret < 0)
		return ret;

	val = pad->amux_input & PMIC_MPP_REG_AIN_ROUTE_MASK;

	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AIN_CTL, val);
	if (ret < 0)
		return ret;

	ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AOUT_CTL, pad->aout_level);
	if (ret < 0)
		return ret;

	ret = pmic_mpp_write_mode_ctl(state, pad);
	if (ret < 0)
		return ret;

	val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;

	return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
}
Exemple #23
0
static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
			    unsigned long *config)
{
	struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	u32 value, term;
	u16 arg = 0;

	if (!mrfld_buf_available(mp, pin))
		return -ENOTSUPP;

	value = readl(mrfld_get_bufcfg(mp, pin));
	term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		if (value & BUFCFG_Px_EN_MASK)
			return -EINVAL;
		break;

	case PIN_CONFIG_BIAS_PULL_UP:
		if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)
			return -EINVAL;

		switch (term) {
		case BUFCFG_PUPD_VAL_910:
			arg = 910;
			break;
		case BUFCFG_PUPD_VAL_2K:
			arg = 2000;
			break;
		case BUFCFG_PUPD_VAL_20K:
			arg = 20000;
			break;
		case BUFCFG_PUPD_VAL_50K:
			arg = 50000;
			break;
		}

		break;

	case PIN_CONFIG_BIAS_PULL_DOWN:
		if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)
			return -EINVAL;

		switch (term) {
		case BUFCFG_PUPD_VAL_910:
			arg = 910;
			break;
		case BUFCFG_PUPD_VAL_2K:
			arg = 2000;
			break;
		case BUFCFG_PUPD_VAL_20K:
			arg = 20000;
			break;
		case BUFCFG_PUPD_VAL_50K:
			arg = 50000;
			break;
		}

		break;

	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		if (!(value & BUFCFG_OD_EN))
			return -EINVAL;
		break;

	case PIN_CONFIG_SLEW_RATE:
		if (!(value & BUFCFG_SLEWSEL))
			arg = 0;
		else
			arg = 1;
		break;

	default:
		return -ENOTSUPP;
	}

	*config = pinconf_to_config_packed(param, arg);
	return 0;
}
Exemple #24
0
static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin,
				unsigned long config)
{
	unsigned int param = pinconf_to_config_param(config);
	unsigned int arg = pinconf_to_config_argument(config);
	u32 bits = 0, mask = 0;
	unsigned long flags;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
		break;

	case PIN_CONFIG_BIAS_PULL_UP:
		mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
		bits |= BUFCFG_PU_EN;

		switch (arg) {
		case 50000:
			bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
			break;
		case 20000:
			bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
			break;
		case 2000:
			bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
			break;
		default:
			return -EINVAL;
		}

		break;

	case PIN_CONFIG_BIAS_PULL_DOWN:
		mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
		bits |= BUFCFG_PD_EN;

		switch (arg) {
		case 50000:
			bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT;
			break;
		case 20000:
			bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT;
			break;
		case 2000:
			bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT;
			break;
		default:
			return -EINVAL;
		}

		break;

	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		mask |= BUFCFG_OD_EN;
		if (arg)
			bits |= BUFCFG_OD_EN;
		break;

	case PIN_CONFIG_SLEW_RATE:
		mask |= BUFCFG_SLEWSEL;
		if (arg)
			bits |= BUFCFG_SLEWSEL;
		break;
	}

	raw_spin_lock_irqsave(&mp->lock, flags);
	mrfld_update_bufcfg(mp, pin, bits, mask);
	raw_spin_unlock_irqrestore(&mp->lock, flags);

	return 0;
}
Exemple #25
0
static int zynq_pinconf_cfg_set(struct pinctrl_dev *pctldev,
				unsigned pin,
				unsigned long *configs,
				unsigned num_configs)
{
	int i, ret;
	u32 reg;
	u32 pullup = 0;
	u32 tristate = 0;
	struct zynq_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);

	if (pin >= ZYNQ_NUM_MIOS)
		return -ENOTSUPP;

	ret = regmap_read(pctrl->syscon, pctrl->pctrl_offset + (4 * pin), &reg);
	if (ret)
		return -EIO;

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

		switch (param) {
		case PIN_CONFIG_BIAS_PULL_UP:
			pullup = ZYNQ_PINCONF_PULLUP;
			break;
		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
			tristate = ZYNQ_PINCONF_TRISTATE;
			break;
		case PIN_CONFIG_BIAS_DISABLE:
			reg &= ~(ZYNQ_PINCONF_PULLUP | ZYNQ_PINCONF_TRISTATE);
			break;
		case PIN_CONFIG_SLEW_RATE:
			if (arg)
				reg |= ZYNQ_PINCONF_SPEED;
			else
				reg &= ~ZYNQ_PINCONF_SPEED;

			break;
		case PIN_CONFIG_IOSTANDARD:
			if (arg <= zynq_iostd_min || arg >= zynq_iostd_max) {
				dev_warn(pctldev->dev,
					 "unsupported IO standard '%u'\n",
					 param);
				break;
			}
			reg &= ~ZYNQ_PINCONF_IOTYPE_MASK;
			reg |= arg << ZYNQ_PINCONF_IOTYPE_SHIFT;
			break;
		case PIN_CONFIG_LOW_POWER_MODE:
			if (arg)
				reg |= ZYNQ_PINCONF_DISABLE_RECVR;
			else
				reg &= ~ZYNQ_PINCONF_DISABLE_RECVR;

			break;
		default:
			dev_warn(pctldev->dev,
				 "unsupported configuration parameter '%u'\n",
				 param);
			continue;
		}
	}

	if (tristate || pullup) {
		reg &= ~(ZYNQ_PINCONF_PULLUP | ZYNQ_PINCONF_TRISTATE);
		reg |= tristate | pullup;
	}

	ret = regmap_write(pctrl->syscon, pctrl->pctrl_offset + (4 * pin), reg);
	if (ret)
		return -EIO;

	return 0;
}
Exemple #26
0
static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin,
			     unsigned long *configs, unsigned num_configs)
{
	struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
	struct meson_bank *bank;
	enum pin_config_param param;
	unsigned int reg, bit;
	int i, ret;

	ret = meson_get_bank(pc, pin, &bank);
	if (ret)
		return ret;

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

		switch (param) {
		case PIN_CONFIG_BIAS_DISABLE:
			dev_dbg(pc->dev, "pin %u: disable bias\n", pin);

			meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
			ret = regmap_update_bits(pc->reg_pull, reg,
						 BIT(bit), 0);
			if (ret)
				return ret;
			break;
		case PIN_CONFIG_BIAS_PULL_UP:
			dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin);

			meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
					       &reg, &bit);
			ret = regmap_update_bits(pc->reg_pullen, reg,
						 BIT(bit), BIT(bit));
			if (ret)
				return ret;

			meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
			ret = regmap_update_bits(pc->reg_pull, reg,
						 BIT(bit), BIT(bit));
			if (ret)
				return ret;
			break;
		case PIN_CONFIG_BIAS_PULL_DOWN:
			dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin);

			meson_calc_reg_and_bit(bank, pin, REG_PULLEN,
					       &reg, &bit);
			ret = regmap_update_bits(pc->reg_pullen, reg,
						 BIT(bit), BIT(bit));
			if (ret)
				return ret;

			meson_calc_reg_and_bit(bank, pin, REG_PULL, &reg, &bit);
			ret = regmap_update_bits(pc->reg_pull, reg,
						 BIT(bit), 0);
			if (ret)
				return ret;
			break;
		default:
			return -ENOTSUPP;
		}
	}

	return 0;
}
Exemple #27
0
static int pmic_mpp_config_get(struct pinctrl_dev *pctldev,
			       unsigned int pin, unsigned long *config)
{
	unsigned param = pinconf_to_config_param(*config);
	struct pmic_mpp_pad *pad;
	unsigned arg = 0;

	pad = pctldev->desc->pins[pin].drv_data;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		arg = pad->pullup == PMIC_MPP_PULL_UP_OPEN;
		break;
	case PIN_CONFIG_BIAS_PULL_UP:
		switch (pad->pullup) {
		case PMIC_MPP_PULL_UP_OPEN:
			arg = 0;
			break;
		case PMIC_MPP_PULL_UP_0P6KOHM:
			arg = 600;
			break;
		case PMIC_MPP_PULL_UP_10KOHM:
			arg = 10000;
			break;
		case PMIC_MPP_PULL_UP_30KOHM:
			arg = 30000;
			break;
		default:
			return -EINVAL;
		}
		break;
	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
		arg = !pad->is_enabled;
		break;
	case PIN_CONFIG_POWER_SOURCE:
		arg = pad->power_source;
		break;
	case PIN_CONFIG_INPUT_ENABLE:
		arg = pad->input_enabled;
		break;
	case PIN_CONFIG_OUTPUT:
		arg = pad->out_value;
		break;
	case PMIC_MPP_CONF_DTEST_SELECTOR:
		arg = pad->dtest;
		break;
	case PMIC_MPP_CONF_AMUX_ROUTE:
		arg = pad->amux_input;
		break;
	case PMIC_MPP_CONF_PAIRED:
		arg = pad->paired;
		break;
	case PIN_CONFIG_DRIVE_STRENGTH:
		arg = pad->drive_strength;
		break;
	case PMIC_MPP_CONF_ANALOG_LEVEL:
		arg = pad->aout_level;
		break;
	default:
		return -EINVAL;
	}

	/* Convert register value to pinconf value */
	*config = pinconf_to_config_packed(param, arg);
	return 0;
}