Commit d48c1ada authored by Cezary Rojewski's avatar Cezary Rojewski Committed by Mark Brown

ASoC: Intel: avs: Support link_mask formatted string

Allow topology to specify formatted strings so machine board's
predefined ->link_mask can be used to specify SSP port number
automatically.

This is done to help reduce the amount of topology files as many I2S
configurations contain codec of the same type with little to no
differences in number of scenarios supported - the only difference being
the port number codec is connected to.
Signed-off-by: default avatarAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20220331135246.993089-9-cezary.rojewski@intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent d73d1b67
......@@ -372,6 +372,26 @@ parse_audio_format_bitfield(struct snd_soc_component *comp, void *elem, void *ob
return 0;
}
static int parse_link_formatted_string(struct snd_soc_component *comp, void *elem,
void *object, u32 offset)
{
struct snd_soc_tplg_vendor_string_elem *tuple = elem;
struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
char *val = (char *)((u8 *)object + offset);
/*
* Dynamic naming - string formats, e.g.: ssp%d - supported only for
* topologies describing single device e.g.: an I2S codec on SSP0.
*/
if (hweight_long(mach->link_mask) != 1)
return avs_parse_string_token(comp, elem, object, offset);
snprintf(val, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, tuple->string,
__ffs(mach->link_mask));
return 0;
}
static int
parse_dictionary_header(struct snd_soc_component *comp,
struct snd_soc_tplg_vendor_array *tuples,
......@@ -928,7 +948,7 @@ static const struct avs_tplg_token_parser binding_parsers[] = {
.token = AVS_TKN_BINDING_TARGET_TPLG_NAME_STRING,
.type = SND_SOC_TPLG_TUPLE_TYPE_STRING,
.offset = offsetof(struct avs_tplg_binding, target_tplg_name),
.parse = avs_parse_string_token,
.parse = parse_link_formatted_string,
},
{
.token = AVS_TKN_BINDING_TARGET_PATH_TMPL_ID_U32,
......@@ -1323,6 +1343,31 @@ avs_tplg_path_template_create(struct snd_soc_component *comp, struct avs_tplg *o
return template;
}
static int avs_route_load(struct snd_soc_component *comp, int index,
struct snd_soc_dapm_route *route)
{
struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
size_t len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
char buf[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
u32 port;
/* See parse_link_formatted_string() for dynamic naming when(s). */
if (hweight_long(mach->link_mask) == 1) {
port = __ffs(mach->link_mask);
snprintf(buf, len, route->source, port);
strncpy((char *)route->source, buf, len);
snprintf(buf, len, route->sink, port);
strncpy((char *)route->sink, buf, len);
if (route->control) {
snprintf(buf, len, route->control, port);
strncpy((char *)route->control, buf, len);
}
}
return 0;
}
static int avs_widget_load(struct snd_soc_component *comp, int index,
struct snd_soc_dapm_widget *w,
struct snd_soc_tplg_dapm_widget *dw)
......@@ -1338,6 +1383,15 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
tplg = acomp->tplg;
mach = dev_get_platdata(comp->card->dev);
/* See parse_link_formatted_string() for dynamic naming when(s). */
if (hweight_long(mach->link_mask) == 1) {
kfree(w->name);
/* w->name is freed later by soc_tplg_dapm_widget_create() */
w->name = kasprintf(GFP_KERNEL, dw->name, __ffs(mach->link_mask));
if (!w->name)
return -ENOMEM;
}
template = avs_tplg_path_template_create(comp, tplg, dw->priv.array,
le32_to_cpu(dw->priv.size));
if (IS_ERR(template)) {
......@@ -1380,7 +1434,7 @@ static const struct avs_tplg_token_parser manifest_parsers[] = {
.token = AVS_TKN_MANIFEST_NAME_STRING,
.type = SND_SOC_TPLG_TUPLE_TYPE_STRING,
.offset = offsetof(struct avs_tplg, name),
.parse = avs_parse_string_token,
.parse = parse_link_formatted_string,
},
{
.token = AVS_TKN_MANIFEST_VERSION_U32,
......@@ -1498,6 +1552,7 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
}
static struct snd_soc_tplg_ops avs_tplg_ops = {
.dapm_route_load = avs_route_load,
.widget_load = avs_widget_load,
.dai_load = avs_dai_load,
.link_load = avs_link_load,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment