diff mbox

[v8,2/2] ASoC: fsl: Add S/PDIF machine driver

Message ID ca3061d70ab8bf59afc59031fa7befcfaed26d51.1376912873.git.b42378@freescale.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Nicolin Chen Aug. 19, 2013, 12:08 p.m. UTC
This patch implements a device-tree-only machine driver for Freescale
i.MX series Soc. It works with spdif_transmitter/spdif_receiver and
fsl_spdif.c drivers.

Signed-off-by: Nicolin Chen <b42378@freescale.com>
---
 .../devicetree/bindings/sound/imx-audio-spdif.txt  |   29 +++++
 sound/soc/fsl/Kconfig                              |   11 ++
 sound/soc/fsl/Makefile                             |    2 +
 sound/soc/fsl/imx-spdif.c                          |  134 ++++++++++++++++++++
 4 files changed, 176 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
 create mode 100644 sound/soc/fsl/imx-spdif.c

Comments

Stephen Warren Aug. 19, 2013, 9:39 p.m. UTC | #1
On 08/19/2013 06:08 AM, Nicolin Chen wrote:
> This patch implements a device-tree-only machine driver for Freescale
> i.MX series Soc. It works with spdif_transmitter/spdif_receiver and
> fsl_spdif.c drivers.

> diff --git a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt

> +Optional properties:
> +
> +  - spdif-transmitter : The phandle of the spdif-transmitter dummy codec
> +
> +  - spdif-receiver : The phandle of the spdif-receiver dummy codec
> +
> +* Note: At least one of these two properties should be set in the DT binding.

Those object truly don't exist in HW and only exist due to internal
details of Linux's ASoC subsystem.

Instead, you should register any SPDIF rx/tx dummy CODEC internally to
the machine driver.

Perhaps you'll still need properties to indicate which of the RX and TX
paths of the HW block are actually connected to anything on the board.
Perhaps a Boolean property "spdif-tx" to indicate TX support, otherwise
RX support is assumed?

Or, to map the properties more directly to HW, perhaps name the property
"spdif-tx-jack-exists", or even "spdif-tx-jack" and make it a phandle to
a node that represents the actual S/PDIF connector?
Mark Brown Aug. 20, 2013, 12:18 a.m. UTC | #2
On Mon, Aug 19, 2013 at 03:39:26PM -0600, Stephen Warren wrote:
> On 08/19/2013 06:08 AM, Nicolin Chen wrote:
> > This patch implements a device-tree-only machine driver for Freescale
> > i.MX series Soc. It works with spdif_transmitter/spdif_receiver and
> > fsl_spdif.c drivers.
> 
> > diff --git a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt

> > +Optional properties:

> > +  - spdif-transmitter : The phandle of the spdif-transmitter dummy codec
> > +  - spdif-receiver : The phandle of the spdif-receiver dummy codec

> > +* Note: At least one of these two properties should be set in the DT binding.

> Those object truly don't exist in HW and only exist due to internal
> details of Linux's ASoC subsystem.

They will physically exist if they're usefully present on the board (in
the sense that they're there and can be pointed at) - there will be
either a TOSLINK optical connector or (less commonly) an electrical
connector breaking the signal out to go elsewhere though they don't have
any interaction with software usually which is more what you mean here.

> Or, to map the properties more directly to HW, perhaps name the property
> "spdif-tx-jack-exists", or even "spdif-tx-jack" and make it a phandle to
> a node that represents the actual S/PDIF connector?

S/PDIF is also sometimes used as an interconnect between devices - some
CODECs have S/PDIF I/O (more normally used as an external connector on
the box).  This is most frequently seen as a way to plumb HDMI in since
some HDMI devices seem to provide this as a legacy interconnect, though
it can get used just for regular CODECs as well.  Using this machine
driver would probably be a bit of an abuse for some applications, though
with things like the HDMI one the goal of the hardware is to be dropped
into a driver like this so perhaps it makes sense and is useful anyway.

