Lines Matching +full:comp +full:- +full:int
1 // SPDX-License-Identifier: GPL-2.0-only
12 #include <sound/soc-acpi.h>
13 #include <sound/soc-topology.h>
26 (avs_tplg_vendor_array_at(array, le32_to_cpu((array)->size)))
33 * Returns 0 on success, -ENOENT if not found and error code otherwise.
35 static int
43 u32 tuples_size = le32_to_cpu(tuples->size);
46 return -EINVAL;
48 tuple = tuples->value;
49 if (le32_to_cpu(tuple->token) == token) {
54 block_size -= tuples_size;
59 return -ENOENT;
71 static int
75 u32 tuples_size = le32_to_cpu(tuples->size);
76 int ret;
79 return -EINVAL;
82 block_size -= tuples_size;
100 static int
104 int ret;
107 if (ret == -ENOENT) {
127 int (*parse)(struct snd_soc_component *comp, void *elem, void *object, u32 offset);
130 static int
131 avs_parse_uuid_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
136 guid_copy((guid_t *)val, (const guid_t *)&tuple->uuid);
141 static int
142 avs_parse_bool_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
147 *val = le32_to_cpu(tuple->value);
152 static int
153 avs_parse_byte_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
158 *val = le32_to_cpu(tuple->value);
163 static int
164 avs_parse_short_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
169 *val = le32_to_cpu(tuple->value);
174 static int
175 avs_parse_word_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
180 *val = le32_to_cpu(tuple->value);
185 static int
186 avs_parse_string_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
191 snprintf(val, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s", tuple->string);
196 static int avs_parse_uuid_tokens(struct snd_soc_component *comp, void *object,
197 const struct avs_tplg_token_parser *parsers, int count,
201 int ret, i, j;
204 for (i = 0; i < le32_to_cpu(tuples->num_elems); i++) {
205 tuple = &tuples->uuid[i];
208 /* Ignore non-UUID tokens. */
210 parsers[j].token != le32_to_cpu(tuple->token))
213 ret = parsers[j].parse(comp, tuple, object, parsers[j].offset);
222 static int avs_parse_string_tokens(struct snd_soc_component *comp, void *object,
223 const struct avs_tplg_token_parser *parsers, int count,
227 int ret, i, j;
230 for (i = 0; i < le32_to_cpu(tuples->num_elems); i++) {
231 tuple = &tuples->string[i];
234 /* Ignore non-string tokens. */
236 parsers[j].token != le32_to_cpu(tuple->token))
239 ret = parsers[j].parse(comp, tuple, object, parsers[j].offset);
248 static int avs_parse_word_tokens(struct snd_soc_component *comp, void *object,
249 const struct avs_tplg_token_parser *parsers, int count,
253 int ret, i, j;
256 for (i = 0; i < le32_to_cpu(tuples->num_elems); i++) {
257 tuple = &tuples->value[i];
260 /* Ignore non-integer tokens. */
267 if (parsers[j].token != le32_to_cpu(tuple->token))
270 ret = parsers[j].parse(comp, tuple, object, parsers[j].offset);
279 static int avs_parse_tokens(struct snd_soc_component *comp, void *object,
281 struct snd_soc_tplg_vendor_array *tuples, int priv_size)
283 int array_size, ret;
286 array_size = le32_to_cpu(tuples->size);
289 dev_err(comp->dev, "invalid array size 0x%x\n", array_size);
290 return -EINVAL;
294 priv_size -= array_size;
296 dev_err(comp->dev, "invalid array size 0x%x\n", array_size);
297 return -EINVAL;
300 switch (le32_to_cpu(tuples->type)) {
302 ret = avs_parse_uuid_tokens(comp, object, parsers, count, tuples);
305 ret = avs_parse_string_tokens(comp, object, parsers, count, tuples);
311 ret = avs_parse_word_tokens(comp, object, parsers, count, tuples);
314 dev_err(comp->dev, "unknown token type %d\n", tuples->type);
315 ret = -EINVAL;
319 dev_err(comp->dev, "parsing %zu tokens of %d type failed: %d\n",
320 count, tuples->type, ret);
331 static int \
332 avs_parse_##name##_ptr(struct snd_soc_component *comp, void *elem, void *object, u32 offset) \
335 struct avs_soc_component *acomp = to_avs_soc_component(comp); \
339 idx = le32_to_cpu(tuple->value); \
340 if (idx >= acomp->tplg->num_##member) \
341 return -EINVAL; \
343 *val = &acomp->tplg->member[idx]; \
354 static int
355 parse_audio_format_bitfield(struct snd_soc_component *comp, void *elem, void *object, u32 offset)
362 audio_format->num_channels = le32_to_cpu(velem->value);
365 audio_format->valid_bit_depth = le32_to_cpu(velem->value);
368 audio_format->sample_type = le32_to_cpu(velem->value);
375 static int avs_ssp_sprint(char *buf, size_t size, const char *fmt, int port, int tdm)
378 int retsize;
386 retsize = scnprintf(buf, min_t(size_t, size, needle - fmt + 1), "%s", fmt);
387 retsize += scnprintf(buf + retsize, size - retsize, "%d", port);
389 retsize += scnprintf(buf + retsize, size - retsize, ":%d", tdm);
390 retsize += scnprintf(buf + retsize, size - retsize, "%s", needle + 2);
397 static int parse_link_formatted_string(struct snd_soc_component *comp, void *elem,
401 struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
403 int ssp_port, tdm_slot;
406 * Dynamic naming - string formats, e.g.: ssp%d - supported only for
410 return avs_parse_string_token(comp, elem, object, offset);
414 return avs_parse_string_token(comp, elem, object, offset);
418 avs_ssp_sprint(val, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, tuple->string, ssp_port, tdm_slot);
423 static int
424 parse_dictionary_header(struct snd_soc_component *comp,
431 /* Dictionary header consists of single tuple - entry count. */
432 tuple = tuples->value;
433 if (le32_to_cpu(tuple->token) != num_entries_token) {
434 dev_err(comp->dev, "invalid dictionary header, expected: %d\n",
436 return -EINVAL;
439 *num_entries = le32_to_cpu(tuple->value);
440 *dict = devm_kcalloc(comp->card->dev, *num_entries, entry_size, GFP_KERNEL);
442 return -ENOMEM;
447 static int
448 parse_dictionary_entries(struct snd_soc_component *comp,
455 int i;
459 int ret;
466 ret = avs_parse_tokens(comp, pos, parsers, num_parsers, tuples, esize);
468 dev_err(comp->dev, "parse entry: %d of type: %d failed: %d\n",
474 block_size -= esize;
481 static int parse_dictionary(struct snd_soc_component *comp,
487 int ret;
489 ret = parse_dictionary_header(comp, tuples, dict, num_entries,
494 block_size -= le32_to_cpu(tuples->size);
498 return parse_dictionary_entries(comp, tuples, block_size, *dict,
512 static int avs_tplg_parse_libraries(struct snd_soc_component *comp,
515 struct avs_soc_component *acomp = to_avs_soc_component(comp);
516 struct avs_tplg *tplg = acomp->tplg;
518 return parse_dictionary(comp, tuples, block_size, (void **)&tplg->libs,
519 &tplg->num_libs, sizeof(*tplg->libs),
576 static int avs_tplg_parse_audio_formats(struct snd_soc_component *comp,
580 struct avs_soc_component *acomp = to_avs_soc_component(comp);
581 struct avs_tplg *tplg = acomp->tplg;
583 return parse_dictionary(comp, tuples, block_size, (void **)&tplg->fmts,
584 &tplg->num_fmts, sizeof(*tplg->fmts),
617 static int avs_tplg_parse_modcfgs_base(struct snd_soc_component *comp,
621 struct avs_soc_component *acomp = to_avs_soc_component(comp);
622 struct avs_tplg *tplg = acomp->tplg;
624 return parse_dictionary(comp, tuples, block_size, (void **)&tplg->modcfgs_base,
625 &tplg->num_modcfgs_base, sizeof(*tplg->modcfgs_base),
842 assign_copier_gtw_instance(struct snd_soc_component *comp, struct avs_tplg_modcfg_ext *cfg)
845 int ssp_port, tdm_slot;
847 if (!guid_equal(&cfg->type, &AVS_COPIER_MOD_UUID))
850 /* Only I2S boards assign port instance in ->i2s_link_mask. */
851 switch (cfg->copier.dma_type) {
860 if (cfg->copier.vindex.val)
863 mach = dev_get_platdata(comp->card->dev);
873 cfg->copier.vindex.i2s.instance = ssp_port;
874 cfg->copier.vindex.i2s.time_slot = tdm_slot;
877 static int avs_tplg_parse_modcfg_ext(struct snd_soc_component *comp,
883 int ret;
891 ret = avs_parse_tokens(comp, cfg, modcfg_ext_parsers,
897 assign_copier_gtw_instance(comp, cfg);
899 block_size -= esize;
905 num_pins = cfg->generic.num_input_pins + cfg->generic.num_output_pins;
907 return -EINVAL;
909 pins = devm_kcalloc(comp->card->dev, num_pins, sizeof(*pins), GFP_KERNEL);
911 return -ENOMEM;
914 ret = parse_dictionary_entries(comp, tuples, block_size,
921 cfg->generic.pin_fmts = pins;
927 static int avs_tplg_parse_modcfgs_ext(struct snd_soc_component *comp,
931 struct avs_soc_component *acomp = to_avs_soc_component(comp);
932 struct avs_tplg *tplg = acomp->tplg;
933 int ret, i;
935 ret = parse_dictionary_header(comp, tuples, (void **)&tplg->modcfgs_ext,
936 &tplg->num_modcfgs_ext,
937 sizeof(*tplg->modcfgs_ext),
942 block_size -= le32_to_cpu(tuples->size);
946 for (i = 0; i < tplg->num_modcfgs_ext; i++) {
947 struct avs_tplg_modcfg_ext *cfg = &tplg->modcfgs_ext[i];
955 ret = avs_tplg_parse_modcfg_ext(comp, cfg, tuples, esize);
959 block_size -= esize;
999 static int avs_tplg_parse_pplcfgs(struct snd_soc_component *comp,
1003 struct avs_soc_component *acomp = to_avs_soc_component(comp);
1004 struct avs_tplg *tplg = acomp->tplg;
1006 return parse_dictionary(comp, tuples, block_size, (void **)&tplg->pplcfgs,
1007 &tplg->num_pplcfgs, sizeof(*tplg->pplcfgs),
1064 static int avs_tplg_parse_bindings(struct snd_soc_component *comp,
1068 struct avs_soc_component *acomp = to_avs_soc_component(comp);
1069 struct avs_tplg *tplg = acomp->tplg;
1071 return parse_dictionary(comp, tuples, block_size, (void **)&tplg->bindings,
1072 &tplg->num_bindings, sizeof(*tplg->bindings),
1139 avs_tplg_module_create(struct snd_soc_component *comp, struct avs_tplg_pipeline *owner,
1144 int ret;
1152 module = devm_kzalloc(comp->card->dev, sizeof(*module), GFP_KERNEL);
1154 return ERR_PTR(-ENOMEM);
1156 ret = avs_parse_tokens(comp, module, module_parsers,
1161 block_size -= esize;
1164 u32 num_config_ids = module->num_config_ids;
1168 return ERR_PTR(-EINVAL);
1170 config_ids = devm_kcalloc(comp->card->dev, num_config_ids, sizeof(*config_ids),
1173 return ERR_PTR(-ENOMEM);
1176 ret = parse_dictionary_entries(comp, tuples, block_size,
1184 module->config_ids = config_ids;
1187 module->owner = owner;
1188 INIT_LIST_HEAD(&module->node);
1218 .offset = 0, /* to treat pipeline->bindings as dictionary */
1224 avs_tplg_pipeline_create(struct snd_soc_component *comp, struct avs_tplg_path *owner,
1229 int ret;
1231 pipeline = devm_kzalloc(comp->card->dev, sizeof(*pipeline), GFP_KERNEL);
1233 return ERR_PTR(-ENOMEM);
1235 pipeline->owner = owner;
1236 INIT_LIST_HEAD(&pipeline->mod_list);
1242 ret = -EINVAL;
1247 ret = avs_parse_tokens(comp, pipeline, pipeline_parsers,
1252 block_size -= offset;
1259 if (ret != -ENOENT)
1263 if (pipeline->num_bindings)
1264 return ERR_PTR(-EINVAL);
1268 pipeline->bindings = devm_kcalloc(comp->card->dev, pipeline->num_bindings,
1269 sizeof(*pipeline->bindings), GFP_KERNEL);
1270 if (!pipeline->bindings)
1271 return ERR_PTR(-ENOMEM);
1276 block_size -= modblk_size;
1286 module = avs_tplg_module_create(comp, pipeline, tuples, esize);
1288 dev_err(comp->dev, "parse module failed: %ld\n",
1293 list_add_tail(&module->node, &pipeline->mod_list);
1294 modblk_size -= esize;
1299 ret = parse_dictionary_entries(comp, tuples, block_size, pipeline->bindings,
1300 pipeline->num_bindings, sizeof(*pipeline->bindings),
1331 avs_tplg_path_create(struct snd_soc_component *comp, struct avs_tplg_path_template *owner,
1338 int ret;
1340 path = devm_kzalloc(comp->card->dev, sizeof(*path), GFP_KERNEL);
1342 return ERR_PTR(-ENOMEM);
1344 path->owner = owner;
1345 INIT_LIST_HEAD(&path->ppl_list);
1346 INIT_LIST_HEAD(&path->node);
1351 if (ret == -ENOENT)
1356 return ERR_PTR(-EINVAL);
1359 ret = avs_parse_tokens(comp, path, parsers, num_parsers, tuples, offset);
1363 block_size -= offset;
1373 pipeline = avs_tplg_pipeline_create(comp, path, tuples, esize);
1375 dev_err(comp->dev, "parse pipeline failed: %ld\n",
1380 list_add_tail(&pipeline->node, &path->ppl_list);
1381 block_size -= esize;
1397 static int parse_path_template(struct snd_soc_component *comp,
1405 int ret;
1414 ret = avs_parse_tokens(comp, template, tmpl_tokens, num_tmpl_tokens, tuples, offset);
1418 block_size -= offset;
1428 path = avs_tplg_path_create(comp, template, tuples, esize, path_tokens,
1431 dev_err(comp->dev, "parse path failed: %ld\n", PTR_ERR(path));
1435 list_add_tail(&path->node, &template->path_list);
1436 block_size -= esize;
1444 avs_tplg_path_template_create(struct snd_soc_component *comp, struct avs_tplg *owner,
1448 int ret;
1450 template = devm_kzalloc(comp->card->dev, sizeof(*template), GFP_KERNEL);
1452 return ERR_PTR(-ENOMEM);
1454 template->owner = owner; /* Used to access component tplg is assigned to. */
1455 INIT_LIST_HEAD(&template->path_list);
1456 INIT_LIST_HEAD(&template->node);
1458 ret = parse_path_template(comp, tuples, block_size, template, path_tmpl_parsers,
1488 static int avs_tplg_parse_initial_configs(struct snd_soc_component *comp,
1492 struct avs_soc_component *acomp = to_avs_soc_component(comp);
1493 struct avs_tplg *tplg = acomp->tplg;
1494 int ret, i;
1497 ret = parse_dictionary_header(comp, tuples, (void **)&tplg->init_configs,
1498 &tplg->num_init_configs,
1499 sizeof(*tplg->init_configs),
1504 block_size -= le32_to_cpu(tuples->size);
1508 for (i = 0; i < tplg->num_init_configs && block_size > 0; i++) {
1509 struct avs_tplg_init_config *config = &tplg->init_configs[i];
1519 esize = le32_to_cpu(tuples->size) + le32_to_cpu(tmp->size);
1521 ret = parse_dictionary_entries(comp, tuples, esize, config, 1, sizeof(*config),
1526 block_size -= esize;
1530 esize = config->length;
1532 config->data = devm_kmemdup(comp->card->dev, init_config_data, esize, GFP_KERNEL);
1533 if (!config->data)
1534 return -ENOMEM;
1537 block_size -= esize;
1543 static int avs_route_load(struct snd_soc_component *comp, int index,
1546 struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev);
1548 int ssp_port, tdm_slot;
1560 buf = devm_kzalloc(comp->card->dev, len, GFP_KERNEL);
1562 return -ENOMEM;
1563 avs_ssp_sprint(buf, len, route->source, ssp_port, tdm_slot);
1564 route->source = buf;
1566 buf = devm_kzalloc(comp->card->dev, len, GFP_KERNEL);
1568 return -ENOMEM;
1569 avs_ssp_sprint(buf, len, route->sink, ssp_port, tdm_slot);
1570 route->sink = buf;
1572 if (route->control) {
1573 buf = devm_kzalloc(comp->card->dev, len, GFP_KERNEL);
1575 return -ENOMEM;
1576 avs_ssp_sprint(buf, len, route->control, ssp_port, tdm_slot);
1577 route->control = buf;
1583 static int avs_widget_load(struct snd_soc_component *comp, int index,
1589 struct avs_soc_component *acomp = to_avs_soc_component(comp);
1591 int ssp_port, tdm_slot;
1593 if (!le32_to_cpu(dw->priv.size))
1596 w->no_wname_in_kcontrol_name = true;
1598 if (w->ignore_suspend && !AVS_S0IX_SUPPORTED) {
1599 dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n");
1600 w->ignore_suspend = false;
1603 tplg = acomp->tplg;
1604 mach = dev_get_platdata(comp->card->dev);
1611 /* size is based on possible %d -> SSP:TDM, where SSP and TDM < 10 + '\0' */
1612 size_t size = strlen(dw->name) + 2;
1619 return -ENOMEM;
1620 avs_ssp_sprint(buf, size, dw->name, ssp_port, tdm_slot);
1621 kfree(w->name);
1622 /* w->name is freed later by soc_tplg_dapm_widget_create() */
1623 w->name = buf;
1627 template = avs_tplg_path_template_create(comp, tplg, dw->priv.array,
1628 le32_to_cpu(dw->priv.size));
1630 dev_err(comp->dev, "widget %s load failed: %ld\n", dw->name,
1635 w->priv = template; /* link path information to widget */
1636 list_add_tail(&template->node, &tplg->path_tmpl_list);
1640 static int avs_widget_ready(struct snd_soc_component *comp, int index,
1644 struct avs_tplg_path_template *template = w->priv;
1646 template->w = w;
1650 static int avs_dai_load(struct snd_soc_component *comp, int index,
1659 dai_drv->ops = &avs_dai_fe_ops;
1660 dai_drv->capture.subformats = fe_subformats;
1661 dai_drv->playback.subformats = fe_subformats;
1667 static int avs_link_load(struct snd_soc_component *comp, int index, struct snd_soc_dai_link *link,
1670 if (link->ignore_suspend && !AVS_S0IX_SUPPORTED) {
1671 dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n");
1672 link->ignore_suspend = false;
1675 if (!link->no_pcm) {
1677 link->nonatomic = true;
1680 link->trigger[0] = SND_SOC_DPCM_TRIGGER_PRE;
1681 link->trigger[1] = SND_SOC_DPCM_TRIGGER_PRE;
1684 link->dpcm_merged_format = 1;
1705 static int avs_manifest(struct snd_soc_component *comp, int index,
1708 struct snd_soc_tplg_vendor_array *tuples = manifest->priv.array;
1709 struct avs_soc_component *acomp = to_avs_soc_component(comp);
1710 size_t remaining = le32_to_cpu(manifest->priv.size);
1713 int ret;
1719 ret = -EINVAL;
1721 dev_err(comp->dev, "incorrect manifest format: %d\n", ret);
1726 ret = avs_parse_tokens(comp, acomp->tplg, manifest_parsers,
1731 remaining -= offset;
1737 dev_err(comp->dev, "audio formats lookup failed: %d\n", ret);
1742 ret = avs_tplg_parse_libraries(comp, tuples, offset);
1746 remaining -= offset;
1752 dev_err(comp->dev, "modcfgs_base lookup failed: %d\n", ret);
1757 ret = avs_tplg_parse_audio_formats(comp, tuples, offset);
1761 remaining -= offset;
1767 dev_err(comp->dev, "modcfgs_ext lookup failed: %d\n", ret);
1771 /* Module configs-base dictionary. */
1772 ret = avs_tplg_parse_modcfgs_base(comp, tuples, offset);
1776 remaining -= offset;
1782 dev_err(comp->dev, "pplcfgs lookup failed: %d\n", ret);
1786 /* Module configs-ext dictionary. */
1787 ret = avs_tplg_parse_modcfgs_ext(comp, tuples, offset);
1791 remaining -= offset;
1797 dev_err(comp->dev, "bindings lookup failed: %d\n", ret);
1802 ret = avs_tplg_parse_pplcfgs(comp, tuples, offset);
1806 remaining -= offset;
1812 dev_err(comp->dev, "condpath lookup failed: %d\n", ret);
1817 ret = avs_tplg_parse_bindings(comp, tuples, offset);
1821 remaining -= offset;
1826 if (ret == -ENOENT) {
1827 dev_dbg(comp->dev, "init config lookup failed: %d\n", ret);
1830 dev_err(comp->dev, "init config lookup failed: %d\n", ret);
1837 remaining -= offset;
1841 ret = avs_tplg_parse_initial_configs(comp, tuples, remaining);
1867 static int
1868 avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_new *ctmpl,
1876 int ret;
1878 switch (le32_to_cpu(hdr->type)) {
1881 tuples = tmc->priv.array;
1882 block_size = le32_to_cpu(tmc->priv.size);
1885 return -EINVAL;
1888 ctl_data = devm_kzalloc(comp->card->dev, sizeof(*ctl_data), GFP_KERNEL);
1890 return -ENOMEM;
1892 ret = parse_dictionary_entries(comp, tuples, block_size, ctl_data, 1, sizeof(*ctl_data),
1898 mc = (struct soc_mixer_control *)ctmpl->private_value;
1899 mc->dobj.private = ctl_data;
1915 struct avs_tplg *avs_tplg_new(struct snd_soc_component *comp)
1919 tplg = devm_kzalloc(comp->card->dev, sizeof(*tplg), GFP_KERNEL);
1923 tplg->comp = comp;
1924 INIT_LIST_HEAD(&tplg->path_tmpl_list);
1929 int avs_load_topology(struct snd_soc_component *comp, const char *filename)
1932 int ret;
1934 ret = request_firmware(&fw, filename, comp->dev);
1936 dev_err(comp->dev, "request topology \"%s\" failed: %d\n", filename, ret);
1940 ret = snd_soc_tplg_component_load(comp, &avs_tplg_ops, fw);
1942 dev_err(comp->dev, "load topology \"%s\" failed: %d\n", filename, ret);
1948 int avs_remove_topology(struct snd_soc_component *comp)
1950 snd_soc_tplg_component_remove(comp);