Example #1
0
/**
 * pinctrl_generic_set_state_subnode() - apply all settings in config node
 *
 * @dev: pin controller device
 * @config: pseudo device pointing to config node
 * @return: 0 on success, or negative error code on failure
 */
static int pinctrl_generic_set_state_subnode(struct udevice *dev,
					     struct udevice *config)
{
	const void *fdt = gd->fdt_blob;
	int node = config->of_offset;
	const char *subnode_target_type = "pins";
	bool is_group = false;
	const char *name;
	int strings_count, selector, i, ret;

	strings_count = fdt_stringlist_count(fdt, node, subnode_target_type);
	if (strings_count < 0) {
		subnode_target_type = "groups";
		is_group = true;
		strings_count = fdt_stringlist_count(fdt, node,
						     subnode_target_type);
		if (strings_count < 0) {
			/* skip this node; may contain config child nodes */
			return 0;
		}
	}

	for (i = 0; i < strings_count; i++) {
		name = fdt_stringlist_get(fdt, node, subnode_target_type, i,
					  NULL);
		if (!name)
			return -EINVAL;

		if (is_group)
			selector = pinctrl_group_name_to_selector(dev, name);
		else
			selector = pinctrl_pin_name_to_selector(dev, name);
		if (selector < 0)
			return selector;

		ret = pinctrl_generic_set_state_one(dev, config,
						    is_group, selector);
		if (ret)
			return ret;
	}

	return 0;
}
Example #2
0
/**
 * exynos_pinctrl_set_state: configure a pin state.
 * dev: the pinctrl device to be configured.
 * config: the state to be configured.
 */
int exynos_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
	const void *fdt = gd->fdt_blob;
	int node = config->of_offset;
	unsigned int count, idx, pin_num;
	unsigned int pinfunc, pinpud, pindrv;
	unsigned long reg, value;
	const char *name;

	/*
	 * refer to the following document for the pinctrl bindings
	 * linux/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
	 */
	count = fdt_stringlist_count(fdt, node, "samsung,pins");
	if (count <= 0)
		return -EINVAL;

	pinfunc = fdtdec_get_int(fdt, node, "samsung,pin-function", -1);
	pinpud = fdtdec_get_int(fdt, node, "samsung,pin-pud", -1);
	pindrv = fdtdec_get_int(fdt, node, "samsung,pin-drv", -1);

	for (idx = 0; idx < count; idx++) {
		name = fdt_stringlist_get(fdt, node, "samsung,pins", idx, NULL);
		if (!name)
			continue;
		reg = pin_to_bank_base(dev, name, &pin_num);

		if (pinfunc != -1) {
			value = readl(reg + PIN_CON);
			value &= ~(0xf << (pin_num << 2));
			value |= (pinfunc << (pin_num << 2));
			writel(value, reg + PIN_CON);
		}

		if (pinpud != -1) {
			value = readl(reg + PIN_PUD);
			value &= ~(0x3 << (pin_num << 1));
			value |= (pinpud << (pin_num << 1));
			writel(value, reg + PIN_PUD);
		}

		if (pindrv != -1) {
			value = readl(reg + PIN_DRV);
			value &= ~(0x3 << (pin_num << 1));
			value |= (pindrv << (pin_num << 1));
			writel(value, reg + PIN_DRV);
		}
	}

	return 0;
}
Example #3
0
static void check_string_count(const void *fdt, const char *path,
                               const char *property, int count)
{
    int offset, err;

    offset = fdt_path_offset(fdt, path);
    if (offset < 0)
        FAIL("Couldn't find path %s", path);

    err = fdt_stringlist_count(fdt, offset, property);
    if (err < 0)
        FAIL("Couldn't count strings in property %s of node %s: %d\n",
             property, path, err);

    if (err != count)
        FAIL("String count for property %s of node %s is %d instead of %d\n",
             path, property, err, count);
}
static int
tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl,
				 struct tegra_xusb_padctl_group *group,
				 const void *fdt, int node)
{
	unsigned int i;
	int len;

	group->name = fdt_get_name(fdt, node, &len);

	len = fdt_stringlist_count(fdt, node, "nvidia,lanes");
	if (len < 0) {
		error("failed to parse \"nvidia,lanes\" property");
		return -EINVAL;
	}

	group->num_pins = len;

	for (i = 0; i < group->num_pins; i++) {
		group->pins[i] = fdt_stringlist_get(fdt, node, "nvidia,lanes",
						    i, NULL);
		if (!group->pins[i]) {
			error("failed to read string from \"nvidia,lanes\" property");
			return -EINVAL;
		}
	}

	group->num_pins = len;

	group->func = fdt_stringlist_get(fdt, node, "nvidia,function", 0, NULL);
	if (!group->func) {
		error("failed to parse \"nvidia,func\" property");
		return -EINVAL;
	}

	group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1);

	return 0;
}
Example #5
0
static void check_expected_failure(const void *fdt, const char *path,
                                   const char *property)
{
    int offset, err;

    offset = fdt_path_offset(fdt, "/");
    if (offset < 0)
        FAIL("Couldn't find path %s", path);

    err = fdt_stringlist_count(fdt, offset, "#address-cells");
    if (err != -FDT_ERR_BADVALUE)
        FAIL("unexpectedly succeeded in parsing #address-cells\n");

    err = fdt_stringlist_search(fdt, offset, "#address-cells", "foo");
    if (err != -FDT_ERR_BADVALUE)
        FAIL("found string in #address-cells: %d\n", err);

    /*
     * Note that the #address-cells property contains a small 32-bit
     * unsigned integer, hence some bytes will be zero, and searching for
     * the empty string will succeed.
     *
     * The reason for this oddity is that the function will exit when the
     * first occurrence of the string is found, but in order to determine
     * that the property does not contain a valid string list it would
     * need to process the whole value.
     */
    err = fdt_stringlist_search(fdt, offset, "#address-cells", "");
    if (err != 0)
        FAIL("empty string not found in #address-cells: %d\n", err);

    /*
     * fdt_get_string() can successfully extract strings from non-string
     * properties. This is because it doesn't necessarily parse the whole
     * property value, which would be necessary for it to determine if a
     * valid string or string list is present.
     */
}