/**
 * pinctrl_select_state_full() - full implementation of pinctrl_select_state
 *
 * @dev: peripheral device
 * @statename: state name, like "default"
 * @return: 0 on success, or negative error code on failure
 */
static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
{
	const void *fdt = gd->fdt_blob;
	int node = dev->of_offset;
	char propname[32]; /* long enough */
	const fdt32_t *list;
	uint32_t phandle;
	int config_node;
	struct udevice *config;
	int state, size, i, ret;

	state = fdt_find_string(fdt, node, "pinctrl-names", statename);
	if (state < 0) {
		char *end;
		/*
		 * If statename is not found in "pinctrl-names",
		 * assume statename is just the integer state ID.
		 */
		state = simple_strtoul(statename, &end, 10);
		if (*end)
			return -EINVAL;
	}

	snprintf(propname, sizeof(propname), "pinctrl-%d", state);
	list = fdt_getprop(fdt, node, propname, &size);
	if (!list)
		return -EINVAL;

	size /= sizeof(*list);
	for (i = 0; i < size; i++) {
		phandle = fdt32_to_cpu(*list++);

		config_node = fdt_node_offset_by_phandle(fdt, phandle);
		if (config_node < 0) {
			dev_err(dev, "prop %s index %d invalid phandle\n",
				propname, i);
			return -EINVAL;
		}
		ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG,
						     config_node, &config);
		if (ret)
			return ret;

		ret = pinctrl_config_one(config);
		if (ret)
			return ret;
	}

	return 0;
}
Ejemplo n.º 2
0
/**
 * pinctrl_select_state_full() - full implementation of pinctrl_select_state
 *
 * @dev: peripheral device
 * @statename: state name, like "default"
 * @return: 0 on success, or negative error code on failure
 */
static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
{
	char propname[32]; /* long enough */
	const fdt32_t *list;
	uint32_t phandle;
	struct udevice *config;
	int state, size, i, ret;

	state = dev_read_stringlist_search(dev, "pinctrl-names", statename);
	if (state < 0) {
		char *end;
		/*
		 * If statename is not found in "pinctrl-names",
		 * assume statename is just the integer state ID.
		 */
		state = simple_strtoul(statename, &end, 10);
		if (*end)
			return -EINVAL;
	}

	snprintf(propname, sizeof(propname), "pinctrl-%d", state);
	list = dev_read_prop(dev, propname, &size);
	if (!list)
		return -EINVAL;

	size /= sizeof(*list);
	for (i = 0; i < size; i++) {
		phandle = fdt32_to_cpu(*list++);
		ret = uclass_get_device_by_phandle_id(UCLASS_PINCONFIG, phandle,
						      &config);
		if (ret)
			return ret;

		ret = pinctrl_config_one(config);
		if (ret)
			return ret;
	}

	return 0;
}
Ejemplo n.º 3
0
int of_pinctrl_select_state(struct device_node *np, const char *name)
{
	int state, ret;
	char propname[sizeof("pinctrl-4294967295")];
	const __be32 *list;
	int size, config;
	phandle phandle;
	struct device_node *np_config;
	const char *statename;

	if (!of_find_property(np, "pinctrl-0", NULL))
		return 0;

	/* For each defined state ID */
	for (state = 0; ; state++) {
		/* Retrieve the pinctrl-* property */
		sprintf(propname, "pinctrl-%d", state);
		list = of_get_property(np, propname, &size);
		if (!list) {
			ret = -ENODEV;
			break;
		}

		size /= sizeof(*list);

		/* Determine whether pinctrl-names property names the state */
		ret = of_property_read_string_index(np, "pinctrl-names",
						    state, &statename);
		/*
		 * If not, statename is just the integer state ID. But rather
		 * than dynamically allocate it and have to free it later,
		 * just point part way into the property name for the string.
		 */
		if (ret < 0) {
			/* strlen("pinctrl-") == 8 */
			statename = &propname[8];
		}

		if (strcmp(name, statename))
			continue;

		/* For every referenced pin configuration node in it */
		for (config = 0; config < size; config++) {
			phandle = be32_to_cpup(list++);

			/* Look up the pin configuration node */
			np_config = of_find_node_by_phandle(phandle);
			if (!np_config) {
				pr_err("prop %s %s index %i invalid phandle\n",
					np->full_name, propname, config);
				ret = -EINVAL;
				goto err;
			}

			/* Parse the node */
			ret = pinctrl_config_one(np_config);
			if (ret < 0)
				goto err;
		}

		return 0;
	}
err:
	return ret;
}