Skip to content

Commit 1b4217e

Browse files
Amadeusz Sławińskibroonie
authored andcommitted
ASoC: Intel: avs: Add topology parsing support for initial config
Add topology parsing for initial config. Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com> Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> Link: https://lore.kernel.org/r/20240208102400.2497791-3-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent a5766cd commit 1b4217e

File tree

2 files changed

+175
-2
lines changed

2 files changed

+175
-2
lines changed

sound/soc/intel/avs/topology.c

Lines changed: 162 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,24 +1118,72 @@ static const struct avs_tplg_token_parser module_parsers[] = {
11181118
.offset = offsetof(struct avs_tplg_module, ctl_id),
11191119
.parse = avs_parse_byte_token,
11201120
},
1121+
{
1122+
.token = AVS_TKN_MOD_INIT_CONFIG_NUM_IDS_U32,
1123+
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
1124+
.offset = offsetof(struct avs_tplg_module, num_config_ids),
1125+
.parse = avs_parse_byte_token,
1126+
},
1127+
};
1128+
1129+
static const struct avs_tplg_token_parser init_config_parsers[] = {
1130+
{
1131+
.token = AVS_TKN_MOD_INIT_CONFIG_ID_U32,
1132+
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
1133+
.offset = 0,
1134+
.parse = avs_parse_word_token,
1135+
},
11211136
};
11221137

11231138
static struct avs_tplg_module *
11241139
avs_tplg_module_create(struct snd_soc_component *comp, struct avs_tplg_pipeline *owner,
11251140
struct snd_soc_tplg_vendor_array *tuples, u32 block_size)
11261141
{
11271142
struct avs_tplg_module *module;
1143+
u32 esize;
11281144
int ret;
11291145

1146+
/* See where config id block starts. */
1147+
ret = avs_tplg_vendor_entry_size(tuples, block_size,
1148+
AVS_TKN_MOD_INIT_CONFIG_ID_U32, &esize);
1149+
if (ret)
1150+
return ERR_PTR(ret);
1151+
11301152
module = devm_kzalloc(comp->card->dev, sizeof(*module), GFP_KERNEL);
11311153
if (!module)
11321154
return ERR_PTR(-ENOMEM);
11331155

11341156
ret = avs_parse_tokens(comp, module, module_parsers,
1135-
ARRAY_SIZE(module_parsers), tuples, block_size);
1157+
ARRAY_SIZE(module_parsers), tuples, esize);
11361158
if (ret < 0)
11371159
return ERR_PTR(ret);
11381160

1161+
block_size -= esize;
1162+
/* Parse trailing config ids if any. */
1163+
if (block_size) {
1164+
u32 num_config_ids = module->num_config_ids;
1165+
u32 *config_ids;
1166+
1167+
if (!num_config_ids)
1168+
return ERR_PTR(-EINVAL);
1169+
1170+
config_ids = devm_kcalloc(comp->card->dev, num_config_ids, sizeof(*config_ids),
1171+
GFP_KERNEL);
1172+
if (!config_ids)
1173+
return ERR_PTR(-ENOMEM);
1174+
1175+
tuples = avs_tplg_vendor_array_at(tuples, esize);
1176+
ret = parse_dictionary_entries(comp, tuples, block_size,
1177+
config_ids, num_config_ids, sizeof(*config_ids),
1178+
AVS_TKN_MOD_INIT_CONFIG_ID_U32,
1179+
init_config_parsers,
1180+
ARRAY_SIZE(init_config_parsers));
1181+
if (ret)
1182+
return ERR_PTR(ret);
1183+
1184+
module->config_ids = config_ids;
1185+
}
1186+
11391187
module->owner = owner;
11401188
INIT_LIST_HEAD(&module->node);
11411189

@@ -1416,6 +1464,82 @@ avs_tplg_path_template_create(struct snd_soc_component *comp, struct avs_tplg *o
14161464
return template;
14171465
}
14181466

