示例#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));
	}
}
示例#2
0
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
			      struct seq_file *s, unsigned pin)
{
	const struct pinconf_ops *ops = pctldev->desc->confops;
	int i;

	if (!ops->is_generic)
		return;

	for(i = 0; i < ARRAY_SIZE(conf_items); i++) {
		unsigned long config;
		int ret;

		/* We want to check out this parameter */
		config = pinconf_to_config_packed(conf_items[i].param, 0);
		ret = pin_config_get_for_pin(pctldev, pin, &config);
		/* These are legal errors */
		if (ret == -EINVAL || ret == -ENOTSUPP)
			continue;
		if (ret) {
			seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
			continue;
		}
		/* Space between multiple configs */
		seq_puts(s, " ");
		seq_puts(s, conf_items[i].display);
		/* Print unit if available */
		if (conf_items[i].format &&
		    pinconf_to_config_argument(config) != 0)
			seq_printf(s, " (%u %s)",
				   pinconf_to_config_argument(config),
				   conf_items[i].format);
	}
}
示例#3
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);
}
示例#4
0
文件: gpio.c 项目: AshishNamdev/linux
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);
}
示例#5
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;
}
示例#6
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;
}
示例#7
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;
}
/* 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;
}
示例#9
0
static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
				     struct seq_file *s, const char *gname,
				     unsigned pin,
				     const struct pin_config_item *items,
				     int nitems, int *print_sep)
{
	int i;

	for (i = 0; i < nitems; i++) {
		unsigned long config;
		int ret;

		/* We want to check out this parameter */
		config = pinconf_to_config_packed(items[i].param, 0);
		if (gname)
			ret = pin_config_group_get(dev_name(pctldev->dev),
						   gname, &config);
		else
			ret = pin_config_get_for_pin(pctldev, pin, &config);
		/* These are legal errors */
		if (ret == -EINVAL || ret == -ENOTSUPP)
			continue;
		if (ret) {
			seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
			continue;
		}
		/* comma between multiple configs */
		if (*print_sep)
			seq_puts(s, ", ");
		*print_sep = 1;
		seq_puts(s, items[i].display);
		/* Print unit if available */
		if (items[i].has_arg) {
			seq_printf(s, " (%u",
				   pinconf_to_config_argument(config));
			if (items[i].format)
				seq_printf(s, " %s)", items[i].format);
			else
				seq_puts(s, ")");
		}
	}
}
示例#10
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;
}
示例#11
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;
}
示例#12
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;
}
示例#13
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;
}
示例#14
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;
}
示例#15
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);
}