int pin_config_group_get(const char *dev_name, const char *pin_group, unsigned long *config) { struct pinctrl_dev *pctldev; const struct pinconf_ops *ops; int selector; pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; if (!ops || !ops->pin_config_group_get) { dev_err(pctldev->dev, "cannot get configuration for pin " "group, missing group config get function in " "driver\n"); return -EINVAL; } selector = pinctrl_get_group_selector(pctldev, pin_group); if (selector < 0) return selector; return ops->pin_config_group_get(pctldev, selector, config); }
int pin_config_group_get(const char *dev_name, const char *pin_group, unsigned long *config) { struct pinctrl_dev *pctldev; const struct pinconf_ops *ops; int selector, ret; pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) { ret = -EINVAL; return ret; } mutex_lock(&pctldev->mutex); ops = pctldev->desc->confops; if (!ops || !ops->pin_config_group_get) { dev_dbg(pctldev->dev, "cannot get configuration for pin " "group, missing group config get function in " "driver\n"); ret = -ENOTSUPP; goto unlock; } selector = pinctrl_get_group_selector(pctldev, pin_group); if (selector < 0) { ret = selector; goto unlock; } ret = ops->pin_config_group_get(pctldev, selector, config); unlock: mutex_unlock(&pctldev->mutex); return ret; }
int pinconf_map_to_setting(struct pinctrl_map const *map, struct pinctrl_setting *setting) { struct pinctrl_dev *pctldev = setting->pctldev; int pin; switch (setting->type) { case PIN_MAP_TYPE_CONFIGS_PIN: pin = pin_get_from_name(pctldev, map->data.configs.group_or_pin); if (pin < 0) { dev_err(pctldev->dev, "could not map pin config for \"%s\"", map->data.configs.group_or_pin); return pin; } setting->data.configs.group_or_pin = pin; break; case PIN_MAP_TYPE_CONFIGS_GROUP: pin = pinctrl_get_group_selector(pctldev, map->data.configs.group_or_pin); if (pin < 0) { dev_err(pctldev->dev, "could not map group config for \"%s\"", map->data.configs.group_or_pin); return pin; } setting->data.configs.group_or_pin = pin; break; default: return -EINVAL; } setting->data.configs.num_configs = map->data.configs.num_configs; setting->data.configs.configs = map->data.configs.configs; return 0; }
int pinmux_map_to_setting(struct pinctrl_map const *map, struct pinctrl_setting *setting) { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *pmxops = pctldev->desc->pmxops; char const * const *groups; unsigned num_groups; int ret; const char *group; int i; if (!pmxops) { dev_err(pctldev->dev, "does not support mux function\n"); return -EINVAL; } ret = pinmux_func_name_to_selector(pctldev, map->data.mux.function); if (ret < 0) { dev_err(pctldev->dev, "invalid function %s in map table\n", map->data.mux.function); return ret; } setting->data.mux.func = ret; ret = pmxops->get_function_groups(pctldev, setting->data.mux.func, &groups, &num_groups); if (ret < 0) { dev_err(pctldev->dev, "can't query groups for function %s\n", map->data.mux.function); return ret; } if (!num_groups) { dev_err(pctldev->dev, "function %s can't be selected on any group\n", map->data.mux.function); return -EINVAL; } if (map->data.mux.group) { bool found = false; group = map->data.mux.group; for (i = 0; i < num_groups; i++) { if (!strcmp(group, groups[i])) { found = true; break; } } if (!found) { dev_err(pctldev->dev, "invalid group \"%s\" for function \"%s\"\n", group, map->data.mux.function); return -EINVAL; } } else { group = groups[0]; } ret = pinctrl_get_group_selector(pctldev, group); if (ret < 0) { dev_err(pctldev->dev, "invalid group %s in map table\n", map->data.mux.group); return ret; } setting->data.mux.group = ret; return 0; }
int pin_config_group_set(const char *dev_name, const char *pin_group, unsigned long config) { struct pinctrl_dev *pctldev; const struct pinconf_ops *ops; const struct pinctrl_ops *pctlops; int selector; const unsigned *pins; unsigned num_pins; int ret; int i; mutex_lock(&pinctrl_mutex); pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) { ret = -EINVAL; goto unlock; } ops = pctldev->desc->confops; pctlops = pctldev->desc->pctlops; if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { dev_err(pctldev->dev, "cannot configure pin group, missing " "config function in driver\n"); ret = -EINVAL; goto unlock; } selector = pinctrl_get_group_selector(pctldev, pin_group); if (selector < 0) { ret = selector; goto unlock; } ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); if (ret) { dev_err(pctldev->dev, "cannot configure pin group, error " "getting pins\n"); goto unlock; } /* * If the pin controller supports handling entire groups we use that * capability. */ if (ops->pin_config_group_set) { ret = ops->pin_config_group_set(pctldev, selector, config); /* * If the pin controller prefer that a certain group be handled * pin-by-pin as well, it returns -EAGAIN. */ if (ret != -EAGAIN) goto unlock; } /* * If the controller cannot handle entire groups, we configure each pin * individually. */ if (!ops->pin_config_set) { ret = 0; goto unlock; } for (i = 0; i < num_pins; i++) { ret = ops->pin_config_set(pctldev, pins[i], config); if (ret < 0) goto unlock; } ret = 0; unlock: mutex_unlock(&pinctrl_mutex); return ret; }