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)); } }
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); } }
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 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 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; }
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, ")"); } } }
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 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 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 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 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 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); }