示例#1
0
/**
 * pinctrl_generic_set_state_one() - set state for a certain pin/group
 * Apply all pin multiplexing and pin configurations specified by @config
 * for a given pin or pin group.
 *
 * @dev: pin controller device
 * @config: pseudo device pointing to config node
 * @is_group: target of operation (true: pin group, false: pin)
 * @selector: pin selector or group selector, depending on @is_group
 * @return: 0 on success, or negative error code on failure
 */
static int pinctrl_generic_set_state_one(struct udevice *dev,
					 struct udevice *config,
					 bool is_group, unsigned selector)
{
	const void *fdt = gd->fdt_blob;
	int node_offset = config->of_offset;
	const char *propname;
	const void *value;
	int prop_offset, len, func_selector, param, ret;
	u32 arg, default_val;

	for (prop_offset = fdt_first_property_offset(fdt, node_offset);
	     prop_offset > 0;
	     prop_offset = fdt_next_property_offset(fdt, prop_offset)) {
		value = fdt_getprop_by_offset(fdt, prop_offset,
					      &propname, &len);
		if (!value)
			return -EINVAL;

		if (!strcmp(propname, "function")) {
			func_selector = pinmux_func_name_to_selector(dev,
								     value);
			if (func_selector < 0)
				return func_selector;
			ret = pinmux_enable_setting(dev, is_group,
						    selector,
						    func_selector);
		} else {
			param = pinconf_prop_name_to_param(dev, propname,
							   &default_val);
			if (param < 0)
				continue; /* just skip unknown properties */

			if (len >= sizeof(fdt32_t))
				arg = fdt32_to_cpu(*(fdt32_t *)value);
			else
				arg = default_val;

			ret = pinconf_enable_setting(dev, is_group,
						     selector, param, arg);
		}

		if (ret)
			return ret;
	}

	return 0;
}
示例#2
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;
}