ASoC: tegra: Fix PCM and Compress device IDs

DAI links are getting parsed in a reverse order with Kernel OOT,
where the DAI link nodes are now defined in overlays which gets
applied to the upstream DTB. Due to this PCM and compress devices
get a very large number which makes existing applications fail.

This seems to be expected as the overlay subnodes are merged just
after the parent properties. Each subnode comes just after the
properties. Because of this the later merged subnodes come before
the earlier merged nodes and eventually the DAI link nodes, in
this case, get reversed.

Given above it would be better to not assume DAI link node order.
To fix this use full name of DAI link nodes and identify the DAI
link index from it during parsing in kernel. The DAI link nodes
are named as 'nvidia-audio-card,dai-link@<xxx>', where <xxx>
signifies link index. Parse this info and store it under DAI link
ID. With this the PCM and Compress device IDs do not depend anymore
on the parsing order of DAI links.

Bug 3583581

Change-Id: I3d0e7ed9fb0edfe1f066e12527b44a85c2716df0
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2776061
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Sameer Pujar
2022-10-16 06:02:15 +00:00
committed by mobile promotions
parent 541420a420
commit 19292f7cb8
3 changed files with 30 additions and 3 deletions

View File

@@ -1174,6 +1174,7 @@ static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
.close = tegra_pcm_close, .close = tegra_pcm_close,
.hw_params = tegra_pcm_hw_params, .hw_params = tegra_pcm_hw_params,
.pointer = tegra_pcm_pointer, .pointer = tegra_pcm_pointer,
.use_dai_pcm_id = 1,
}; };
static const struct snd_soc_component_driver tegra186_admaif_cmpnt = { static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
@@ -1188,6 +1189,7 @@ static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
.close = tegra_pcm_close, .close = tegra_pcm_close,
.hw_params = tegra_pcm_hw_params, .hw_params = tegra_pcm_hw_params,
.pointer = tegra_pcm_pointer, .pointer = tegra_pcm_pointer,
.use_dai_pcm_id = 1,
}; };
static const struct tegra_admaif_soc_data soc_data_tegra210 = { static const struct tegra_admaif_soc_data soc_data_tegra210 = {

View File

@@ -3,7 +3,7 @@
* tegra210_adsp.c - Tegra ADSP audio driver * tegra210_adsp.c - Tegra ADSP audio driver
* *
* Author: Sumit Bhattacharya <sumitb@nvidia.com> * Author: Sumit Bhattacharya <sumitb@nvidia.com>
* Copyright (c) 2014-2021 NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2014-2022 NVIDIA CORPORATION. All rights reserved.
* *
*/ */
@@ -4438,6 +4438,8 @@ static struct snd_soc_component_driver tegra210_adsp_cmpnt = {
.compress_ops = &tegra210_adsp_compress_ops, .compress_ops = &tegra210_adsp_compress_ops,
.read = tegra210_adsp_read, .read = tegra210_adsp_read,
.write = tegra210_adsp_write, .write = tegra210_adsp_write,
.use_dai_pcm_id = 1,
}; };
static u64 tegra_dma_mask = DMA_BIT_MASK(32); static u64 tegra_dma_mask = DMA_BIT_MASK(32);

View File

@@ -2,7 +2,7 @@
/* /*
* tegra_asoc_machine.c - Tegra DAI links parser * tegra_asoc_machine.c - Tegra DAI links parser
* *
* Copyright (c) 2014-2021 NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2014-2022 NVIDIA CORPORATION. All rights reserved.
* *
*/ */
@@ -424,6 +424,7 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
struct device_node *codec = NULL, *cpu = NULL; struct device_node *codec = NULL, *cpu = NULL;
struct snd_soc_dai_link *dai_link; struct snd_soc_dai_link *dai_link;
int link_type = 0, codec_count = 0; int link_type = 0, codec_count = 0;
char *link_addr;
if (!of_dai_link_is_available(link_node)) { if (!of_dai_link_is_available(link_node)) {
link_node = of_get_next_child(top, link_node); link_node = of_get_next_child(top, link_node);
@@ -505,6 +506,28 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
goto cleanup; goto cleanup;
} }
/*
* Assign DAI link ID based on DT link address.
* This is done to use consistent PCM/Compress device
* IDs irrespective of parsing order of DT DAI links.
*/
link_addr = strrchr(link_node->full_name, '@');
if (!link_addr) {
dev_err(&pdev->dev,
"Invalid link node (%pOF)\n",
link_node);
ret = -EINVAL;
goto cleanup;
}
ret = kstrtos32(++link_addr, 10, &dai_link->id);
if (ret < 0) {
dev_err(&pdev->dev,
"Failed to get link node (%pOF) ID\n",
link_node);
goto cleanup;
}
link_count++; link_count++;
codec_count++; codec_count++;
} }
@@ -544,7 +567,7 @@ int parse_card_info(struct snd_soc_card *card, struct snd_soc_ops *pcm_ops,
return ret; return ret;
} }
/* /*str
* Below property of routing map is required only when there * Below property of routing map is required only when there
* are DAPM input/output widgets available for external codec, * are DAPM input/output widgets available for external codec,
* which require them to be connected to machine source/sink * which require them to be connected to machine source/sink