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; }
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++); }
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; }
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; }