Revert "Revert "ASoC: tegra: Single cpu multi codec dai support""

This reverts commit 43ae0060cd.

Reason for revert: Fixed the build issue on sidecar branch

Bug 3772918

Change-Id: Ib02496f93fe79aec04f3b5b1c78a5681b1e56819
Signed-off-by: Mohan Kumar <mkumard@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2819603
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: Sharad Gupta <sharadg@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Mohan Kumar D
2022-11-30 22:09:55 -08:00
committed by mobile promotions
parent 3c67831fe8
commit f9d418aa6a
3 changed files with 133 additions and 160 deletions

View File

@@ -446,38 +446,6 @@ static struct snd_soc_dai_driver tegra186_dspk_dais[] = {
.ops = &tegra186_dspk_dai_ops,
.symmetric_rate = 1,
},
/* The second DAI is used when the output of the DSPK is connected
* to two mono codecs. When the output of the DSPK is connected to
* a single stereo codec, then only the first DAI should be used.
*/
{
.name = "CIF2",
.playback = {
.stream_name = "CIF2-Playback",
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
},
{
.name = "DAP2",
#if IS_ENABLED(CONFIG_TEGRA_DPCM)
.playback = {
.stream_name = "DAP2-Playback",
#else
.capture = {
.stream_name = "DAP2-Capture",
#endif
.channels_min = 1,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
.symmetric_rate = 1,
},
{
.name = "DUMMY_SINK",
.playback = {
@@ -493,7 +461,6 @@ static struct snd_soc_dai_driver tegra186_dspk_dais[] = {
static const struct snd_soc_dapm_widget tegra186_dspk_widgets[] = {
SND_SOC_DAPM_AIF_IN("RX", NULL, 0, TEGRA186_DSPK_ENABLE, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAP2 TX", NULL, 0, 0, 0, 0),
SND_SOC_DAPM_SPK("SPK", NULL),
};
@@ -507,8 +474,6 @@ static const struct snd_soc_dapm_route tegra186_dspk_routes[] = {
#else
{ "RX", NULL, "CIF-Playback" },
{ "DAP-Capture", NULL, "RX" },
{ "DAP2 TX", NULL, "CIF2-Playback" },
{ "DAP2-Capture", NULL, "DAP2 TX" },
{ "SPK", NULL, "Dummy-Playback" },
#endif
};

View File

@@ -97,7 +97,35 @@ static int get_num_dai_links(struct platform_device *pdev,
unsigned int *num_links)
{
struct device_node *top = pdev->dev.of_node;
struct device_node *link_node, *codec;
struct device_node *link_node;
unsigned int link_count = 0;
link_node = of_get_child_by_name(top, PREFIX "dai-link");
if (!link_node) {
dev_err(&pdev->dev, "no dai links found\n");
return -ENOENT;
}
do {
if (!of_dai_link_is_available(link_node)) {
link_node = of_get_next_child(top, link_node);
continue;
}
link_count++;
link_node = of_get_next_child(top, link_node);
} while (link_node);
*num_links = link_count;
return 0;
}
static int allocate_link_dais(struct platform_device *pdev,
struct snd_soc_dai_link *dai_links)
{
struct device_node *top = pdev->dev.of_node;
struct device_node *link_node;
unsigned int link_count = 0, num_codecs;
link_node = of_get_child_by_name(top, PREFIX "dai-link");
@@ -112,14 +140,14 @@ static int get_num_dai_links(struct platform_device *pdev,
continue;
}
/*
* depending on the number of codec subnodes, DAI link
* count is incremented. DT can have one DAI link entry
* with multiple codec nodes(for ex: DSPK), driver can
* create multiple links out of it.
*/
dai_links[link_count].cpus = devm_kzalloc(&pdev->dev,
sizeof(*dai_links[link_count].cpus),
GFP_KERNEL);
if (!dai_links[link_count].cpus)
return -ENOMEM;
num_codecs = of_get_child_count_with_name(link_node,
"codec");
"codec");
if (!num_codecs) {
of_node_put(link_node);
dev_err(&pdev->dev,
@@ -127,19 +155,28 @@ static int get_num_dai_links(struct platform_device *pdev,
return -EINVAL;
}
for_each_child_of_node(link_node, codec) {
if (of_node_cmp(codec->name, "codec"))
continue;
dai_links[link_count].codecs =
devm_kzalloc(&pdev->dev,
sizeof(*dai_links[link_count].codecs) * num_codecs,
GFP_KERNEL);
if (!dai_links[link_count].codecs)
return -ENOMEM;
if (of_property_read_bool(codec, DAI))
link_count++;
}
dai_links[link_count].platforms = devm_kzalloc(&pdev->dev,
sizeof(*dai_links[link_count].platforms),
GFP_KERNEL);
if (!dai_links[link_count].platforms)
return -ENOMEM;
dai_links[link_count].num_cpus = 1;
dai_links[link_count].num_codecs = num_codecs;
dai_links[link_count].num_platforms = 1;
link_count++;
link_node = of_get_next_child(top, link_node);
} while (link_node);
*num_links = link_count;
return 0;
}
@@ -372,7 +409,7 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
struct device_node *top = pdev->dev.of_node;
struct device_node *link_node;
struct snd_soc_dai_link *dai_links;
unsigned int num_links, link_count = 0, i;
unsigned int num_links, link_count = 0;
int ret;
ret = get_num_dai_links(pdev, &machine->asoc->num_links);
@@ -388,29 +425,9 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
if (!dai_links)
return -ENOMEM;
for (i = 0; i < num_links; i++) {
dai_links[i].cpus = devm_kzalloc(&pdev->dev,
sizeof(*dai_links[i].cpus),
GFP_KERNEL);
if (!dai_links[i].cpus)
return -ENOMEM;
dai_links[i].codecs = devm_kzalloc(&pdev->dev,
sizeof(*dai_links[i].codecs),
GFP_KERNEL);
if (!dai_links[i].codecs)
return -ENOMEM;
dai_links[i].platforms = devm_kzalloc(&pdev->dev,
sizeof(*dai_links[i].platforms),
GFP_KERNEL);
if (!dai_links[i].platforms)
return -ENOMEM;
dai_links[i].num_cpus = 1;
dai_links[i].num_codecs = 1;
dai_links[i].num_platforms = 1;
}
ret = allocate_link_dais(pdev, dai_links);
if (ret < 0)
return ret;
machine->asoc->dai_links = dai_links;
@@ -433,6 +450,7 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
dev_dbg(&pdev->dev, "parsing (%pOF)\n", link_node);
dai_link = &dai_links[link_count];
cpu = of_get_child_by_name(link_node, "cpu");
if (!cpu) {
dev_err(&pdev->dev, "cpu subnode is missing");
@@ -440,6 +458,11 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
goto cleanup;
}
/* parse CPU DAI */
ret = parse_dai(cpu, dai_link->cpus);
if (ret < 0)
goto cleanup;
for_each_child_of_node(link_node, codec) {
/* loop over codecs only */
if (of_node_cmp(codec->name, "codec"))
@@ -453,48 +476,43 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
continue;
}
dai_link = &dai_links[link_count];
/* parse CPU DAI */
ret = parse_dai(cpu, dai_link->cpus);
if (ret < 0)
goto cleanup;
/* parse CODEC DAI */
ret = parse_dai(codec, dai_link->codecs);
ret = parse_dai(codec, &dai_link->codecs[codec_count]);
if (ret < 0)
goto cleanup;
/* set DAI link name */
if (of_property_read_string_index(link_node,
"link-name",
codec_count,
&dai_link->name)) {
ret = asoc_simple_set_dailink_name(
&pdev->dev, dai_link, "%s-%d",
"tegra-dlink", link_count);
if (ret < 0)
goto cleanup;
}
codec_count++;
}
asoc_simple_parse_daifmt(&pdev->dev, link_node, codec,
NULL, &dai_link->dai_fmt);
/* set DAI link name */
if (of_property_read_string(link_node,
"link-name",
&dai_link->name)) {
ret = asoc_simple_set_dailink_name(
&pdev->dev, dai_link, "%s-%d",
"tegra-dlink", link_count);
if (ret < 0)
goto cleanup;
}
asoc_simple_canonicalize_platform(dai_link->platforms,
dai_link->cpus);
asoc_simple_parse_daifmt(&pdev->dev, link_node, codec,
NULL, &dai_link->dai_fmt);
of_property_read_u32(link_node, "link-type",
&link_type);
switch (link_type) {
case PCM_LINK:
dai_link->ops = pcm_ops;
break;
case COMPR_LINK:
dai_link->compr_ops = compr_ops;
break;
case C2C_LINK:
/* Parse DT provided link params */
ret = parse_dai_link_params(pdev, link_node,
asoc_simple_canonicalize_platform(dai_link->platforms,
dai_link->cpus);
of_property_read_u32(link_node, "link-type",
&link_type);
switch (link_type) {
case PCM_LINK:
dai_link->ops = pcm_ops;
break;
case COMPR_LINK:
dai_link->compr_ops = compr_ops;
break;
case C2C_LINK:
/* Parse DT provided link params */
ret = parse_dai_link_params(pdev, link_node,
dai_link);
if (ret < 0)
goto cleanup;
@@ -504,33 +522,32 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
dev_err(&pdev->dev, "DAI link type invalid\n");
ret = -EINVAL;
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++;
codec_count++;
}
/*
* 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++;
cleanup:
of_node_put(cpu);
if (ret < 0) {

View File

@@ -185,7 +185,7 @@ int tegra_codecs_runtime_setup(struct snd_soc_card *card,
unsigned int aud_mclk)
{
struct snd_soc_pcm_runtime *rtd;
int err;
int i, err;
rtd = get_pcm_runtime(card, "rt565x-playback");
if (rtd) {
@@ -231,30 +231,21 @@ int tegra_codecs_runtime_setup(struct snd_soc_card *card,
}
}
rtd = get_pcm_runtime(card, "dspk-playback-r");
rtd = get_pcm_runtime(card, "dspk-playback-dual-tas2552");
if (rtd) {
if (!strcmp(rtd->dais[rtd->dai_link->num_cpus]->name, "tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(rtd->dais[rtd->dai_link->num_cpus],
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "dais[%d] clock not set\n",
rtd->dai_link->num_cpus);
return err;
}
}
}
rtd = get_pcm_runtime(card, "dspk-playback-l");
if (rtd) {
if (!strcmp(rtd->dais[rtd->dai_link->num_cpus]->name, "tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(rtd->dais[rtd->dai_link->num_cpus],
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "dais[%d] clock not set\n",
rtd->dai_link->num_cpus);
return err;
for (i = 0; i < rtd->num_codecs; i++) {
if (!strcmp(rtd->dais[rtd->num_cpus + i]->name,
"tas2552-amplifier")) {
err = snd_soc_dai_set_sysclk(
rtd->dais[rtd->num_cpus + i],
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev,
"dais[%d] clock not set\n",
rtd->num_cpus + i);
return err;
}
}
}
}