mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 20:46:48 +02:00
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: Antonio Borneo <antonio.borneo@foss.st.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
4a6cc9655f
commit
90a18c5128
|
|
@ -65,11 +65,12 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < nitems; i++) {
|
for (i = 0; i < nitems; i++) {
|
||||||
|
const struct pin_config_item *item = &items[i];
|
||||||
unsigned long config;
|
unsigned long config;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* We want to check out this parameter */
|
/* 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)
|
if (gname)
|
||||||
ret = pin_config_group_get(dev_name(pctldev->dev),
|
ret = pin_config_group_get(dev_name(pctldev->dev),
|
||||||
gname, &config);
|
gname, &config);
|
||||||
|
|
@ -86,15 +87,22 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
|
||||||
if (*print_sep)
|
if (*print_sep)
|
||||||
seq_puts(s, ", ");
|
seq_puts(s, ", ");
|
||||||
*print_sep = 1;
|
*print_sep = 1;
|
||||||
seq_puts(s, items[i].display);
|
seq_puts(s, item->display);
|
||||||
/* Print unit if available */
|
/* Print unit if available */
|
||||||
if (items[i].has_arg) {
|
if (item->has_arg) {
|
||||||
u32 val = pinconf_to_config_argument(config);
|
u32 val = pinconf_to_config_argument(config);
|
||||||
|
|
||||||
if (items[i].format)
|
if (item->format)
|
||||||
seq_printf(s, " (%u %s)", val, items[i].format);
|
seq_printf(s, " (%u %s)", val, item->format);
|
||||||
else
|
else
|
||||||
seq_printf(s, " (0x%x)", val);
|
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,10 +213,10 @@ static const struct pinconf_generic_params dt_params[] = {
|
||||||
* @ncfg. @ncfg is updated to reflect the number of entries after parsing. @cfg
|
* @ncfg. @ncfg is updated to reflect the number of entries after parsing. @cfg
|
||||||
* needs to have enough memory allocated to hold all possible entries.
|
* 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,
|
const struct pinconf_generic_params *params,
|
||||||
unsigned int count, unsigned long *cfg,
|
unsigned int count, unsigned long *cfg,
|
||||||
unsigned int *ncfg)
|
unsigned int *ncfg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -217,7 +225,19 @@ static void parse_dt_cfg(struct device_node *np,
|
||||||
int ret;
|
int ret;
|
||||||
const struct pinconf_generic_params *par = ¶ms[i];
|
const struct pinconf_generic_params *par = ¶ms[i];
|
||||||
|
|
||||||
ret = of_property_read_u32(np, par->property, &val);
|
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 */
|
/* property not found */
|
||||||
if (ret == -EINVAL)
|
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);
|
cfg[*ncfg] = pinconf_to_config_packed(par->param, val);
|
||||||
(*ncfg)++;
|
(*ncfg)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -323,13 +345,16 @@ int pinconf_generic_parse_dt_config(struct device_node *np,
|
||||||
if (!cfg)
|
if (!cfg)
|
||||||
return -ENOMEM;
|
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 &&
|
if (pctldev && pctldev->desc->num_custom_params &&
|
||||||
pctldev->desc->custom_params)
|
pctldev->desc->custom_params) {
|
||||||
parse_dt_cfg(np, pctldev->desc->custom_params,
|
ret = parse_dt_cfg(np, pctldev->desc->custom_params,
|
||||||
pctldev->desc->num_custom_params, cfg, &ncfg);
|
pctldev->desc->num_custom_params, cfg, &ncfg);
|
||||||
|
if (ret)
|
||||||
ret = 0;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* no configs found at all */
|
/* no configs found at all */
|
||||||
if (ncfg == 0) {
|
if (ncfg == 0) {
|
||||||
|
|
|
||||||
|
|
@ -181,21 +181,28 @@ static inline unsigned long pinconf_to_config_packed(enum pin_config_param param
|
||||||
return PIN_CONF_PACKED(param, argument);
|
return PIN_CONF_PACKED(param, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PCONFDUMP(a, b, c, d) { \
|
#define PCONFDUMP_WITH_VALUES(a, b, c, d, e, f) { \
|
||||||
.param = a, .display = b, .format = c, .has_arg = d \
|
.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 {
|
struct pin_config_item {
|
||||||
const enum pin_config_param param;
|
const enum pin_config_param param;
|
||||||
const char * const display;
|
const char * const display;
|
||||||
const char * const format;
|
const char * const format;
|
||||||
bool has_arg;
|
bool has_arg;
|
||||||
|
const char * const *values;
|
||||||
|
size_t num_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pinconf_generic_params {
|
struct pinconf_generic_params {
|
||||||
const char * const property;
|
const char * const property;
|
||||||
enum pin_config_param param;
|
enum pin_config_param param;
|
||||||
u32 default_value;
|
u32 default_value;
|
||||||
|
const char * const *values;
|
||||||
|
size_t num_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
|
int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user