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)); } }
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; }
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; }
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; }
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; }
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; }
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), ®); 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; }
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); }
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 {
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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, ®, pin); else if (pin_cap->type == TYPE_USB1) ret = lpc18xx_pconf_set_usb1(pctldev, param, param_val, ®); else ret = lpc18xx_pconf_set_pin(pctldev, param, param_val, ®, pin_cap); if (ret) return ret; } writel(reg, scu->base + pin_cap->offset); return 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); }
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; }
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; }
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), ®); 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; }
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, ®, &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, ®, &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, ®, &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, ®, &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, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), 0); if (ret) return ret; break; default: return -ENOTSUPP; } } return 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; }