From: Maruthi Srinivas Bayyavarapu <Maruthi.Bayyavarapu@xxxxxxx> 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