[PATCH 012/117] ASoC: AMD: create/add dummy codec and machine devices/drivers

Alex Deucher alexdeucher at gmail.com
Wed May 10 18:46:11 UTC 2017


From: Maruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu at amd.com>

Dummy codec and machine devices are created so that ASoC based
soundcard can be created. Respective drivers which bound to
these devices are added.

Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 sound/soc/amd/raven/Makefile          |   4 +
 sound/soc/amd/raven/acp3x-dummy5102.c | 136 ++++++++++++++++++++++++++++++++++
 sound/soc/amd/raven/dummy-w5102.c     | 102 +++++++++++++++++++++++++
 sound/soc/amd/raven/pci-acp3x.c       |  34 ++++++++-
 4 files changed, 272 insertions(+), 4 deletions(-)
 create mode 100644 sound/soc/amd/raven/acp3x-dummy5102.c
 create mode 100644 sound/soc/amd/raven/dummy-w5102.c

diff --git a/sound/soc/amd/raven/Makefile b/sound/soc/amd/raven/Makefile
index 8c03e6f..5db3afc 100644
--- a/sound/soc/amd/raven/Makefile
+++ b/sound/soc/amd/raven/Makefile
@@ -1,4 +1,8 @@
 snd-pci-acp3x-objs	:= pci-acp3x.o
 snd-acp3x-pcm-dma-objs	:= acp3x-pcm-dma.o
+snd-soc-dummy-w5102-objs := dummy-w5102.o
+snd-soc-acp3x-mach-objs := acp3x-dummy5102.o
 obj-$(CONFIG_SND_SOC_AMD_ACP3x)	 += snd-pci-acp3x.o
 obj-$(CONFIG_SND_SOC_AMD_ACP3x)	 += snd-acp3x-pcm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x)	+= snd-soc-dummy-w5102.o
+obj-$(CONFIG_SND_SOC_AMD_ACP3x)	+= snd-soc-acp3x-mach.o
diff --git a/sound/soc/amd/raven/acp3x-dummy5102.c b/sound/soc/amd/raven/acp3x-dummy5102.c
new file mode 100644
index 0000000..3b2f509
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x-dummy5102.c
@@ -0,0 +1,136 @@
+/*
+ * Machine driver for AMD ACP Audio engine using dummy codec
+ *
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/module.h>
+
+static int acp3x_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
+
+{
+	return 0;
+}
+
+static struct snd_soc_ops acp3x_wm5102_ops = {
+	.hw_params = acp3x_hw_params,
+};
+
+static int acp3x_init(struct snd_soc_pcm_runtime *rtd)
+{
+	return 0;
+}
+
+static struct snd_soc_dai_link acp3x_dai_w5102[] = {
+	{
+		.name = "RV-W5102-PLAY",
+		.stream_name = "Playback",
+		.platform_name = "acp3x_rv_i2s.0",
+		.cpu_dai_name = "acp3x_rv_i2s.0",
+		.codec_dai_name = "dummy_w5102_dai",
+		.codec_name = "dummy_w5102.0",
+		.dai_fmt = SND_SOC_DAIFMT_DSP_A /*SND_SOC_DAIFMT_I2S*/ | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.ops = &acp3x_wm5102_ops,
+		.init = acp3x_init,
+	},
+};
+
+static const struct snd_soc_dapm_widget acp3x_widgets[] = {
+	SND_SOC_DAPM_HP("Headphones", NULL),
+	SND_SOC_DAPM_MIC("Analog Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route acp3x_audio_route[] = {
+	{"Headphones", NULL, "HPO L"},
+	{"Headphones", NULL, "HPO R"},
+	{"MIC1", NULL, "Analog Mic"},
+};
+
+static struct snd_soc_card acp3x_card = {
+	.name = "acp3x",
+	.owner = THIS_MODULE,
+	.dai_link = acp3x_dai_w5102,
+	.num_links = 1,
+};
+
+static int acp3x_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct acp_wm5102 *machine = NULL;
+	struct snd_soc_card *card;
+
+	card = &acp3x_card;
+	acp3x_card.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, card);
+	snd_soc_card_set_drvdata(card, machine);
+
+	ret = snd_soc_register_card(card);
+	if (ret) {
+		dev_err(&pdev->dev,
+				"snd_soc_register_card(%s) failed: %d\n",
+				acp3x_card.name, ret);
+		return ret;
+	}
+	return 0;
+}
+
+static int acp3x_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card;
+
+	card = platform_get_drvdata(pdev);
+	snd_soc_unregister_card(card);
+
+	return 0;
+}
+
+static struct platform_driver acp3x_mach_driver = {
+	.driver = {
+		.name = "acp3x_w5102_mach",
+		.pm = &snd_soc_pm_ops,
+	},
+	.probe = acp3x_probe,
+	.remove = acp3x_remove,
+};
+
+static int __init acp3x_audio_init(void)
+{
+	platform_driver_register(&acp3x_mach_driver);
+	return 0;
+}
+
+static void __exit acp3x_audio_exit(void)
+{
+	platform_driver_unregister(&acp3x_mach_driver);
+}
+
+module_init(acp3x_audio_init);
+module_exit(acp3x_audio_exit);
+
+MODULE_AUTHOR("Maruthi.Bayyavarapu at amd.com");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/raven/dummy-w5102.c b/sound/soc/amd/raven/dummy-w5102.c
new file mode 100644
index 0000000..3e09e32
--- /dev/null
+++ b/sound/soc/amd/raven/dummy-w5102.c
@@ -0,0 +1,102 @@
+/*
+ * dummy audio codec driver
+ *
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <sound/soc.h>
+
+#define W5102_RATES	SNDRV_PCM_RATE_8000_96000
+#define W5102_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
+			SNDRV_PCM_FMTBIT_S32_LE | \
+			SNDRV_PCM_FMTBIT_S24_LE)
+
+static const struct snd_soc_dapm_widget w5102_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("dummy-w5102-out"),
+	SND_SOC_DAPM_INPUT("dummy-w5102-in"),
+};
+
+static const struct snd_soc_dapm_route w5102_routes[] = {
+	{ "dummy-w5102-out", NULL, "Playback" },
+	{ "Capture", NULL, "dummy-w5102-in" },
+};
+
+static struct snd_soc_codec_driver soc_codec_w5102_dummy = {
+	.component_driver = {
+		.dapm_widgets = w5102_widgets,
+		.num_dapm_widgets = ARRAY_SIZE(w5102_widgets),
+		.dapm_routes = w5102_routes,
+		.num_dapm_routes = ARRAY_SIZE(w5102_routes),
+	},
+};
+
+static struct snd_soc_dai_driver w5102_stub_dai = {
+	.name		= "dummy_w5102_dai",
+	.playback	= {
+		.stream_name	= "Playback",
+		.channels_min	= 2,
+		.channels_max	= 2,
+		.rates		= W5102_RATES,
+		.formats	= W5102_FORMATS,
+	},
+	.capture	= {
+		.stream_name	= "Capture",
+		.channels_min	= 2,
+		.channels_max	= 2,
+		.rates		= W5102_RATES,
+		.formats	= W5102_FORMATS,
+	},
+
+};
+
+static int dummy_w5102_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_w5102_dummy,
+			&w5102_stub_dai, 1);
+	return ret;
+}
+
+static int dummy_w5102_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+
+
+static struct platform_driver dummy_w5102_driver = {
+	.probe		= dummy_w5102_probe,
+	.remove		= dummy_w5102_remove,
+	.driver		= {
+		.name	= "dummy_w5102",
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(dummy_w5102_driver);
+
+MODULE_DESCRIPTION("dummy-w5102 dummy codec driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform: dummy_w5102");
diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c
index a182013..5891c5b 100644
--- a/sound/soc/amd/raven/pci-acp3x.c
+++ b/sound/soc/amd/raven/pci-acp3x.c
@@ -24,7 +24,7 @@ struct acp3x_dev_data {
 	void __iomem *acp3x_base;
 	bool acp3x_audio_mode;
 	struct resource *res;
-	struct platform_device *pdev;
+	struct platform_device *pdev[3];
 };
 
 static int snd_acp3x_probe(struct pci_dev *pci,
@@ -103,13 +103,30 @@ static int snd_acp3x_probe(struct pci_dev *pci,
 		pdevinfo.data = &irqflags;
 		pdevinfo.size_data = sizeof(irqflags);
 
-		adata->pdev = platform_device_register_full(&pdevinfo);
-		if (adata->pdev == NULL) {
+		adata->pdev[0] = platform_device_register_full(&pdevinfo);
+		if (adata->pdev[0] == NULL) {
 			dev_err(&pci->dev, "cannot register %s device\n",
 				pdevinfo.name);
 			ret = -ENODEV;
 			goto unmap_mmio;
 		}
+
+		/* create dummy codec device */
+		adata->pdev[1] = platform_device_register_simple("dummy_w5102",
+					0, NULL, 0);
+		if (IS_ERR(adata->pdev[1])) {
+			dev_err(&pci->dev, "Cannot register dummy_w5102\n");
+			ret = -ENODEV;
+			goto unregister_pdev0;
+		}
+		/* create dummy mach device */
+		adata->pdev[2] = platform_device_register_simple(
+					"acp3x_w5102_mach", 0, NULL, 0);
+		if (IS_ERR(adata->pdev[2])) {
+			dev_err(&pci->dev, "Cannot register acp3x_w5102_mach\n");
+			ret = -ENODEV;
+			goto unregister_pdev1;
+		}
 	} else {
 		dev_err(&pci->dev, "Inavlid ACP audio mode : %d\n", val);
 		ret = -ENODEV;
@@ -118,6 +135,10 @@ static int snd_acp3x_probe(struct pci_dev *pci,
 
 	return 0;
 
+unregister_pdev1:
+	platform_device_unregister(adata->pdev[1]);
+unregister_pdev0:
+	platform_device_unregister(adata->pdev[0]);
 unmap_mmio:
 	pci_disable_msi(pci);
 	iounmap(adata->acp3x_base);
@@ -131,9 +152,14 @@ static int snd_acp3x_probe(struct pci_dev *pci,
 
 static void snd_acp3x_remove(struct pci_dev *pci)
 {
+	int i;
 	struct acp3x_dev_data *adata = pci_get_drvdata(pci);
 
-	platform_device_unregister(adata->pdev);
+	if (adata->acp3x_audio_mode == ACP3x_I2S_MODE) {
+		for (i = 2; i >= 0; i--)
+			platform_device_unregister(adata->pdev[i]);
+	}
+
 	iounmap(adata->acp3x_base);
 
 	pci_disable_msi(pci);
-- 
2.5.5



More information about the amd-gfx mailing list