1467+
static const struct avs_tplg_token_parser mod_init_config_parsers[] = {
1468+
{
1469+
.token = AVS_TKN_MOD_INIT_CONFIG_ID_U32,
1470+
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
1471+
.offset = offsetof(struct avs_tplg_init_config, id),
1472+
.parse = avs_parse_word_token,
1473+
},
1474+
{
1475+
.token = AVS_TKN_INIT_CONFIG_PARAM_U8,
1476+
.type = SND_SOC_TPLG_TUPLE_TYPE_BYTE,
1477+
.offset = offsetof(struct avs_tplg_init_config, param),
1478+
.parse = avs_parse_byte_token,
1479+
},
1480+
{
1481+
.token = AVS_TKN_INIT_CONFIG_LENGTH_U32,
1482+
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
1483+
.offset = offsetof(struct avs_tplg_init_config, length),
1484+
.parse = avs_parse_word_token,
1485+
},
1486+
};
1487+
1488+
static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp,
1489+
struct snd_soc_tplg_vendor_array *tuples,
1490+
u32 block_size)
1491+
{
1492+
struct avs_soc_component *acomp = to_avs_soc_component(comp);
1493+
struct avs_tplg *tplg = acomp->tplg;
1494+
int ret, i;
1495+
1496+
/* Parse tuple section telling how many init configs there are. */
1497+
ret = parse_dictionary_header(comp, tuples, (void **)&tplg->init_configs,
1498+
&tplg->num_init_configs,
1499+
sizeof(*tplg->init_configs),
1500+
AVS_TKN_MANIFEST_NUM_INIT_CONFIGS_U32);
1501+
if (ret)
1502+
return ret;
1503+
1504+
block_size -= le32_to_cpu(tuples->size);
1505+
/* With header parsed, move on to parsing entries. */
1506+
tuples = avs_tplg_vendor_array_next(tuples);
1507+
1508+
for (i = 0; i < tplg->num_init_configs && block_size > 0; i++) {
1509+
struct avs_tplg_init_config *config = &tplg->init_configs[i];
1510+
struct snd_soc_tplg_vendor_array *tmp;
1511+
void *init_config_data;
1512+
u32 esize;
1513+
1514+
/*
1515+
* Usually to get section length we search for first token of next group of data,
1516+
* but in this case we can't as tuples are followed by raw data.
1517+
*/
1518+
tmp = avs_tplg_vendor_array_next(tuples);
1519+
esize = le32_to_cpu(tuples->size) + le32_to_cpu(tmp->size);
1520+
1521+
ret = parse_dictionary_entries(comp, tuples, esize, config, 1, sizeof(*config),
1522+
AVS_TKN_MOD_INIT_CONFIG_ID_U32,
1523+
mod_init_config_parsers,
1524+
ARRAY_SIZE(mod_init_config_parsers));
1525+
1526+
block_size -= esize;
1527+
1528+
/* handle raw data section */
1529+
init_config_data = (void *)tuples + esize;
1530+
esize = config->length;
1531+
1532+
config->data = devm_kmemdup(comp->card->dev, init_config_data, esize, GFP_KERNEL);
1533+
if (!config->data)
1534+
return -ENOMEM;
1535+
1536+
tuples = init_config_data + esize;
1537+
block_size -= esize;
1538+
}
1539+
1540+
return 0;
1541+
}
1542+
14191543
static int avs_route_load(struct snd_soc_component *comp, int index,
14201544
struct snd_soc_dapm_route *route)
14211545
{
@@ -1571,6 +1695,7 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
15711695
struct snd_soc_tplg_vendor_array *tuples = manifest->priv.array;
15721696
struct avs_soc_component *acomp = to_avs_soc_component(comp);
15731697
size_t remaining = le32_to_cpu(manifest->priv.size);
1698+
bool has_init_config = true;
15741699
u32 offset;
15751700
int ret;
15761701

@@ -1668,8 +1793,43 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
16681793
remaining -= offset;
16691794
tuples = avs_tplg_vendor_array_at(tuples, offset);
16701795

1796+
ret = avs_tplg_vendor_array_lookup(tuples, remaining,
1797+
AVS_TKN_MANIFEST_NUM_CONDPATH_TMPLS_U32, &offset);
1798+
if (ret) {
1799+
dev_err(comp->dev, "condpath lookup failed: %d\n", ret);
1800+
return ret;
1801+
}
1802+
16711803
/* Bindings dictionary. */
1672-
return avs_tplg_parse_bindings(comp, tuples, remaining);
1804+
ret = avs_tplg_parse_bindings(comp, tuples, offset);
1805+
if (ret < 0)
1806+
return ret;
1807+
1808+
remaining -= offset;
1809+
tuples = avs_tplg_vendor_array_at(tuples, offset);
1810+
1811+
ret = avs_tplg_vendor_array_lookup(tuples, remaining,
1812+
AVS_TKN_MANIFEST_NUM_INIT_CONFIGS_U32, &offset);
1813+
if (ret == -ENOENT) {
1814+
dev_dbg(comp->dev, "init config lookup failed: %d\n", ret);
1815+
has_init_config = false;
1816+
} else if (ret) {
1817+
dev_err(comp->dev, "init config lookup failed: %d\n", ret);
1818+
return ret;
1819+
}
1820+
1821+
if (!has_init_config)
1822+
return 0;
1823+
1824+
remaining -= offset;
1825+
tuples = avs_tplg_vendor_array_at(tuples, offset);
1826+
1827+
/* Initial configs dictionary. */
1828+
ret = avs_tplg_parse_initial_configs(comp, tuples, remaining);
1829+
if (ret < 0)
1830+
return ret;
1831+
1832+
return 0;
16731833
}
16741834

16751835
#define AVS_CONTROL_OPS_VOLUME 257

sound/soc/intel/avs/topology.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ struct avs_tplg {
3333
u32 num_pplcfgs;
3434
struct avs_tplg_binding *bindings;
3535
u32 num_bindings;
36+
u32 num_condpath_tmpls;
37+
struct avs_tplg_init_config *init_configs;
38+
u32 num_init_configs;
3639

3740
struct list_head path_tmpl_list;
3841
};
@@ -147,6 +150,14 @@ struct avs_tplg_path_template {
147150
struct list_head node;
148151
};
149152

153+
struct avs_tplg_init_config {
154+
u32 id;
155+
156+
u8 param;
157+
size_t length;
158+
void *data;
159+
};
160+
150161
struct avs_tplg_path {
151162
u32 id;
152163

@@ -183,6 +194,8 @@ struct avs_tplg_module {
183194
u8 domain;
184195
struct avs_tplg_modcfg_ext *cfg_ext;
185196
u32 ctl_id;
197+
u32 num_config_ids;
198+
u32 *config_ids;
186199

187200
struct avs_tplg_pipeline *owner;
188201
/* Pipeline modules management. */

0 commit comments

Comments
 (0)