Commit 90a18c51 authored by Antonio Borneo's avatar Antonio Borneo Committed by Linus Walleij
Browse files

pinctrl: pinconf-generic: Handle string values for generic properties



Allow a generic pinconf property to specify its argument as one of
the strings in a match list.
Convert the matching string to an integer value using the index in
the list, then keep using this value in the generic pinconf code.

Signed-off-by: default avatarAntonio Borneo <antonio.borneo@foss.st.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 4a6cc965
Loading
Loading
Loading
Loading
+41 −16
Original line number Diff line number Diff line
@@ -65,11 +65,12 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
	int i;

	for (i = 0; i < nitems; i++) {
		const struct pin_config_item *item = &items[i];
		unsigned long config;
		int ret;

		/* We want to check out this parameter */
		config = pinconf_to_config_packed(items[i].param, 0);
		config = pinconf_to_config_packed(item->param, 0);
		if (gname)
			ret = pin_config_group_get(dev_name(pctldev->dev),
						   gname, &config);
@@ -86,15 +87,22 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
		if (*print_sep)
			seq_puts(s, ", ");
		*print_sep = 1;
		seq_puts(s, items[i].display);
		seq_puts(s, item->display);
		/* Print unit if available */
		if (items[i].has_arg) {
		if (item->has_arg) {
			u32 val = pinconf_to_config_argument(config);

			if (items[i].format)
				seq_printf(s, " (%u %s)", val, items[i].format);
			if (item->format)
				seq_printf(s, " (%u %s)", val, item->format);
			else
				seq_printf(s, " (0x%x)", val);

			if (item->values && item->num_values) {
				if (val < item->num_values)
					seq_printf(s, " \"%s\"", item->values[val]);
				else
					seq_puts(s, " \"(unknown)\"");
			}
		}
	}
}
@@ -205,7 +213,7 @@ static const struct pinconf_generic_params dt_params[] = {
 * @ncfg. @ncfg is updated to reflect the number of entries after parsing. @cfg
 * needs to have enough memory allocated to hold all possible entries.
 */
static void parse_dt_cfg(struct device_node *np,
static int parse_dt_cfg(struct device_node *np,
			const struct pinconf_generic_params *params,
			unsigned int count, unsigned long *cfg,
			unsigned int *ncfg)
@@ -217,7 +225,19 @@ static void parse_dt_cfg(struct device_node *np,
		int ret;
		const struct pinconf_generic_params *par = &params[i];

		if (par->values && par->num_values) {
			ret = fwnode_property_match_property_string(of_fwnode_handle(np),
								    par->property,
								    par->values, par->num_values);
			if (ret == -ENOENT)
				return ret;
			if (ret >= 0) {
				val = ret;
				ret = 0;
			}
		} else {
			ret = of_property_read_u32(np, par->property, &val);
		}

		/* property not found */
		if (ret == -EINVAL)
@@ -231,6 +251,8 @@ static void parse_dt_cfg(struct device_node *np,
		cfg[*ncfg] = pinconf_to_config_packed(par->param, val);
		(*ncfg)++;
	}

	return 0;
}

/**
@@ -323,13 +345,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
	if (!cfg)
		return -ENOMEM;

	parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg);
	ret = parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg);
	if (ret)
		return ret;
	if (pctldev && pctldev->desc->num_custom_params &&
		pctldev->desc->custom_params)
		parse_dt_cfg(np, pctldev->desc->custom_params,
		pctldev->desc->custom_params) {
		ret = parse_dt_cfg(np, pctldev->desc->custom_params,
				   pctldev->desc->num_custom_params, cfg, &ncfg);

	ret = 0;
		if (ret)
			return ret;
	}

	/* no configs found at all */
	if (ncfg == 0) {
+9 −2
Original line number Diff line number Diff line
@@ -181,21 +181,28 @@ static inline unsigned long pinconf_to_config_packed(enum pin_config_param param
	return PIN_CONF_PACKED(param, argument);
}

#define PCONFDUMP(a, b, c, d) {					\
	.param = a, .display = b, .format = c, .has_arg = d	\
#define PCONFDUMP_WITH_VALUES(a, b, c, d, e, f) {		\
	.param = a, .display = b, .format = c, .has_arg = d,	\
	.values = e, .num_values = f				\
	}

#define PCONFDUMP(a, b, c, d)	PCONFDUMP_WITH_VALUES(a, b, c, d, NULL, 0)

struct pin_config_item {
	const enum pin_config_param param;
	const char * const display;
	const char * const format;
	bool has_arg;
	const char * const *values;
	size_t num_values;
};

struct pinconf_generic_params {
	const char * const property;
	enum pin_config_param param;
	u32 default_value;
	const char * const *values;
	size_t num_values;
};

int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,