diff --git a/sound/soc/tegra/tegra186_dspk.c b/sound/soc/tegra/tegra186_dspk.c index c6001171..230dce47 100644 --- a/sound/soc/tegra/tegra186_dspk.c +++ b/sound/soc/tegra/tegra186_dspk.c @@ -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 }; diff --git a/sound/soc/tegra/tegra_asoc_machine.c b/sound/soc/tegra/tegra_asoc_machine.c index 586dbb23..0976e539 100644 --- a/sound/soc/tegra/tegra_asoc_machine.c +++ b/sound/soc/tegra/tegra_asoc_machine.c @@ -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) { diff --git a/sound/soc/tegra/tegra_codecs.c b/sound/soc/tegra/tegra_codecs.c index 3252e27b..c530ca6b 100644 --- a/sound/soc/tegra/tegra_codecs.c +++ b/sound/soc/tegra/tegra_codecs.c @@ -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; + } } } }