[alsa-devel] [PATCH v2 0/2] register atmel-ssc as sound DAI w/o platform driver
Hi!
v1 -> v2 changes - add ack from Rob Herring on patch 1/2. - add reasons why breaking compatibility is ok for patch 2/2 (requested by Rob). - add #sound-dai-cells to the ssc0 node in the devcietree example.
The Atmel SSC is currently not usable as an audio DAI unless someone registers it with ASoC. This is currently delegated to a platform driver for every possible audio use, and prevents the SSC from being used as a cpu DAI with the simple-audio-card driver.
The first patch fixes this.
The second patch simplifies one of these platform drivers, since it can now rely on the SSC to register itself with ASoC. However, this may not be a possible simplification for other, older, drivers since it also requires device tree changes.
Cheers, Peter
Peter Rosin (2): misc: atmel-ssc: register as sound DAI if #sound-dai-cells is present ASoC: atmel: tse850: rely on the ssc to register as a cpu dai by itself
.../devicetree/bindings/misc/atmel-ssc.txt | 2 + .../bindings/sound/axentia,tse850-pcm5142.txt | 11 +++-- drivers/misc/atmel-ssc.c | 50 ++++++++++++++++++++++ include/linux/atmel-ssc.h | 1 + sound/soc/atmel/tse850-pcm5142.c | 23 ++-------- 5 files changed, 64 insertions(+), 23 deletions(-)
The SSC is currently not usable with the ASoC simple-audio-card, as every SSC audio user has to build a platform driver that may do as little as calling atmel_ssc_set_audio/atmel_ssc_put_audio (which allocates the SSC and registers a DAI with the ASoC subsystem).
So, have that happen automatically, if the #sound-dai-cells property is present in devicetree, which it has to be anyway for simple audio card to work.
Acked-by: Rob Herring robh@kernel.org Signed-off-by: Peter Rosin peda@axentia.se --- .../devicetree/bindings/misc/atmel-ssc.txt | 2 + drivers/misc/atmel-ssc.c | 50 ++++++++++++++++++++++ include/linux/atmel-ssc.h | 1 + 3 files changed, 53 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt index efc98ea1f23d..f8629bb73945 100644 --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -24,6 +24,8 @@ Optional properties: this parameter to choose where the clock from. - By default the clock is from TK pin, if the clock from RK pin, this property is needed. + - #sound-dai-cells: Should contain <0>. + - This property makes the SSC into an automatically registered DAI.
Examples: - PDC transfer: diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 0516ecda54d3..b2a0340f277e 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -20,6 +20,8 @@
#include <linux/of.h>
+#include "../../sound/soc/atmel/atmel_ssc_dai.h" + /* Serialize access to ssc_list and user count */ static DEFINE_SPINLOCK(user_lock); static LIST_HEAD(ssc_list); @@ -145,6 +147,49 @@ static inline const struct atmel_ssc_platform_data * __init platform_get_device_id(pdev)->driver_data; }
+#ifdef CONFIG_SND_ATMEL_SOC_SSC +static int ssc_sound_dai_probe(struct ssc_device *ssc) +{ + struct device_node *np = ssc->pdev->dev.of_node; + int ret; + int id; + + ssc->sound_dai = false; + + if (!of_property_read_bool(np, "#sound-dai-cells")) + return 0; + + id = of_alias_get_id(np, "ssc"); + if (id < 0) + return id; + + ret = atmel_ssc_set_audio(id); + ssc->sound_dai = !ret; + + return ret; +} + +static void ssc_sound_dai_remove(struct ssc_device *ssc) +{ + if (!ssc->sound_dai) + return; + + atmel_ssc_put_audio(of_alias_get_id(ssc->pdev->dev.of_node, "ssc")); +} +#else +static inline int ssc_sound_dai_probe(struct ssc_device *ssc) +{ + if (of_property_read_bool(ssc->pdev->dev.of_node, "#sound-dai-cells")) + return -ENOTSUPP; + + return 0; +} + +static inline void ssc_sound_dai_remove(struct ssc_device *ssc) +{ +} +#endif + static int ssc_probe(struct platform_device *pdev) { struct resource *regs; @@ -204,6 +249,9 @@ static int ssc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", ssc->regs, ssc->irq);
+ if (ssc_sound_dai_probe(ssc)) + dev_err(&pdev->dev, "failed to auto-setup ssc for audio\n"); + return 0; }
@@ -211,6 +259,8 @@ static int ssc_remove(struct platform_device *pdev) { struct ssc_device *ssc = platform_get_drvdata(pdev);
+ ssc_sound_dai_remove(ssc); + spin_lock(&user_lock); list_del(&ssc->list); spin_unlock(&user_lock); diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 7c0f6549898b..fdb545101ede 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -20,6 +20,7 @@ struct ssc_device { int user; int irq; bool clk_from_rk_pin; + bool sound_dai; };
struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
Le 06/12/2016 à 20:22, Peter Rosin a écrit :
The SSC is currently not usable with the ASoC simple-audio-card, as every SSC audio user has to build a platform driver that may do as little as calling atmel_ssc_set_audio/atmel_ssc_put_audio (which allocates the SSC and registers a DAI with the ASoC subsystem).
So, have that happen automatically, if the #sound-dai-cells property is present in devicetree, which it has to be anyway for simple audio card to work.
Acked-by: Rob Herring robh@kernel.org Signed-off-by: Peter Rosin peda@axentia.se
Sounds okay: thanks Peter. Acked-by: Nicolas Ferre nicolas.ferre@atmel.com
I don't think my tag is needed for second patch but you can add it if you wish.
Regards,
.../devicetree/bindings/misc/atmel-ssc.txt | 2 + drivers/misc/atmel-ssc.c | 50 ++++++++++++++++++++++ include/linux/atmel-ssc.h | 1 + 3 files changed, 53 insertions(+)
diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt index efc98ea1f23d..f8629bb73945 100644 --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -24,6 +24,8 @@ Optional properties: this parameter to choose where the clock from. - By default the clock is from TK pin, if the clock from RK pin, this property is needed.
- #sound-dai-cells: Should contain <0>.
- This property makes the SSC into an automatically registered DAI.
Examples:
- PDC transfer:
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 0516ecda54d3..b2a0340f277e 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -20,6 +20,8 @@
#include <linux/of.h>
+#include "../../sound/soc/atmel/atmel_ssc_dai.h"
/* Serialize access to ssc_list and user count */ static DEFINE_SPINLOCK(user_lock); static LIST_HEAD(ssc_list); @@ -145,6 +147,49 @@ static inline const struct atmel_ssc_platform_data * __init platform_get_device_id(pdev)->driver_data; }
+#ifdef CONFIG_SND_ATMEL_SOC_SSC +static int ssc_sound_dai_probe(struct ssc_device *ssc) +{
- struct device_node *np = ssc->pdev->dev.of_node;
- int ret;
- int id;
- ssc->sound_dai = false;
- if (!of_property_read_bool(np, "#sound-dai-cells"))
return 0;
- id = of_alias_get_id(np, "ssc");
- if (id < 0)
return id;
- ret = atmel_ssc_set_audio(id);
- ssc->sound_dai = !ret;
- return ret;
+}
+static void ssc_sound_dai_remove(struct ssc_device *ssc) +{
- if (!ssc->sound_dai)
return;
- atmel_ssc_put_audio(of_alias_get_id(ssc->pdev->dev.of_node, "ssc"));
+} +#else +static inline int ssc_sound_dai_probe(struct ssc_device *ssc) +{
- if (of_property_read_bool(ssc->pdev->dev.of_node, "#sound-dai-cells"))
return -ENOTSUPP;
- return 0;
+}
+static inline void ssc_sound_dai_remove(struct ssc_device *ssc) +{ +} +#endif
static int ssc_probe(struct platform_device *pdev) { struct resource *regs; @@ -204,6 +249,9 @@ static int ssc_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", ssc->regs, ssc->irq);
- if (ssc_sound_dai_probe(ssc))
dev_err(&pdev->dev, "failed to auto-setup ssc for audio\n");
- return 0;
}
@@ -211,6 +259,8 @@ static int ssc_remove(struct platform_device *pdev) { struct ssc_device *ssc = platform_get_drvdata(pdev);
- ssc_sound_dai_remove(ssc);
- spin_lock(&user_lock); list_del(&ssc->list); spin_unlock(&user_lock);
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 7c0f6549898b..fdb545101ede 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -20,6 +20,7 @@ struct ssc_device { int user; int irq; bool clk_from_rk_pin;
- bool sound_dai;
};
struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
This breaks devicetree compatibility, but in this case that is ok. All affected units are either on my desk, or running an even older version of the driver that is not compatible with the upstreamed version anyway (and when these other units are eventually updated, they will get a fresh dtb as well, so that is not a significant problem either).
All of that is of course assuming that noone else has managed to build something that can use this driver, but that seems extremely improbable.
Signed-off-by: Peter Rosin peda@axentia.se --- .../bindings/sound/axentia,tse850-pcm5142.txt | 11 ++++++++--- sound/soc/atmel/tse850-pcm5142.c | 23 +++------------------- 2 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt index 5b9b38f578bb..fdb25b492514 100644 --- a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt +++ b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt @@ -2,8 +2,7 @@ Devicetree bindings for the Axentia TSE-850 audio complex
Required properties: - compatible: "axentia,tse850-pcm5142" - - axentia,ssc-controller: The phandle of the atmel SSC controller used as - cpu dai. + - axentia,cpu-dai: The phandle of the cpu dai. - axentia,audio-codec: The phandle of the PCM5142 codec. - axentia,add-gpios: gpio specifier that controls the mixer. - axentia,loop1-gpios: gpio specifier that controls loop relays on channel 1. @@ -43,6 +42,12 @@ the PCM5142 codec.
Example:
+ &ssc0 { + #sound-dai-cells = <0>; + + status = "okay"; + }; + &i2c { codec: pcm5142@4c { compatible = "ti,pcm5142"; @@ -77,7 +82,7 @@ Example: sound { compatible = "axentia,tse850-pcm5142";
- axentia,ssc-controller = <&ssc0>; + axentia,cpu-dai = <&ssc0>; axentia,audio-codec = <&codec>;
axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>; diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c index ac6a814c8ecf..a72c7d642026 100644 --- a/sound/soc/atmel/tse850-pcm5142.c +++ b/sound/soc/atmel/tse850-pcm5142.c @@ -51,11 +51,7 @@ #include <sound/soc.h> #include <sound/pcm_params.h>
-#include "atmel_ssc_dai.h" - struct tse850_priv { - int ssc_id; - struct gpio_desc *add; struct gpio_desc *loop1; struct gpio_desc *loop2; @@ -329,23 +325,20 @@ static int tse850_dt_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *codec_np, *cpu_np; - struct snd_soc_card *card = &tse850_card; struct snd_soc_dai_link *dailink = &tse850_dailink; - struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
if (!np) { dev_err(&pdev->dev, "only device tree supported\n"); return -EINVAL; }
- cpu_np = of_parse_phandle(np, "axentia,ssc-controller", 0); + cpu_np = of_parse_phandle(np, "axentia,cpu-dai", 0); if (!cpu_np) { - dev_err(&pdev->dev, "failed to get dai and pcm info\n"); + dev_err(&pdev->dev, "failed to get cpu dai\n"); return -EINVAL; } dailink->cpu_of_node = cpu_np; dailink->platform_of_node = cpu_np; - tse850->ssc_id = of_alias_get_id(cpu_np, "ssc"); of_node_put(cpu_np);
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0); @@ -415,23 +408,14 @@ static int tse850_probe(struct platform_device *pdev) return ret; }
- ret = atmel_ssc_set_audio(tse850->ssc_id); - if (ret != 0) { - dev_err(dev, - "failed to set SSC %d for audio\n", tse850->ssc_id); - goto err_disable_ana; - } - ret = snd_soc_register_card(card); if (ret) { dev_err(dev, "snd_soc_register_card failed\n"); - goto err_put_audio; + goto err_disable_ana; }
return 0;
-err_put_audio: - atmel_ssc_put_audio(tse850->ssc_id); err_disable_ana: regulator_disable(tse850->ana); return ret; @@ -443,7 +427,6 @@ static int tse850_remove(struct platform_device *pdev) struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card); - atmel_ssc_put_audio(tse850->ssc_id); regulator_disable(tse850->ana);
return 0;
On Tue, Dec 06, 2016 at 08:22:37PM +0100, Peter Rosin wrote:
This breaks devicetree compatibility, but in this case that is ok. All affected units are either on my desk, or running an even older version of the driver that is not compatible with the upstreamed version anyway (and when these other units are eventually updated, they will get a fresh dtb as well, so that is not a significant problem either).
Perfect.
All of that is of course assuming that noone else has managed to build something that can use this driver, but that seems extremely improbable.
Signed-off-by: Peter Rosin peda@axentia.se
.../bindings/sound/axentia,tse850-pcm5142.txt | 11 ++++++++---
Acked-by: Rob Herring robh@kernel.org
sound/soc/atmel/tse850-pcm5142.c | 23 +++------------------- 2 files changed, 11 insertions(+), 23 deletions(-)
The patch
ASoC: atmel: tse850: rely on the ssc to register as a cpu dai by itself
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From ca8c7f233fa2c40e2a23f982dc33d947f28ad207 Mon Sep 17 00:00:00 2001
From: Peter Rosin peda@axentia.se Date: Tue, 6 Dec 2016 20:22:37 +0100 Subject: [PATCH] ASoC: atmel: tse850: rely on the ssc to register as a cpu dai by itself
This breaks devicetree compatibility, but in this case that is ok. All affected units are either on my desk, or running an even older version of the driver that is not compatible with the upstreamed version anyway (and when these other units are eventually updated, they will get a fresh dtb as well, so that is not a significant problem either).
All of that is of course assuming that noone else has managed to build something that can use this driver, but that seems extremely improbable.
Signed-off-by: Peter Rosin peda@axentia.se Acked-by: Rob Herring robh@kernel.org Signed-off-by: Mark Brown broonie@kernel.org --- .../bindings/sound/axentia,tse850-pcm5142.txt | 11 ++++++++--- sound/soc/atmel/tse850-pcm5142.c | 23 +++------------------- 2 files changed, 11 insertions(+), 23 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt index 5b9b38f578bb..fdb25b492514 100644 --- a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt +++ b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt @@ -2,8 +2,7 @@ Devicetree bindings for the Axentia TSE-850 audio complex
Required properties: - compatible: "axentia,tse850-pcm5142" - - axentia,ssc-controller: The phandle of the atmel SSC controller used as - cpu dai. + - axentia,cpu-dai: The phandle of the cpu dai. - axentia,audio-codec: The phandle of the PCM5142 codec. - axentia,add-gpios: gpio specifier that controls the mixer. - axentia,loop1-gpios: gpio specifier that controls loop relays on channel 1. @@ -43,6 +42,12 @@ the PCM5142 codec.
Example:
+ &ssc0 { + #sound-dai-cells = <0>; + + status = "okay"; + }; + &i2c { codec: pcm5142@4c { compatible = "ti,pcm5142"; @@ -77,7 +82,7 @@ Example: sound { compatible = "axentia,tse850-pcm5142";
- axentia,ssc-controller = <&ssc0>; + axentia,cpu-dai = <&ssc0>; axentia,audio-codec = <&codec>;
axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>; diff --git a/sound/soc/atmel/tse850-pcm5142.c b/sound/soc/atmel/tse850-pcm5142.c index ac6a814c8ecf..a72c7d642026 100644 --- a/sound/soc/atmel/tse850-pcm5142.c +++ b/sound/soc/atmel/tse850-pcm5142.c @@ -51,11 +51,7 @@ #include <sound/soc.h> #include <sound/pcm_params.h>
-#include "atmel_ssc_dai.h" - struct tse850_priv { - int ssc_id; - struct gpio_desc *add; struct gpio_desc *loop1; struct gpio_desc *loop2; @@ -329,23 +325,20 @@ static int tse850_dt_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *codec_np, *cpu_np; - struct snd_soc_card *card = &tse850_card; struct snd_soc_dai_link *dailink = &tse850_dailink; - struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
if (!np) { dev_err(&pdev->dev, "only device tree supported\n"); return -EINVAL; }
- cpu_np = of_parse_phandle(np, "axentia,ssc-controller", 0); + cpu_np = of_parse_phandle(np, "axentia,cpu-dai", 0); if (!cpu_np) { - dev_err(&pdev->dev, "failed to get dai and pcm info\n"); + dev_err(&pdev->dev, "failed to get cpu dai\n"); return -EINVAL; } dailink->cpu_of_node = cpu_np; dailink->platform_of_node = cpu_np; - tse850->ssc_id = of_alias_get_id(cpu_np, "ssc"); of_node_put(cpu_np);
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0); @@ -415,23 +408,14 @@ static int tse850_probe(struct platform_device *pdev) return ret; }
- ret = atmel_ssc_set_audio(tse850->ssc_id); - if (ret != 0) { - dev_err(dev, - "failed to set SSC %d for audio\n", tse850->ssc_id); - goto err_disable_ana; - } - ret = snd_soc_register_card(card); if (ret) { dev_err(dev, "snd_soc_register_card failed\n"); - goto err_put_audio; + goto err_disable_ana; }
return 0;
-err_put_audio: - atmel_ssc_put_audio(tse850->ssc_id); err_disable_ana: regulator_disable(tse850->ana); return ret; @@ -443,7 +427,6 @@ static int tse850_remove(struct platform_device *pdev) struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card); - atmel_ssc_put_audio(tse850->ssc_id); regulator_disable(tse850->ana);
return 0;
participants (4)
-
Mark Brown
-
Nicolas Ferre
-
Peter Rosin
-
Rob Herring