Example #1
0
static int pinmux_pins_show(struct seq_file *s, void *what)
{
    struct pinctrl_dev *pctldev = s->private;
    const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
    const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
    unsigned i, pin;

    if (!pmxops)
        return 0;

    seq_puts(s, "Pinmux settings per pin\n");
    seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n");

    mutex_lock(&pinctrl_mutex);

    /* The pin number can be retrived from the pin controller descriptor */
    for (i = 0; i < pctldev->desc->npins; i++) {
        struct pin_desc *desc;
        bool is_hog = false;

        pin = pctldev->desc->pins[i].number;
        desc = pin_desc_get(pctldev, pin);
        /* Skip if we cannot search the pin */
        if (desc == NULL)
            continue;

        if (desc->mux_owner &&
                !strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
            is_hog = true;

        seq_printf(s, "pin %d (%s): %s %s%s", pin,
                   desc->name ? desc->name : "unnamed",
                   desc->mux_owner ? desc->mux_owner
                   : "(MUX UNCLAIMED)",
                   desc->gpio_owner ? desc->gpio_owner
                   : "(GPIO UNCLAIMED)",
                   is_hog ? " (HOG)" : "");

        if (desc->mux_setting)
            seq_printf(s, " function %s group %s\n",
                       pmxops->get_function_name(pctldev,
                                                 desc->mux_setting->func),
                       pctlops->get_group_name(pctldev,
                                               desc->mux_setting->group));
        else
            seq_printf(s, "\n");
    }

    mutex_unlock(&pinctrl_mutex);

    return 0;
}
Example #2
0
static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
{
	struct device_node *np = chip->of_node;
	struct of_phandle_args pinspec;
	struct pinctrl_dev *pctldev;
	int index = 0, ret;

	if (!np)
		return;

	do {
		ret = of_parse_phandle_with_args(np, "gpio-ranges",
				"#gpio-range-cells", index, &pinspec);
		if (ret)
			break;

		pctldev = of_pinctrl_get(pinspec.np);
		if (!pctldev)
			break;

		/*
		 * This assumes that the n GPIO pins are consecutive in the
		 * GPIO number space, and that the pins are also consecutive
		 * in their local number space. Currently it is not possible
		 * to add different ranges for one and the same GPIO chip,
		 * as the code assumes that we have one consecutive range
		 * on both, mapping 1-to-1.
		 *
		 * TODO: make the OF bindings handle multiple sparse ranges
		 * on the same GPIO chip.
		 */
		ret = gpiochip_add_pin_range(chip,
					     pinctrl_dev_get_name(pctldev),
					     0, /* offset in gpiochip */
					     pinspec.args[0],
					     pinspec.args[1]);

		if (ret)
			break;

	} while (index++);
}
Example #3
0
static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev,
                                        const char *function)
{
    const struct pinmux_ops *ops = pctldev->desc->pmxops;
    unsigned nfuncs = ops->get_functions_count(pctldev);
    unsigned selector = 0;

    /* See if this pctldev has this function */
    while (selector < nfuncs) {
        const char *fname = ops->get_function_name(pctldev,
                            selector);

        if (!strcmp(function, fname))
            return selector;

        selector++;
    }

    pr_err("%s does not support function %s\n",
           pinctrl_dev_get_name(pctldev), function);
    return -EINVAL;
}
Example #4
0
int pinmux_enable_setting(struct pinctrl_setting const *setting)
{
    struct pinctrl_dev *pctldev = setting->pctldev;
    const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
    const struct pinmux_ops *ops = pctldev->desc->pmxops;
    int ret;
    const unsigned *pins;
    unsigned num_pins;
    int i;
    struct pin_desc *desc;

    ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
                                  &pins, &num_pins);
    if (ret) {
        /* errors only affect debug data, so just warn */
        dev_warn(pctldev->dev,
                 "could not get pins for group selector %d\n",
                 setting->data.mux.group);
        num_pins = 0;
    }

    /* Try to allocate all pins in this group, one by one */
    for (i = 0; i < num_pins; i++) {
        ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
        if (ret) {
            dev_err(pctldev->dev,
                    "could not request pin %d on device %s\n",
                    pins[i], pinctrl_dev_get_name(pctldev));
            goto err_pin_request;
        }
    }

    /* Now that we have acquired the pins, encode the mux setting */
    for (i = 0; i < num_pins; i++) {
        desc = pin_desc_get(pctldev, pins[i]);
        if (desc == NULL) {
            dev_warn(pctldev->dev,
                     "could not get pin desc for pin %d\n",
                     pins[i]);
            continue;
        }
        desc->mux_setting = &(setting->data.mux);
    }

    ret = ops->enable(pctldev, setting->data.mux.func,
                      setting->data.mux.group);

    if (ret)
        goto err_enable;

    return 0;

err_enable:
    for (i = 0; i < num_pins; i++) {
        desc = pin_desc_get(pctldev, pins[i]);
        if (desc)
            desc->mux_setting = NULL;
    }
err_pin_request:
    /* On error release all taken pins */
    while (--i >= 0)
        pin_free(pctldev, pins[i], NULL);

    return ret;
}
int pinmux_enable_setting(struct pinctrl_setting const *setting)
{
	struct pinctrl_dev *pctldev = setting->pctldev;
	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
	const struct pinmux_ops *ops = pctldev->desc->pmxops;
	int ret;
	const unsigned *pins;
	unsigned num_pins;
	int i;
	struct pin_desc *desc;

	ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
				      &pins, &num_pins);
	if (ret) {
		
		dev_warn(pctldev->dev,
			 "could not get pins for group selector %d\n",
			 setting->data.mux.group);
		num_pins = 0;
	}

	
	for (i = 0; i < num_pins; i++) {
		ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
		if (ret) {
			dev_err(pctldev->dev,
				"could not request pin %d on device %s\n",
				pins[i], pinctrl_dev_get_name(pctldev));
			goto err_pin_request;
		}
	}

	
	for (i = 0; i < num_pins; i++) {
		desc = pin_desc_get(pctldev, pins[i]);
		if (desc == NULL) {
			dev_warn(pctldev->dev,
				 "could not get pin desc for pin %d\n",
				 pins[i]);
			continue;
		}
		desc->mux_setting = &(setting->data.mux);
	}

	ret = ops->enable(pctldev, setting->data.mux.func,
			  setting->data.mux.group);

	if (ret)
		goto err_enable;

	return 0;

err_enable:
	for (i = 0; i < num_pins; i++) {
		desc = pin_desc_get(pctldev, pins[i]);
		if (desc)
			desc->mux_setting = NULL;
	}
err_pin_request:
	
	while (--i >= 0)
		pin_free(pctldev, pins[i], NULL);

	return ret;
}