[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