[PATCHv2 00/10] ASoC: fsl-asoc-card: compatibility integration of a generic codec use case for use with S/PDIF controller
Hello,
This is the v2 of the series of patch aiming to make the machine driver fsl-asoc-card compatible with use cases where there is no real codec driver. It proposes to use the spdif_receiver and spdif_transmitter drivers instead of the dummy codec. This is a first step in using the S/PDIF controller with the ASRC.
The five first patches add compatibility with the pair of codecs spdif_receiver and spdif_transmitter with a new compatible, "fsl,imx-audio-generic". Codec parameters are set with default values.
The remaining patches add configuration options for the device tree. They configure the CPU DAI when using "fsl,imx-audio-generic". These are usually hard-coded in fsl-asoc-card for each audio codec. Because the generic codec could be used with other CPU DAI than the S/PDIF controller, setting these parameters could be required.
This series of patch was successfully built for arm64 and x86 on top of the latest for-next branch of the ASoC git tree on the 24/10. These modifications have also been tested on an i.MX8MN evaluation board, with a linux kernel RT v6.1.26-rt8.
We also have a few questions :
* We named the compatible "fsl,imx-audio-generic" as, for the moment, it could work with any CPU DAI, even if it uses S/PDIF codecs. Is it preferable to keep these modifications specific to the S/PDIF, thus specifying "spdif" in the compatible ? Or is it okay to keep the actual name of the compatible, and the generic purpose of this compatible ?
* Part of the dai_fmt variable hold information on the codec provider or consumer status for bit/frame clocks. In patch 03/10, as we add compatibility for multiple codecs, we make the test about bit/frame clock provider only check with codec[0]. That way we assure compatibility with all already existing compatibles. As it was never intended before to have multiple codecs for this test, is there a better way to handle it ? Should we make this test check if any codec is clock provider ? Or should we let codec[0] be the default possibility ? That way, future compatibles that could encounter this specific case with multi-codecs should adapt the test for their needs.
Best regards, Elinor Montmasson
Changelog: v1 -> v2: * replace use of the dummy codec by the pair of codecs spdif_receiver / spdif_transmitter * adapt how dai links codecs are used to take into account the possibility for multiple codecs per link * change compatible name * adapt driver to be able to register two codecs given in the device tree * v1 patch series at: https://lore.kernel.org/alsa-devel/20230901144550.520072-1-elinor.montmasson...
Elinor Montmasson (10): ASoC: fsl-asoc-card: add support for dai links with multiple codecs ASoC: fsl-asoc-card: add second dai link component for codecs ASoC: fsl-asoc-card: add compatibility to use 2 codecs from device tree ASoC: fsl-asoc-card: add new compatible for a generic codec use case ASoC: fsl-asoc-card: set generic codec as clock provider ASoC: fsl-asoc-card: add dts property "cpu-slot-width" ASoC: fsl-asoc-card: add dts property "cpu-slot-num" ASoC: fsl-asoc-card: add dts properties "cpu-sysclk-freq" ASoC: fsl-asoc-card: add dts properties "cpu-sysclk-dir-out" Documentation: fsl-asoc-card: add documentation for generic codec case
.../bindings/sound/fsl-asoc-card.txt | 26 +++- sound/soc/fsl/fsl-asoc-card.c | 128 ++++++++++++------ 2 files changed, 114 insertions(+), 40 deletions(-)
Add support for dai links using multiple codecs for multi-codec use cases.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 7518ab9d768e..cde31fd38262 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -809,10 +809,10 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
/* Normal DAI Link */ priv->dai_link[0].cpus->of_node = cpu_np; - priv->dai_link[0].codecs->dai_name = codec_dai_name; + priv->dai_link[0].codecs[0].dai_name = codec_dai_name;
if (!fsl_asoc_card_is_ac97(priv)) - priv->dai_link[0].codecs->of_node = codec_np; + priv->dai_link[0].codecs[0].of_node = codec_np; else { u32 idx;
@@ -823,11 +823,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) goto asrc_fail; }
- priv->dai_link[0].codecs->name = + priv->dai_link[0].codecs[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ac97-codec.%u", (unsigned int)idx); - if (!priv->dai_link[0].codecs->name) { + if (!priv->dai_link[0].codecs[0].name) { ret = -ENOMEM; goto asrc_fail; } @@ -838,13 +838,19 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->card.num_links = 1;
if (asrc_pdev) { + int i; + struct snd_soc_dai_link_component *codec; + struct snd_soc_dai_link *link; + /* DPCM DAI Links only if ASRC exists */ priv->dai_link[1].cpus->of_node = asrc_np; priv->dai_link[1].platforms->of_node = asrc_np; - priv->dai_link[2].codecs->dai_name = codec_dai_name; - priv->dai_link[2].codecs->of_node = codec_np; - priv->dai_link[2].codecs->name = - priv->dai_link[0].codecs->name; + link = &(priv->dai_link[2]); + for_each_link_codecs(link, i, codec) { + codec->dai_name = priv->dai_link[0].codecs[i].dai_name; + codec->of_node = priv->dai_link[0].codecs[i].of_node; + codec->name = priv->dai_link[0].codecs[i].name; + } priv->dai_link[2].cpus->of_node = cpu_np; priv->dai_link[2].dai_fmt = priv->dai_fmt; priv->card.num_links = 3;
Add a second dai link component for codecs that will be use for the generic codec use case. It will use spdif_receiver and spdif_transmitter drivers as dummy codec drivers, needing 2 codecs slots for the links.
To prevent deferrment for use cases using only one codec, also set by default the number of codecs to 1 for the relevant dai links.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index cde31fd38262..a62f26fe9802 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -295,7 +295,7 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
SND_SOC_DAILINK_DEFS(hifi, DAILINK_COMP_ARRAY(COMP_EMPTY()), - DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY()), DAILINK_COMP_ARRAY(COMP_EMPTY()));
SND_SOC_DAILINK_DEFS(hifi_fe, @@ -305,7 +305,7 @@ SND_SOC_DAILINK_DEFS(hifi_fe,
SND_SOC_DAILINK_DEFS(hifi_be, DAILINK_COMP_ARRAY(COMP_EMPTY()), - DAILINK_COMP_ARRAY(COMP_EMPTY()), + DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY()), DAILINK_COMP_ARRAY(COMP_DUMMY()));
static const struct snd_soc_dai_link fsl_asoc_card_dai[] = { @@ -618,6 +618,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
memcpy(priv->dai_link, fsl_asoc_card_dai, sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link)); + priv->dai_link[0].num_codecs = 1; + priv->dai_link[2].num_codecs = 1;
priv->card.dapm_routes = audio_map; priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
Add compatibility with the use of 2 codecs from the device tree. It will be needed for the generic codec case. Use cases using one codec will ignore any given codecs other than the first.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 62 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index a62f26fe9802..55052da60ccc 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -541,16 +541,17 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
static int fsl_asoc_card_probe(struct platform_device *pdev) { - struct device_node *cpu_np, *codec_np, *asrc_np; + struct device_node *cpu_np, *asrc_np; + struct device_node *codec_np[2]; struct device_node *np = pdev->dev.of_node; struct platform_device *asrc_pdev = NULL; struct device_node *bitclkprovider = NULL; struct device_node *frameprovider = NULL; struct platform_device *cpu_pdev; struct fsl_asoc_card_priv *priv; - struct device *codec_dev = NULL; + struct device *codec_dev[2] = { NULL, NULL }; const char *codec_dai_name; - const char *codec_dev_name; + const char *codec_dev_name[2]; u32 asrc_fmt = 0; u32 width; int ret; @@ -576,21 +577,25 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) goto fail; }
- codec_np = of_parse_phandle(np, "audio-codec", 0); - if (codec_np) { - struct platform_device *codec_pdev; - struct i2c_client *codec_i2c; + codec_np[0] = of_parse_phandle(np, "audio-codec", 0); + codec_np[1] = of_parse_phandle(np, "audio-codec", 1);
- codec_i2c = of_find_i2c_device_by_node(codec_np); - if (codec_i2c) { - codec_dev = &codec_i2c->dev; - codec_dev_name = codec_i2c->name; - } - if (!codec_dev) { - codec_pdev = of_find_device_by_node(codec_np); - if (codec_pdev) { - codec_dev = &codec_pdev->dev; - codec_dev_name = codec_pdev->name; + for (int i = 0; i < 2; i++) { + if (codec_np[i]) { + struct platform_device *codec_pdev; + struct i2c_client *codec_i2c; + + codec_i2c = of_find_i2c_device_by_node(codec_np[i]); + if (codec_i2c) { + codec_dev[i] = &codec_i2c->dev; + codec_dev_name[i] = codec_i2c->name; + } + if (!codec_dev[i]) { + codec_pdev = of_find_device_by_node(codec_np[i]); + if (codec_pdev) { + codec_dev[i] = &codec_pdev->dev; + codec_dev_name[i] = codec_pdev->name; + } } } } @@ -600,8 +605,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) asrc_pdev = of_find_device_by_node(asrc_np);
/* Get the MCLK rate only, and leave it controlled by CODEC drivers */ - if (codec_dev) { - struct clk *codec_clk = clk_get(codec_dev, NULL); + if (codec_dev[0]) { + struct clk *codec_clk = clk_get(codec_dev[0], NULL);
if (!IS_ERR(codec_clk)) { priv->codec_priv.mclk_freq = clk_get_rate(codec_clk); @@ -710,8 +715,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->codec_priv.fll_id = NAU8822_CLK_PLL; priv->codec_priv.pll_id = NAU8822_CLK_PLL; priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; - if (codec_dev) - priv->codec_priv.mclk = devm_clk_get(codec_dev, NULL); + if (codec_dev[0]) + priv->codec_priv.mclk = devm_clk_get(codec_dev[0], NULL); } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL; @@ -729,11 +734,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) if (bitclkprovider || frameprovider) { unsigned int daifmt = snd_soc_daifmt_parse_format(np, NULL);
- if (codec_np == bitclkprovider) - daifmt |= (codec_np == frameprovider) ? + if (codec_np[0] == bitclkprovider) + daifmt |= (codec_np[0] == frameprovider) ? SND_SOC_DAIFMT_CBP_CFP : SND_SOC_DAIFMT_CBP_CFC; else - daifmt |= (codec_np == frameprovider) ? + daifmt |= (codec_np[0] == frameprovider) ? SND_SOC_DAIFMT_CBC_CFP : SND_SOC_DAIFMT_CBC_CFC;
/* Override dai_fmt with value from DT */ @@ -749,7 +754,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) of_node_put(bitclkprovider); of_node_put(frameprovider);
- if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) { + if (!fsl_asoc_card_is_ac97(priv) && !codec_dev[0]) { dev_dbg(&pdev->dev, "failed to find codec device\n"); ret = -EPROBE_DEFER; goto asrc_fail; @@ -789,7 +794,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ret = snd_soc_of_parse_card_name(&priv->card, "model"); if (ret) { snprintf(priv->name, sizeof(priv->name), "%s-audio", - fsl_asoc_card_is_ac97(priv) ? "ac97" : codec_dev_name); + fsl_asoc_card_is_ac97(priv) ? "ac97" : codec_dev_name[0]); priv->card.name = priv->name; } priv->card.dai_link = priv->dai_link; @@ -814,7 +819,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->dai_link[0].codecs[0].dai_name = codec_dai_name;
if (!fsl_asoc_card_is_ac97(priv)) - priv->dai_link[0].codecs[0].of_node = codec_np; + priv->dai_link[0].codecs[0].of_node = codec_np[0]; else { u32 idx;
@@ -922,7 +927,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
asrc_fail: of_node_put(asrc_np); - of_node_put(codec_np); + of_node_put(codec_np[0]); + of_node_put(codec_np[1]); put_device(&cpu_pdev->dev); fail: of_node_put(cpu_np);
Add the new compatible "fsl,imx-audio-generic" for a generic codec use case. It allows using the fsl-asoc-card driver with the spdif_receiver and spdif_transmitter codec drivers used as dummy codecs. It can be used for cases where there is no real codec or codecs which do not require declaring controls.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 55052da60ccc..64f6bcf04720 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -550,6 +550,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) struct platform_device *cpu_pdev; struct fsl_asoc_card_priv *priv; struct device *codec_dev[2] = { NULL, NULL }; + const char *generic_codec_dai_names[2]; const char *codec_dai_name; const char *codec_dev_name[2]; u32 asrc_fmt = 0; @@ -717,6 +718,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; if (codec_dev[0]) priv->codec_priv.mclk = devm_clk_get(codec_dev[0], NULL); + } else if (of_device_is_compatible(np, "fsl,imx-audio-generic")) { + generic_codec_dai_names[0] = "dit-hifi"; + generic_codec_dai_names[1] = "dir-hifi"; + priv->dai_link[0].num_codecs = 2; + priv->dai_link[2].num_codecs = 2; } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL; @@ -759,6 +765,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ret = -EPROBE_DEFER; goto asrc_fail; } + if (of_device_is_compatible(np, "fsl,imx-audio-generic") + && !codec_dev[1]) { + dev_dbg(&pdev->dev, "failed to find second codec device\n"); + ret = -EPROBE_DEFER; + goto asrc_fail; + }
/* Common settings for corresponding Freescale CPU DAI driver */ if (of_node_name_eq(cpu_np, "ssi")) { @@ -816,11 +828,21 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
/* Normal DAI Link */ priv->dai_link[0].cpus->of_node = cpu_np; - priv->dai_link[0].codecs[0].dai_name = codec_dai_name;
- if (!fsl_asoc_card_is_ac97(priv)) + if (of_device_is_compatible(np, "fsl,imx-audio-generic")) { + priv->dai_link[0].codecs[0].dai_name = + generic_codec_dai_names[0]; + priv->dai_link[0].codecs[1].dai_name = + generic_codec_dai_names[1]; + } else { + priv->dai_link[0].codecs[0].dai_name = codec_dai_name; + } + + if (!fsl_asoc_card_is_ac97(priv)) { priv->dai_link[0].codecs[0].of_node = codec_np[0]; - else { + if (of_device_is_compatible(np, "fsl,imx-audio-generic")) + priv->dai_link[0].codecs[1].of_node = codec_np[1]; + } else { u32 idx;
ret = of_property_read_u32(cpu_np, "cell-index", &idx); @@ -950,6 +972,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = { { .compatible = "fsl,imx-audio-si476x", }, { .compatible = "fsl,imx-audio-wm8958", }, { .compatible = "fsl,imx-audio-nau8822", }, + { .compatible = "fsl,imx-audio-generic", }, {} }; MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
The default dai format defined by DAI_FMT_BASE doesn't set if the codec is consumer or provider of the bit and frame clocks.
S/PDIF DIR usually converts audio signal to an asynchronous I2S/PCM stream, and doesn't consume a bit or frame clock.
As S/PDIF DIR and DIT are used as codecs for the generic use case, set codecs as provider of both bit and frame clocks by default.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 64f6bcf04720..61c0fd97cde3 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -723,6 +723,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) generic_codec_dai_names[1] = "dir-hifi"; priv->dai_link[0].num_codecs = 2; priv->dai_link[2].num_codecs = 2; + priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP; } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL;
Add new optional dts property "cpu-slot-width", which allows to set a custom TDM slot width in bits for the CPU DAI when using the generic codec.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 61c0fd97cde3..42aa6ec306ec 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -724,6 +724,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->dai_link[0].num_codecs = 2; priv->dai_link[2].num_codecs = 2; priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP; + of_property_read_u32(np, "cpu-slot-width", &priv->cpu_priv.slot_width); } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL;
Add new optional dts property "cpu-slot-num", which allows to set a custom number of TDM slots for the CPU DAI when using the generic codec.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 42aa6ec306ec..110ac20ba699 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -725,6 +725,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->dai_link[2].num_codecs = 2; priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP; of_property_read_u32(np, "cpu-slot-width", &priv->cpu_priv.slot_width); + of_property_read_u32(np, "cpu-slot-num", &priv->cpu_priv.slot_num); } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL;
Add new optional dts property "cpu-sysclk-freq" to set custom sysclk frequencies for the CPU DAI with the generic codec. The way values are used is up to the CPU DAI driver implementation.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 110ac20ba699..902715d63add 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -726,6 +726,10 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP; of_property_read_u32(np, "cpu-slot-width", &priv->cpu_priv.slot_width); of_property_read_u32(np, "cpu-slot-num", &priv->cpu_priv.slot_num); + of_property_read_u32(np, "cpu-sysclk-freq-rx", + (u32 *)&priv->cpu_priv.sysclk_freq[RX]); + of_property_read_u32(np, "cpu-sysclk-freq-tx", + (u32 *)&priv->cpu_priv.sysclk_freq[TX]); } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL;
Add new optional dts properties "cpu-sysclk-dir-out" to set sysclk directions as "out" for the CPU DAI when using the generic codec. This can be set for Tx and Rx. If not set, the direction is "in". The way values are used is up to the CPU DAI driver implementation.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- sound/soc/fsl/fsl-asoc-card.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 902715d63add..4c44b4422614 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -730,6 +730,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) (u32 *)&priv->cpu_priv.sysclk_freq[RX]); of_property_read_u32(np, "cpu-sysclk-freq-tx", (u32 *)&priv->cpu_priv.sysclk_freq[TX]); + priv->cpu_priv.sysclk_dir[RX] = + of_property_read_bool(np, "cpu-sysclk-dir-rx-out") ? + SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN; + priv->cpu_priv.sysclk_dir[TX] = + of_property_read_bool(np, "cpu-sysclk-dir-tx-out") ? + SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN; } else { dev_err(&pdev->dev, "unknown Device Tree compatible\n"); ret = -EINVAL;
Add documentation about new dts bindings following new support for compatible "fsl,imx-audio-generic".
Some CPU DAI don't require a real audio codec. The new compatible "fsl,imx-audio-generic" allows to use the driver with codec drivers SPDIF DIT and SPDIF DIR as dummy codecs. It also allows to use not pre-configured audio codecs which don't require specific control through a codec driver.
The new dts properties give the possibility to set some parameters about the CPU DAI usually set through the codec configuration.
Signed-off-by: Elinor Montmasson elinor.montmasson@savoirfairelinux.com Co-authored-by: Philip-Dylan Gleonec philip-dylan.gleonec@savoirfairelinux.com --- .../bindings/sound/fsl-asoc-card.txt | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt index 4e8dbc5abfd1..274319bf7ff7 100644 --- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt @@ -17,6 +17,9 @@ Note: The card is initially designed for those sound cards who use AC'97, I2S and PCM DAI formats. However, it'll be also possible to support those non AC'97/I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as long as the driver has been properly upgraded. + To use CPU DAIs that do not require a codec such as an S/PDIF controller, + or to use a DAI to output or capture raw I2S/TDM data, you can + use the compatible "fsl,imx-audio-generic".
The compatible list for this generic sound card currently: @@ -48,6 +51,8 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-nau8822"
+ "fsl,imx-audio-generic" + Required properties:
- compatible : Contains one of entries in the compatible list. @@ -56,7 +61,11 @@ Required properties:
- audio-cpu : The phandle of an CPU DAI controller
- - audio-codec : The phandle of an audio codec + - audio-codec : The phandle of an audio codec. + If using the "fsl,imx-audio-generic" compatible, + give instead a pair of phandles with the + spdif_transmitter first (driver SPDIF DIT) and the + spdif_receiver second (driver SPDIF DIR).
Optional properties:
@@ -88,6 +97,21 @@ Optional properties: - bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml. - mclk-id : main clock id, specific for each card configuration.
+Optional, relevant only with the "fsl,imx-audio-generic" compatible: + + - cpu-slot-width : Indicates a specific TDM slot width in bits. + - cpu-slot-num : Indicates a specific number of TDM slots per frame. + + - cpu-sysclk-freq-rx : Frequency of the CPU DAI sys clock for Rx. + - cpu-sysclk-freq-tx : Frequency of the CPU DAI sys clock for Tx. + + - cpu-sysclk-dir-rx-out : Boolean property. Specifies sys clock direction + as 'out' on initialization for Rx. + If not set, default direction is 'in'. + - cpu-sysclk-dir-tx-out : Boolean property. Specifies sys clock direction + as 'out' on initialization for Tx. + If not set, default direction is 'in'. + Optional unless SSI is selected as a CPU DAI:
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
On Fri, Oct 27, 2023 at 04:47:24PM +0200, Elinor Montmasson wrote:
Hello,
This is the v2 of the series of patch aiming to make the machine driver fsl-asoc-card compatible with use cases where there is no real codec driver. It proposes to use the spdif_receiver and spdif_transmitter drivers instead of the dummy codec.
Please fix your mail client to word wrap within paragraphs at something substantially less than 80 columns. Doing this makes your messages much easier to read and reply to.
- Part of the dai_fmt variable hold information on the codec provider
or consumer status for bit/frame clocks. In patch 03/10, as we add compatibility for multiple codecs, we make the test about bit/frame clock provider only check with codec[0]. That way we assure compatibility with all already existing compatibles. As it was never intended before to have multiple codecs for this test, is there a better way to handle it ? Should we make this test check if any codec is clock provider ? Or should we let codec[0] be the default possibility ? That way, future compatibles that could encounter this specific case with multi-codecs should adapt the test for their needs.
Yes, we should be checking all the CODECs - existing bindings that only have a single CODEC should work fine since they shouldn't have additional CODECs but it's possible that a device other than the first one found may be providing the clocks.
Documentation: fsl-asoc-card: add documentation for generic codec case
Please submit patches using subject lines reflecting the style for the subsystem, this makes it easier for people to identify relevant patches. Look at what existing commits in the area you're changing are doing and make sure your subject lines visually resemble what they're doing. There's no need to resubmit to fix this alone.
participants (2)
-
Elinor Montmasson
-
Mark Brown