Message ID | ca3061d70ab8bf59afc59031fa7befcfaed26d51.1376912873.git.b42378@freescale.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
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?
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...
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.
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.
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".
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.
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
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 --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");
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