static int sh_pfc_pinctrl_group_set(struct udevice *dev, unsigned group_selector, unsigned func_selector) { struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); struct sh_pfc_pinctrl *pmx = &priv->pmx; struct sh_pfc *pfc = &priv->pfc; const struct sh_pfc_pin_group *grp = &priv->pfc.info->groups[group_selector]; unsigned int i; int ret = 0; for (i = 0; i < grp->nr_pins; ++i) { int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; if (cfg->type != PINMUX_TYPE_NONE) { ret = -EBUSY; goto done; } } for (i = 0; i < grp->nr_pins; ++i) { ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); if (ret < 0) break; } done: return ret; }
int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector) { struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); struct sh_pfc_pinctrl *pmx = &priv->pmx; struct sh_pfc *pfc = &priv->pfc; struct sh_pfc_pin_config *cfg; const struct sh_pfc_pin *pin = NULL; int i, idx; for (i = 1; i < pfc->info->nr_pins; i++) { if (priv->pfc.info->pins[i].pin != pin_selector) continue; pin = &priv->pfc.info->pins[i]; break; } if (!pin) return -EINVAL; idx = sh_pfc_get_pin_index(pfc, pin->pin); cfg = &pmx->configs[idx]; if (cfg->type != PINMUX_TYPE_NONE) return -EBUSY; return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO); }
static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset, bool input) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; int new_type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; int idx = sh_pfc_get_pin_index(pfc, offset); const struct sh_pfc_pin *pin = &pfc->info->pins[idx]; struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; unsigned long flags; unsigned int dir; int ret; /* Check if the requested direction is supported by the pin. Not all SoC * provide pin config data, so perform the check conditionally. */ if (pin->configs) { dir = input ? SH_PFC_PIN_CFG_INPUT : SH_PFC_PIN_CFG_OUTPUT; if (!(pin->configs & dir)) return -EINVAL; } spin_lock_irqsave(&pfc->lock, flags); ret = sh_pfc_config_mux(pfc, pin->enum_id, new_type); if (ret < 0) goto done; cfg->type = new_type; done: spin_unlock_irqrestore(&pfc->lock, flags); return ret; }
static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector, unsigned group) { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; const struct sh_pfc_pin_group *grp = &pfc->info->groups[group]; unsigned long flags; unsigned int i; int ret = 0; spin_lock_irqsave(&pfc->lock, flags); for (i = 0; i < grp->nr_pins; ++i) { int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; if (cfg->type != PINMUX_TYPE_NONE) { ret = -EBUSY; goto done; } } for (i = 0; i < grp->nr_pins; ++i) { ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); if (ret < 0) break; } done: spin_unlock_irqrestore(&pfc->lock, flags); return ret; }
static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector, unsigned func_selector) { struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev); struct sh_pfc_pinctrl *pmx = &priv->pmx; struct sh_pfc *pfc = &priv->pfc; const struct sh_pfc_pin *pin = &priv->pfc.info->pins[pin_selector]; int idx = sh_pfc_get_pin_index(pfc, pin->pin); struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; if (cfg->type != PINMUX_TYPE_NONE) return -EBUSY; return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_FUNCTION); }
static int gpio_function_request(struct gpio_chip *gc, unsigned offset) { static bool __print_once; struct sh_pfc *pfc = gpio_to_pfc(gc); unsigned int mark = pfc->info->func_gpios[offset].enum_id; unsigned long flags; int ret; if (!__print_once) { dev_notice(pfc->dev, "Use of GPIO API for function requests is deprecated." " Convert to pinctrl\n"); __print_once = true; } if (mark == 0) return -EINVAL; spin_lock_irqsave(&pfc->lock, flags); ret = sh_pfc_config_mux(pfc, mark, PINMUX_TYPE_FUNCTION); spin_unlock_irqrestore(&pfc->lock, flags); return ret; }