static int axp_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { struct axp_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); int data; int func; switch (SUNXI_PINCFG_UNPACK_TYPE(config)) { case SUNXI_PINCFG_TYPE_DAT: data = SUNXI_PINCFG_UNPACK_VALUE(config); axp_gpio_set_data(pin, data); pr_debug("axp pconf set pin [%s] data to [%d]\n", pin_get_name(pctl->pctl_dev, pin), data); break; case SUNXI_PINCFG_TYPE_FUNC: func = SUNXI_PINCFG_UNPACK_VALUE(config); axp_pmx_set(pin, func); pr_debug("axp pconf set pin [%s] func to [%d]\n", pin_get_name(pctl->pctl_dev, pin), func); break; default: pr_debug("invalid axp pconf type for set\n"); return -EINVAL; } return 0; }
static int axp_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { struct axp_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); int data; switch (SUNXI_PINCFG_UNPACK_TYPE(*config)) { case SUNXI_PINCFG_TYPE_DAT: data = axp_gpio_get_data(pin); *config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DAT, data); pr_debug("axp pconf get pin [%s] data [%d]\n", pin_get_name(pctl->pctl_dev, pin), data); break; case SUNXI_PINCFG_TYPE_FUNC: data = axp_pmx_get(pin); *config = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, data); pr_debug("axp pconf get pin [%s] funcs [%d]\n", pin_get_name(pctl->pctl_dev, pin), data); break; default: pr_debug("invalid axp pconf type for get\n"); return -EINVAL; } return 0; }
static int imx1_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np, struct pinctrl_map **map, unsigned *num_maps) { struct imx1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx1_pinctrl_soc_info *info = ipctl->info; const struct imx1_pin_group *grp; struct pinctrl_map *new_map; struct device_node *parent; int map_num = 1; int i, j; /* * first find the group of this node and check if we need create * config maps for pins */ grp = imx1_pinctrl_find_group_by_name(info, np->name); if (!grp) { dev_err(info->dev, "unable to find group for node %s\n", np->name); return -EINVAL; } for (i = 0; i < grp->npins; i++) map_num++; new_map = kmalloc(sizeof(struct pinctrl_map) * map_num, GFP_KERNEL); if (!new_map) return -ENOMEM; *map = new_map; *num_maps = map_num; /* create mux map */ parent = of_get_parent(np); if (!parent) { kfree(new_map); return -EINVAL; } new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; new_map[0].data.mux.function = parent->name; new_map[0].data.mux.group = np->name; of_node_put(parent); /* create config map */ new_map++; for (i = j = 0; i < grp->npins; i++) { new_map[j].type = PIN_MAP_TYPE_CONFIGS_PIN; new_map[j].data.configs.group_or_pin = pin_get_name(pctldev, grp->pins[i].pin_id); new_map[j].data.configs.configs = &grp->pins[i].config; new_map[j].data.configs.num_configs = 1; j++; } dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", (*map)->data.mux.function, (*map)->data.mux.group, map_num); return 0; }
static void s32v_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned group) { struct s32v_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct s32v_pinctrl_soc_info *info = ipctl->info; struct s32v_pin_group *grp; unsigned long config; const char *name; int i, ret; if (group > info->ngroups) return; seq_printf(s, "\n"); grp = &info->groups[group]; for (i = 0; i < grp->npins; i++) { struct s32v_pin *pin = &grp->pins[i]; name = pin_get_name(pctldev, pin->pin_id); ret = s32v_pinconf_get(pctldev, pin->pin_id, &config); if (ret) return; seq_printf(s, "%s: 0x%lx", name, config); } }
static int sprd_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np, struct pinctrl_map **map, unsigned int *num_maps) { struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); const struct sprd_pin_group *grp; unsigned long *configs = NULL; unsigned int num_configs = 0; unsigned int reserved_maps = 0; unsigned int reserve = 0; const char *function; enum pinctrl_map_type type; int ret; grp = sprd_pinctrl_find_group_by_name(pctl, np->name); if (!grp) { dev_err(pctl->dev, "unable to find group for node %s\n", of_node_full_name(np)); return -EINVAL; } ret = of_property_count_strings(np, "pins"); if (ret < 0) return ret; if (ret == 1) type = PIN_MAP_TYPE_CONFIGS_PIN; else type = PIN_MAP_TYPE_CONFIGS_GROUP; ret = of_property_read_string(np, "function", &function); if (ret < 0) { if (ret != -EINVAL) dev_err(pctl->dev, "%s: could not parse property function\n", of_node_full_name(np)); function = NULL; } ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs); if (ret < 0) { dev_err(pctl->dev, "%s: could not parse node property\n", of_node_full_name(np)); return ret; } *map = NULL; *num_maps = 0; if (function != NULL) reserve++; if (num_configs) reserve++; ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, num_maps, reserve); if (ret < 0) goto out; if (function) { ret = pinctrl_utils_add_map_mux(pctldev, map, &reserved_maps, num_maps, grp->name, function); if (ret < 0) goto out; } if (num_configs) { const char *group_or_pin; unsigned int pin_id; if (type == PIN_MAP_TYPE_CONFIGS_PIN) { pin_id = grp->pins[0]; group_or_pin = pin_get_name(pctldev, pin_id); } else { group_or_pin = grp->name; } ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps, num_maps, group_or_pin, configs, num_configs, type); } out: kfree(configs); return ret; }
static int axp_pin_cfg_to_pin_map(struct platform_device *pdev, struct gpio_config *cfg, struct pinctrl_map *map, char *mainkey_name) { int num_configs; unsigned long *configs; unsigned int pin_number; const char *pin_name; const char *ctrl_name = dev_name(&pdev->dev); const char *function_name; struct axp_pinctrl *pctl = platform_get_drvdata(pdev); /* convert axp pin config number to pinctrl number */ if (!IS_AXP_PIN(cfg->gpio)) { /* invalid axp pin config, skip it */ return 0; } /* find pin name by number */ pin_number = cfg->gpio - AXP_PIN_BASE; pin_name = pin_get_name(pctl->pctl_dev, pin_number); if (!pin_name) { pr_warn("invalid pin config under axp platform\n"); return 0; } /* mux pinctrl map */ if (cfg->mul_sel == AXP_PIN_INPUT_FUNC) { /* pin mux : input */ function_name = "gpio_in"; } else if (cfg->mul_sel == AXP_PIN_OUTPUT_FUNC) { /* pin mux : output */ function_name = "gpio_out"; } else { /* invalid pin mux for axp pinctrl */ pr_warn("invalid pin mux value for axp pinctrl\n"); return 0; } map[0].dev_name = mainkey_name; map[0].name = PINCTRL_STATE_DEFAULT; map[0].type = PIN_MAP_TYPE_MUX_GROUP; map[0].ctrl_dev_name = ctrl_name; map[0].data.mux.function = function_name; map[0].data.mux.group = pin_name; /* configuration pinctrl map, * suppose max pin config is 1. * axp have only 1 type configurations: output-data/. * yes I know the configs memory will binding to pinctrl always, * if we binding it to pinctrl, we don't free it anywhere! * the configs memory will always allocate for pinctrl. * by sunny at 2013-4-28 15:52:16. */ num_configs = 0; configs = kzalloc(sizeof(unsigned int) * 1, GFP_KERNEL); if (!configs) { pr_err("allocate memory for axp pin config failed\n"); return -ENOMEM; } if (cfg->data != GPIO_DATA_DEFAULT) { configs[0] = SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DAT, cfg->data); num_configs++; } if (num_configs == 0) { /* this pin have no configurations, * use hardware default value. * we have only one map. */ kfree(configs); return 1; } map[1].dev_name = mainkey_name; map[1].name = PINCTRL_STATE_DEFAULT; map[1].type = PIN_MAP_TYPE_CONFIGS_GROUP; map[1].ctrl_dev_name = ctrl_name; map[1].data.configs.group_or_pin = pin_name; map[1].data.configs.configs = configs; map[1].data.configs.num_configs = num_configs; /* we have two maps: mux + configs */ return 2; }