mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
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:
committed by
mobile promotions
parent
3c67831fe8
commit
f9d418aa6a
@@ -446,38 +446,6 @@ static struct snd_soc_dai_driver tegra186_dspk_dais[] = {
|
|||||||
.ops = &tegra186_dspk_dai_ops,
|
.ops = &tegra186_dspk_dai_ops,
|
||||||
.symmetric_rate = 1,
|
.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",
|
.name = "DUMMY_SINK",
|
||||||
.playback = {
|
.playback = {
|
||||||
@@ -493,7 +461,6 @@ static struct snd_soc_dai_driver tegra186_dspk_dais[] = {
|
|||||||
|
|
||||||
static const struct snd_soc_dapm_widget tegra186_dspk_widgets[] = {
|
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_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),
|
SND_SOC_DAPM_SPK("SPK", NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -507,8 +474,6 @@ static const struct snd_soc_dapm_route tegra186_dspk_routes[] = {
|
|||||||
#else
|
#else
|
||||||
{ "RX", NULL, "CIF-Playback" },
|
{ "RX", NULL, "CIF-Playback" },
|
||||||
{ "DAP-Capture", NULL, "RX" },
|
{ "DAP-Capture", NULL, "RX" },
|
||||||
{ "DAP2 TX", NULL, "CIF2-Playback" },
|
|
||||||
{ "DAP2-Capture", NULL, "DAP2 TX" },
|
|
||||||
{ "SPK", NULL, "Dummy-Playback" },
|
{ "SPK", NULL, "Dummy-Playback" },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -97,7 +97,35 @@ static int get_num_dai_links(struct platform_device *pdev,
|
|||||||
unsigned int *num_links)
|
unsigned int *num_links)
|
||||||
{
|
{
|
||||||
struct device_node *top = pdev->dev.of_node;
|
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;
|
unsigned int link_count = 0, num_codecs;
|
||||||
|
|
||||||
link_node = of_get_child_by_name(top, PREFIX "dai-link");
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
dai_links[link_count].cpus = devm_kzalloc(&pdev->dev,
|
||||||
* depending on the number of codec subnodes, DAI link
|
sizeof(*dai_links[link_count].cpus),
|
||||||
* count is incremented. DT can have one DAI link entry
|
GFP_KERNEL);
|
||||||
* with multiple codec nodes(for ex: DSPK), driver can
|
if (!dai_links[link_count].cpus)
|
||||||
* create multiple links out of it.
|
return -ENOMEM;
|
||||||
*/
|
|
||||||
num_codecs = of_get_child_count_with_name(link_node,
|
num_codecs = of_get_child_count_with_name(link_node,
|
||||||
"codec");
|
"codec");
|
||||||
if (!num_codecs) {
|
if (!num_codecs) {
|
||||||
of_node_put(link_node);
|
of_node_put(link_node);
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
@@ -127,19 +155,28 @@ static int get_num_dai_links(struct platform_device *pdev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_child_of_node(link_node, codec) {
|
dai_links[link_count].codecs =
|
||||||
if (of_node_cmp(codec->name, "codec"))
|
devm_kzalloc(&pdev->dev,
|
||||||
continue;
|
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))
|
dai_links[link_count].platforms = devm_kzalloc(&pdev->dev,
|
||||||
link_count++;
|
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);
|
link_node = of_get_next_child(top, link_node);
|
||||||
} while (link_node);
|
} while (link_node);
|
||||||
|
|
||||||
*num_links = link_count;
|
|
||||||
|
|
||||||
return 0;
|
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 *top = pdev->dev.of_node;
|
||||||
struct device_node *link_node;
|
struct device_node *link_node;
|
||||||
struct snd_soc_dai_link *dai_links;
|
struct snd_soc_dai_link *dai_links;
|
||||||
unsigned int num_links, link_count = 0, i;
|
unsigned int num_links, link_count = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = get_num_dai_links(pdev, &machine->asoc->num_links);
|
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)
|
if (!dai_links)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < num_links; i++) {
|
ret = allocate_link_dais(pdev, dai_links);
|
||||||
dai_links[i].cpus = devm_kzalloc(&pdev->dev,
|
if (ret < 0)
|
||||||
sizeof(*dai_links[i].cpus),
|
return ret;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
machine->asoc->dai_links = dai_links;
|
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);
|
dev_dbg(&pdev->dev, "parsing (%pOF)\n", link_node);
|
||||||
|
|
||||||
|
dai_link = &dai_links[link_count];
|
||||||
cpu = of_get_child_by_name(link_node, "cpu");
|
cpu = of_get_child_by_name(link_node, "cpu");
|
||||||
if (!cpu) {
|
if (!cpu) {
|
||||||
dev_err(&pdev->dev, "cpu subnode is missing");
|
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;
|
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) {
|
for_each_child_of_node(link_node, codec) {
|
||||||
/* loop over codecs only */
|
/* loop over codecs only */
|
||||||
if (of_node_cmp(codec->name, "codec"))
|
if (of_node_cmp(codec->name, "codec"))
|
||||||
@@ -453,48 +476,43 @@ static int parse_dt_dai_links(struct snd_soc_card *card,
|
|||||||
continue;
|
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 */
|
/* parse CODEC DAI */
|
||||||
ret = parse_dai(codec, dai_link->codecs);
|
ret = parse_dai(codec, &dai_link->codecs[codec_count]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* set DAI link name */
|
codec_count++;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
asoc_simple_parse_daifmt(&pdev->dev, link_node, codec,
|
/* set DAI link name */
|
||||||
NULL, &dai_link->dai_fmt);
|
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,
|
asoc_simple_parse_daifmt(&pdev->dev, link_node, codec,
|
||||||
dai_link->cpus);
|
NULL, &dai_link->dai_fmt);
|
||||||
|
|
||||||
of_property_read_u32(link_node, "link-type",
|
asoc_simple_canonicalize_platform(dai_link->platforms,
|
||||||
&link_type);
|
dai_link->cpus);
|
||||||
switch (link_type) {
|
|
||||||
case PCM_LINK:
|
of_property_read_u32(link_node, "link-type",
|
||||||
dai_link->ops = pcm_ops;
|
&link_type);
|
||||||
break;
|
switch (link_type) {
|
||||||
case COMPR_LINK:
|
case PCM_LINK:
|
||||||
dai_link->compr_ops = compr_ops;
|
dai_link->ops = pcm_ops;
|
||||||
break;
|
break;
|
||||||
case C2C_LINK:
|
case COMPR_LINK:
|
||||||
/* Parse DT provided link params */
|
dai_link->compr_ops = compr_ops;
|
||||||
ret = parse_dai_link_params(pdev, link_node,
|
break;
|
||||||
|
case C2C_LINK:
|
||||||
|
/* Parse DT provided link params */
|
||||||
|
ret = parse_dai_link_params(pdev, link_node,
|
||||||
dai_link);
|
dai_link);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto cleanup;
|
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");
|
dev_err(&pdev->dev, "DAI link type invalid\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
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++;
|
|
||||||
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:
|
cleanup:
|
||||||
of_node_put(cpu);
|
of_node_put(cpu);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ int tegra_codecs_runtime_setup(struct snd_soc_card *card,
|
|||||||
unsigned int aud_mclk)
|
unsigned int aud_mclk)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd;
|
struct snd_soc_pcm_runtime *rtd;
|
||||||
int err;
|
int i, err;
|
||||||
|
|
||||||
rtd = get_pcm_runtime(card, "rt565x-playback");
|
rtd = get_pcm_runtime(card, "rt565x-playback");
|
||||||
if (rtd) {
|
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 (rtd) {
|
||||||
if (!strcmp(rtd->dais[rtd->dai_link->num_cpus]->name, "tas2552-amplifier")) {
|
for (i = 0; i < rtd->num_codecs; i++) {
|
||||||
err = snd_soc_dai_set_sysclk(rtd->dais[rtd->dai_link->num_cpus],
|
if (!strcmp(rtd->dais[rtd->num_cpus + i]->name,
|
||||||
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
|
"tas2552-amplifier")) {
|
||||||
SND_SOC_CLOCK_IN);
|
err = snd_soc_dai_set_sysclk(
|
||||||
if (err < 0) {
|
rtd->dais[rtd->num_cpus + i],
|
||||||
dev_err(card->dev, "dais[%d] clock not set\n",
|
TAS2552_PDM_CLK_IVCLKIN, aud_mclk,
|
||||||
rtd->dai_link->num_cpus);
|
SND_SOC_CLOCK_IN);
|
||||||
return err;
|
if (err < 0) {
|
||||||
}
|
dev_err(card->dev,
|
||||||
}
|
"dais[%d] clock not set\n",
|
||||||
}
|
rtd->num_cpus + i);
|
||||||
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user