Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  linux/drivers/pinctrl/pinctrl-lantiq.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  based on linux/drivers/pinctrl/pinctrl-pxa3xx.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (C) 2012 John Crispin <john@phrozen.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "pinctrl-lantiq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static int ltq_get_group_count(struct pinctrl_dev *pctrldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	return info->num_grps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static const char *ltq_get_group_name(struct pinctrl_dev *pctrldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 					 unsigned selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	if (selector >= info->num_grps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	return info->grps[selector].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int ltq_get_group_pins(struct pinctrl_dev *pctrldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 				 unsigned selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 				 const unsigned **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 				 unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (selector >= info->num_grps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	*pins = info->grps[selector].pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	*num_pins = info->grps[selector].npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 				    struct pinctrl_map *map, unsigned num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	for (i = 0; i < num_maps; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		    map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			kfree(map[i].data.configs.configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	kfree(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 					struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 					unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	seq_printf(s, " %s", dev_name(pctldev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 				struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 				struct pinctrl_map **map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct property *pins = of_find_property(np, "lantiq,pins", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct property *groups = of_find_property(np, "lantiq,groups", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned long configs[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	unsigned num_configs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	const char *group, *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	const char *function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (!pins && !groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		dev_err(pctldev->dev, "%pOFn defines neither pins nor groups\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	if (pins && groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		dev_err(pctldev->dev, "%pOFn defines both pins and groups\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	ret = of_property_read_string(np, "lantiq,function", &function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (groups && !ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		of_property_for_each_string(np, "lantiq,groups", prop, group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			(*map)->name = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			(*map)->data.mux.group = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			(*map)->data.mux.function = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			(*map)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	for (i = 0; i < info->num_params; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		int ret = of_property_read_u32(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				info->params[i].property, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			configs[num_configs++] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 				LTQ_PINCONF_PACK(info->params[i].param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 				val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (!num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	of_property_for_each_string(np, "lantiq,pins", prop, pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		(*map)->data.configs.configs = kmemdup(configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 					num_configs * sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		(*map)->type = PIN_MAP_TYPE_CONFIGS_PIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		(*map)->name = pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		(*map)->data.configs.group_or_pin = pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		(*map)->data.configs.num_configs = num_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		(*map)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	of_property_for_each_string(np, "lantiq,groups", prop, group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		(*map)->data.configs.configs = kmemdup(configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 					num_configs * sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		(*map)->name = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		(*map)->data.configs.group_or_pin = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		(*map)->data.configs.num_configs = num_configs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		(*map)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	ret = of_property_count_strings(np, "lantiq,groups");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		ret = of_property_count_strings(np, "lantiq,pins");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 				      struct device_node *np_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 				      struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 				      unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct pinctrl_map *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	int max_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	for_each_child_of_node(np_config, np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		max_maps += ltq_pinctrl_dt_subnode_size(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	*map = kzalloc(array3_size(max_maps, sizeof(struct pinctrl_map), 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (!*map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	tmp = *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	for_each_child_of_node(np_config, np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	*num_maps = ((int)(tmp - *map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static const struct pinctrl_ops ltq_pctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	.get_groups_count	= ltq_get_group_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	.get_group_name		= ltq_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	.get_group_pins		= ltq_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	.pin_dbg_show		= ltq_pinctrl_pin_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	.dt_node_to_map		= ltq_pinctrl_dt_node_to_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	.dt_free_map		= ltq_pinctrl_dt_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	return info->num_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static const char *ltq_pmx_func_name(struct pinctrl_dev *pctrldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 					 unsigned selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if (selector >= info->num_funcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	return info->funcs[selector].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int ltq_pmx_get_groups(struct pinctrl_dev *pctrldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				unsigned func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 				const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	*groups = info->funcs[func].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	*num_groups = info->funcs[func].num_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Return function number. If failure, return negative value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	for (i = 0; i < LTQ_MAX_MUX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		if (mfp->func[i] == mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (i >= LTQ_MAX_MUX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* don't assume .mfp is linearly mapped. find the mfp with the correct .pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int match_mfp(const struct ltq_pinmux_info *info, int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	for (i = 0; i < info->num_mfp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		if (info->mfp[i].pin == pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* check whether current pin configuration is valid. Negative for failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int match_group_mux(const struct ltq_pin_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			   const struct ltq_pinmux_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			   unsigned mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	int i, pin, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	for (i = 0; i < grp->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		pin = match_mfp(info, grp->pins[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		if (pin < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			dev_err(info->dev, "could not find mfp for pin %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 				grp->pins[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		ret = match_mux(&info->mfp[pin], mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			dev_err(info->dev, "Can't find mux %d on pin%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				mux, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int ltq_pmx_set(struct pinctrl_dev *pctrldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		       unsigned func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		       unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	const struct ltq_pin_group *pin_grp = &info->grps[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	int i, pin, pin_func, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (!pin_grp->npins ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		(match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		dev_err(info->dev, "Failed to set the pin group: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			info->grps[group].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	for (i = 0; i < pin_grp->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		pin = match_mfp(info, pin_grp->pins[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		if (pin < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			dev_err(info->dev, "could not find mfp for pin %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				pin_grp->pins[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		ret = info->apply_mux(pctrldev, pin, pin_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			dev_err(info->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				"failed to apply mux %d for pin %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 				pin_func, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 				struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 				unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int mfp = match_mfp(info, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	int pin_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	if (mfp < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		dev_err(info->dev, "could not find mfp for pin %d\n", pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	pin_func = match_mux(&info->mfp[mfp], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if (pin_func < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		dev_err(info->dev, "No GPIO function on pin%d\n", mfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	return info->apply_mux(pctrldev, mfp, pin_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static const struct pinmux_ops ltq_pmx_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	.get_functions_count	= ltq_pmx_func_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	.get_function_name	= ltq_pmx_func_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	.get_function_groups	= ltq_pmx_get_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	.set_mux		= ltq_pmx_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	.gpio_request_enable	= ltq_pmx_gpio_request_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  * allow different socs to register with the generic part of the lanti
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * pinctrl code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int ltq_pinctrl_register(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 				struct ltq_pinmux_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	struct pinctrl_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	desc = info->desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	desc->pctlops = &ltq_pctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	desc->pmxops = &ltq_pmx_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	info->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	info->pctrl = devm_pinctrl_register(&pdev->dev, desc, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	if (IS_ERR(info->pctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		return PTR_ERR(info->pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	platform_set_drvdata(pdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }