diff options
author | 2022-08-06 10:19:51 -0700 | |
---|---|---|
committer | 2022-08-06 10:19:51 -0700 | |
commit | 668c3c237f5ddc2889879b08f26d2374231f3287 (patch) | |
tree | c8db84c82cba2c0a9dd7a28c5c8bad99d7ffda3d /sound/soc/sof/topology.c | |
parent | Merge tag 'tpmdd-next-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd (diff) | |
parent | ALSA: hda/realtek: Add quirk for HP Spectre x360 15-eb0xxx (diff) | |
download | linux-rng-668c3c237f5ddc2889879b08f26d2374231f3287.tar.xz linux-rng-668c3c237f5ddc2889879b08f26d2374231f3287.zip |
Merge tag 'sound-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"As the diffstat shows, we've had lots of developments in a wide range
at this time; the majority of changes are about ASoC, including
subsystem-wide cleanups, continued SOF / Intel updates and a bunch of
new drivers (as usual), while there have been some significant (but
almost invisible) improvements in ALSA core side, too.
Below are some highlights:
Core:
- Faster lookups of control elements with Xarray; normal user won't
notice, but on the devices with tons of control elements, it can be
visibly faster
- Support for input validation for controls; this will harden for
badly written drivers in general with a slight overhead
- Deferred async signal handling for working around the potential
deadlocks
- Cleanup / refactoring raw MIDI locking code
ASoC:
- Restructing of the set_fmt() callbacks for making things clearer in
situations like CODEC to CODEC links
- Clean up and modernizing the DAI naming scheme setups
- Merge of more of the Intel AVS driver stack, including some board
integrations
- New version 4 mechanism for communication with SOF DSPs
- Suppoort for dynamically selecting the PLL to use at runtime on
i.MX platforms
- Improvements for CODEC to CODEC support in the generic cards
- Support for AMD Jadeite and various machines, AMD RPL, Intel
MetorLake DSPs, Mediatek MT8186 DSPs and MT6366, nVidia Tegra
MDDRC, OPE and PEQ, NXP TFA9890, Qualcomm SDM845, WCD9335 and
WAS883x, and Texas Instruments TAS2780
HD- and USB-audio:
- Continued improvement for CS35L41 (sub)codec support
- More quirks for various devices (HP, Lenovo, Dell, Clevo)"
* tag 'sound-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (778 commits)
ALSA: hda/realtek: Add quirk for HP Spectre x360 15-eb0xxx
ALSA: line6: Replace sprintf() with sysfs_emit()
ALSA: hda: Replace sprintf() with sysfs_emit()
ALSA: pcm: Replace sprintf() with sysfs_emit()
ALSA: core: Replace scnprintf() with sysfs_emit()
ALSA: control-led: Replace sprintf() with sysfs_emit()
ALSA: aoa: Replace sprintf() with sysfs_emit()
ALSA: ac97: Replace sprintf() with sysfs_emit()
ALSA: hda/realtek: Add quirk for Clevo NV45PZ
ALSA: hda/realtek: Add quirk for Lenovo Yoga9 14IAP7
ALSA: control: Use deferred fasync helper
ALSA: pcm: Use deferred fasync helper
ALSA: timer: Use deferred fasync helper
ALSA: core: Add async signal helpers
ASoC: q6asm: use kcalloc() instead of kzalloc()
ACPI: scan: Add CLSA0101 Laptop Support
ALSA: hda: cs35l41: Support CLSA0101
ALSA: hda: cs35l41: Use the CS35L41 HDA internal define
ASoC: dt-bindings: use spi-peripheral-props.yaml
ASoC: codecs: va-macro: use fsgen as clock
...
Diffstat (limited to 'sound/soc/sof/topology.c')
-rw-r--r-- | sound/soc/sof/topology.c | 121 |
1 files changed, 60 insertions, 61 deletions
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b1fcab7ce48e..9273a70fec25 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -36,9 +36,6 @@ #define TLV_STEP 1 #define TLV_MUTE 2 -/* size of tplg abi in byte */ -#define SOF_TPLG_ABI_SIZE 3 - /** * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the * token ID. @@ -1141,6 +1138,21 @@ static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm, return 0; } +static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples) +{ + int i; + + if (!tuples) + return -EINVAL; + + for (i = 0; i < num_tuples; i++) { + if (tuples[i].token == token_id) + return tuples[i].value.v; + } + + return -EINVAL; +} + static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget, struct snd_soc_tplg_dapm_widget *tw, enum sof_tokens *object_token_list, int count) @@ -1168,6 +1180,8 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s /* parse token list for widget */ for (i = 0; i < count; i++) { + int num_sets = 1; + if (object_token_list[i] >= SOF_TOKEN_COUNT) { dev_err(scomp->dev, "Invalid token id %d for widget %s\n", object_token_list[i], swidget->widget->name); @@ -1175,8 +1189,9 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s goto err; } - /* parse and save UUID in swidget */ - if (object_token_list[i] == SOF_COMP_EXT_TOKENS) { + switch (object_token_list[i]) { + case SOF_COMP_EXT_TOKENS: + /* parse and save UUID in swidget */ ret = sof_parse_tokens(scomp, swidget, token_list[object_token_list[i]].tokens, token_list[object_token_list[i]].count, @@ -1189,11 +1204,41 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s } continue; + case SOF_IN_AUDIO_FORMAT_TOKENS: + case SOF_OUT_AUDIO_FORMAT_TOKENS: + case SOF_COPIER_GATEWAY_CFG_TOKENS: + case SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS: + num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_AUDIO_FORMATS, + swidget->tuples, swidget->num_tuples); + + if (num_sets < 0) { + dev_err(sdev->dev, "Invalid audio format count for %s\n", + swidget->widget->name); + ret = num_sets; + goto err; + } + + if (num_sets > 1) { + struct snd_sof_tuple *new_tuples; + + num_tuples += token_list[object_token_list[i]].count * num_sets; + new_tuples = krealloc(swidget->tuples, + sizeof(*new_tuples) * num_tuples, GFP_KERNEL); + if (!new_tuples) { + ret = -ENOMEM; + goto err; + } + + swidget->tuples = new_tuples; + } + break; + default: + break; } /* copy one set of tuples per token ID into swidget->tuples */ ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), - object_token_list[i], 1, swidget->tuples, + object_token_list[i], num_sets, swidget->tuples, num_tuples, &swidget->num_tuples); if (ret < 0) { dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n", @@ -1208,21 +1253,6 @@ err: return ret; } -static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples) -{ - int i; - - if (!tuples) - return -EINVAL; - - for (i = 0; i < num_tuples; i++) { - if (tuples[i].token == token_id) - return tuples[i].value.v; - } - - return -EINVAL; -} - /* external widget init - used for any driver specific init */ static int sof_widget_ready(struct snd_soc_component *scomp, int index, struct snd_soc_dapm_widget *w, @@ -1389,7 +1419,6 @@ static int sof_widget_unload(struct snd_soc_component *scomp, struct soc_bytes_ext *sbe; struct snd_sof_dai *dai; struct soc_enum *se; - int ret = 0; int i; swidget = dobj->private; @@ -1450,7 +1479,7 @@ out: list_del(&swidget->list); kfree(swidget); - return ret; + return 0; } /* @@ -1709,6 +1738,10 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ token_id = SOF_AFE_TOKENS; num_tuples += token_list[SOF_AFE_TOKENS].count; break; + case SOF_DAI_AMD_DMIC: + token_id = SOF_ACPDMIC_TOKENS; + num_tuples += token_list[SOF_ACPDMIC_TOKENS].count; + break; default: break; } @@ -1987,45 +2020,11 @@ static int sof_complete(struct snd_soc_component *scomp) static int sof_manifest(struct snd_soc_component *scomp, int index, struct snd_soc_tplg_manifest *man) { - u32 size; - u32 abi_version; - - size = le32_to_cpu(man->priv.size); - - /* backward compatible with tplg without ABI info */ - if (!size) { - dev_dbg(scomp->dev, "No topology ABI info\n"); - return 0; - } - - if (size != SOF_TPLG_ABI_SIZE) { - dev_err(scomp->dev, "error: invalid topology ABI size\n"); - return -EINVAL; - } - - dev_info(scomp->dev, - "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", - man->priv.data[0], man->priv.data[1], - man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, - SOF_ABI_PATCH); - - abi_version = SOF_ABI_VER(man->priv.data[0], - man->priv.data[1], - man->priv.data[2]); - - if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { - dev_err(scomp->dev, "error: incompatible topology ABI version\n"); - return -EINVAL; - } + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; - if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { - dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n"); - } else { - dev_err(scomp->dev, "error: topology ABI is more recent than kernel\n"); - return -EINVAL; - } - } + if (ipc_tplg_ops->parse_manifest) + return ipc_tplg_ops->parse_manifest(scomp, index, man); return 0; } |