Equally well it'd be good to get this stuff actually merged, it seems to
have been surprisingly time consuming thus far...
Stephen Warren Aug. 20, 2013, 3:48 p.m. UTC | #3
On 08/19/2013 06:18 PM, Mark Brown wrote:
> On Mon, Aug 19, 2013 at 03:39:26PM -0600, Stephen Warren wrote:
>> On 08/19/2013 06:08 AM, Nicolin Chen wrote:
>>> This patch implements a device-tree-only machine driver for
>>> Freescale i.MX series Soc. It works with
>>> spdif_transmitter/spdif_receiver and fsl_spdif.c drivers.
>> 
>>> diff --git
>>> a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
>>> b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
> 
>>> +Optional properties:
> 
>>> +  - spdif-transmitter : The phandle of the spdif-transmitter
>>> dummy codec +  - spdif-receiver : The phandle of the
>>> spdif-receiver dummy codec
> 
>>> +* Note: At least one of these two properties should be set in
>>> the DT binding.
> 
>> Those object truly don't exist in HW and only exist due to
>> internal details of Linux's ASoC subsystem.
> 
> They will physically exist if they're usefully present on the board
> (in the sense that they're there and can be pointed at) - there
> will be either a TOSLINK optical connector or (less commonly) an
> electrical connector breaking the signal out to go elsewhere though
> they don't have any interaction with software usually which is more
> what you mean here.

Sure, the S/PDIF signal is connected to something, but it is not a
"dummy CODEC"; a "dummy CODEC" is purely something internal to ASoC
and absolutely nothing to do with HW.

>> Or, to map the properties more directly to HW, perhaps name the
>> property "spdif-tx-jack-exists", or even "spdif-tx-jack" and make
>> it a phandle to a node that represents the actual S/PDIF
>> connector?
> 
> S/PDIF is also sometimes used as an interconnect between devices -
> some CODECs have S/PDIF I/O (more normally used as an external
> connector on the box).  This is most frequently seen as a way to
> plumb HDMI in since some HDMI devices seem to provide this as a
> legacy interconnect, though it can get used just for regular CODECs
> as well.  Using this machine driver would probably be a bit of an
> abuse for some applications, though with things like the HDMI one
> the goal of the hardware is to be dropped into a driver like this
> so perhaps it makes sense and is useful anyway.
> 
> Equally well it'd be good to get this stuff actually merged, it
> seems to have been surprisingly time consuming thus far...

That's not a good argument for an incorrect binding.
Mark Brown Aug. 20, 2013, 7:07 p.m. UTC | #4
On Tue, Aug 20, 2013 at 09:48:46AM -0600, Stephen Warren wrote:
> On 08/19/2013 06:18 PM, Mark Brown wrote:

> > S/PDIF is also sometimes used as an interconnect between devices -
> > some CODECs have S/PDIF I/O (more normally used as an external
> > connector on the box).  This is most frequently seen as a way to

> That's not a good argument for an incorrect binding.

The point is that it might turn into a more correct binding depending on
what the S/PDIF device actually is.
Stephen Warren Aug. 20, 2013, 7:53 p.m. UTC | #5
On 08/20/2013 01:07 PM, Mark Brown wrote:
> On Tue, Aug 20, 2013 at 09:48:46AM -0600, Stephen Warren wrote:
>> On 08/19/2013 06:18 PM, Mark Brown wrote:
> 
>>> S/PDIF is also sometimes used as an interconnect between
>>> devices - some CODECs have S/PDIF I/O (more normally used as an
>>> external connector on the box).  This is most frequently seen
>>> as a way to
> 
>> That's not a good argument for an incorrect binding.
> 
> The point is that it might turn into a more correct binding
> depending on what the S/PDIF device actually is.

There's *never* an object on the board called a "dummy codec".
Mark Brown Aug. 20, 2013, 10:28 p.m. UTC | #6
On Tue, Aug 20, 2013 at 01:53:49PM -0600, Stephen Warren wrote:
> On 08/20/2013 01:07 PM, Mark Brown wrote:

> > The point is that it might turn into a more correct binding
> > depending on what the S/PDIF device actually is.

> There's *never* an object on the board called a "dummy codec".

Oh, is that what you're talking about?  Yes, that makes sense.  I had
been responding to the comments about the transceivers.
Nicolin Chen Aug. 21, 2013, 2:18 a.m. UTC | #7
On Tue, Aug 20, 2013 at 11:28:10PM +0100, Mark Brown wrote:
> On Tue, Aug 20, 2013 at 01:53:49PM -0600, Stephen Warren wrote:
> > On 08/20/2013 01:07 PM, Mark Brown wrote:
> 
> > > The point is that it might turn into a more correct binding
> > > depending on what the S/PDIF device actually is.
> 
> > There's *never* an object on the board called a "dummy codec".
> 
> Oh, is that what you're talking about?  Yes, that makes sense.  I had
> been responding to the comments about the transceivers.

I'll remove the 'dummy' words in the next version from the binding doc.

Thank you
Nicolin
Stephen Warren Aug. 21, 2013, 4:08 p.m. UTC | #8
On 08/20/2013 08:18 PM, Nicolin Chen wrote:
> On Tue, Aug 20, 2013 at 11:28:10PM +0100, Mark Brown wrote:
>> On Tue, Aug 20, 2013 at 01:53:49PM -0600, Stephen Warren wrote:
>>> On 08/20/2013 01:07 PM, Mark Brown wrote:
>>
>>>> The point is that it might turn into a more correct binding
>>>> depending on what the S/PDIF device actually is.
>>
>>> There's *never* an object on the board called a "dummy codec".
>>
>> Oh, is that what you're talking about?  Yes, that makes sense.  I had
>> been responding to the comments about the transceivers.
> 
> I'll remove the 'dummy' words in the next version from the binding doc.

I think the word "CODEC" is also problematic in this context, since
whatever is connector to the S/PDIF output path may not be a CODEC.
That's why I suggested some more generic property names that IIRC
concentrated on enabling rx/tx rather than indicating what was actually
connected to the S/PDIF controller.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
new file mode 100644
index 0000000..9a3fa26
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
@@ -0,0 +1,29 @@ 
+Freescale i.MX audio complex with S/PDIF transceiver
+
+Required properties:
+
+  - compatible : "fsl,imx-audio-spdif"
+
+  - model : The user-visible name of this sound complex
+
+  - spdif-controller : The phandle of the i.MX S/PDIF controller
+
+
+Optional properties:
+
+  - spdif-transmitter : The phandle of the spdif-transmitter dummy codec
+
+  - spdif-receiver : The phandle of the spdif-receiver dummy codec
+
+* Note: At least one of these two properties should be set in the DT binding.
+
+
+Example:
+
+sound-spdif {
+	compatible = "fsl,imx-audio-spdif";
+	model = "imx-spdif";
+	spdif-controller = <&spdif>;
+	spdif-transmitter = <&spdif_tx_codec>;
+	spdif-receiver = <&spdif_rx_codec>;
+};
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index cd088cc..a708380 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -193,6 +193,17 @@  config SND_SOC_IMX_SGTL5000
 	  Say Y if you want to add support for SoC audio on an i.MX board with
 	  a sgtl5000 codec.
 
+config SND_SOC_IMX_SPDIF
+	tristate "SoC Audio support for i.MX boards with S/PDIF"
+	select SND_SOC_IMX_PCM_DMA
+	select SND_SOC_FSL_SPDIF
+	select SND_SOC_FSL_UTILS
+	select SND_SOC_SPDIF
+	help
+	  SoC Audio support for i.MX boards with S/PDIF
+	  Say Y if you want to add support for SoC audio on an i.MX board with
+	  a S/DPDIF.
+
 config SND_SOC_IMX_MC13783
 	tristate "SoC Audio support for I.MX boards with mc13783"
 	depends on MFD_MC13783 && ARM
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4b5970e..e2aaff7 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -45,6 +45,7 @@  snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
 snd-soc-wm1133-ev1-objs := wm1133-ev1.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-wm8962-objs := imx-wm8962.o
+snd-soc-imx-spdif-objs :=imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
@@ -53,4 +54,5 @@  obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
+obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
new file mode 100644
index 0000000..893f3d1
--- /dev/null
+++ b/sound/soc/fsl/imx-spdif.c
@@ -0,0 +1,134 @@ 
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <sound/soc.h>
+
+struct imx_spdif_data {
+	struct snd_soc_dai_link dai[2];
+	struct snd_soc_card card;
+};
+
+static int imx_spdif_audio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *spdif_np, *codec_tx_np, *codec_rx_np;
+	struct platform_device *spdif_pdev;
+	struct imx_spdif_data *data;
+	int ret = 0, num_links = 0;
+
+	spdif_np = of_parse_phandle(np, "spdif-controller", 0);
+	if (!spdif_np) {
+		dev_err(&pdev->dev, "failed to find spdif-controller\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	spdif_pdev = of_find_device_by_node(spdif_np);
+	if (!spdif_pdev) {
+		dev_err(&pdev->dev, "failed to find S/PDIF device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	codec_tx_np = of_parse_phandle(np, "spdif-transmitter", 0);
+	if (codec_tx_np) {
+		data->dai[num_links].name = "S/PDIF TX";
+		data->dai[num_links].stream_name = "S/PDIF PCM Playback";
+		data->dai[num_links].codec_dai_name = "dit-hifi";
+		data->dai[num_links].codec_of_node = codec_tx_np;
+		data->dai[num_links].cpu_of_node = spdif_np;
+		data->dai[num_links].platform_of_node = spdif_np;
+		num_links++;
+	}
+
+	codec_rx_np = of_parse_phandle(np, "spdif-receiver", 0);
+	if (codec_rx_np) {
+		data->dai[num_links].name = "S/PDIF RX";
+		data->dai[num_links].stream_name = "S/PDIF PCM Capture";
+		data->dai[num_links].codec_dai_name = "dir-hifi";
+		data->dai[num_links].codec_of_node = codec_rx_np;
+		data->dai[num_links].cpu_of_node = spdif_np;
+		data->dai[num_links].platform_of_node = spdif_np;
+		num_links++;
+	}
+
+	if (!num_links) {
+		dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n");
+		goto fail;
+	}
+
+	data->card.dev = &pdev->dev;
+	data->card.num_links = num_links;
+	data->card.dai_link = data->dai;
+
+	ret = snd_soc_of_parse_card_name(&data->card, "model");
+	if (ret)
+		goto fail;
+
+	ret = snd_soc_register_card(&data->card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+		goto fail;
+	}
+
+	platform_set_drvdata(pdev, data);
+
+fail:
+	if (codec_tx_np)
+		of_node_put(codec_tx_np);
+	if (codec_rx_np)
+		of_node_put(codec_rx_np);
+	if (spdif_np)
+		of_node_put(spdif_np);
+
+	return ret;
+}
+
+static int imx_spdif_audio_remove(struct platform_device *pdev)
+{
+	struct imx_spdif_data *data = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(&data->card);
+
+	return 0;
+}
+
+static const struct of_device_id imx_spdif_dt_ids[] = {
+	{ .compatible = "fsl,imx-audio-spdif", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids);
+
+static struct platform_driver imx_spdif_driver = {
+	.driver = {
+		.name = "imx-spdif",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_spdif_dt_ids,
+	},
+	.probe = imx_spdif_audio_probe,
+	.remove = imx_spdif_audio_remove,
+};
+
+module_platform_driver(imx_spdif_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-spdif");