158c8c843SAjit Kumar Pandey // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
258c8c843SAjit Kumar Pandey //
358c8c843SAjit Kumar Pandey // This file is provided under a dual BSD/GPLv2 license. When using or
458c8c843SAjit Kumar Pandey // redistributing this file, you may do so under either license.
558c8c843SAjit Kumar Pandey //
658c8c843SAjit Kumar Pandey // Copyright(c) 2021 Advanced Micro Devices, Inc.
758c8c843SAjit Kumar Pandey //
858c8c843SAjit Kumar Pandey // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
958c8c843SAjit Kumar Pandey //
1058c8c843SAjit Kumar Pandey
1158c8c843SAjit Kumar Pandey /*
1258c8c843SAjit Kumar Pandey * Hardware interface for Renoir ACP block
1358c8c843SAjit Kumar Pandey */
1458c8c843SAjit Kumar Pandey
1558c8c843SAjit Kumar Pandey #include <linux/platform_device.h>
1658c8c843SAjit Kumar Pandey #include <linux/module.h>
1758c8c843SAjit Kumar Pandey #include <linux/err.h>
1858c8c843SAjit Kumar Pandey #include <linux/io.h>
1958c8c843SAjit Kumar Pandey #include <sound/pcm_params.h>
2058c8c843SAjit Kumar Pandey #include <sound/soc.h>
2158c8c843SAjit Kumar Pandey #include <sound/soc-dai.h>
2258c8c843SAjit Kumar Pandey #include <linux/dma-mapping.h>
2358c8c843SAjit Kumar Pandey
2458c8c843SAjit Kumar Pandey #include "amd.h"
2558c8c843SAjit Kumar Pandey
2658c8c843SAjit Kumar Pandey #define DRV_NAME "acp_asoc_renoir"
2758c8c843SAjit Kumar Pandey
28b24484c1SV sujith kumar Reddy static struct acp_resource rsrc = {
29b24484c1SV sujith kumar Reddy .offset = 20,
30b24484c1SV sujith kumar Reddy .no_of_ctrls = 1,
31b24484c1SV sujith kumar Reddy .irqp_used = 0,
32b24484c1SV sujith kumar Reddy .irq_reg_offset = 0x1800,
33b24484c1SV sujith kumar Reddy .i2s_pin_cfg_offset = 0x1400,
34b24484c1SV sujith kumar Reddy .i2s_mode = 0x04,
35b24484c1SV sujith kumar Reddy .scratch_reg_offset = 0x12800,
36b24484c1SV sujith kumar Reddy .sram_pte_offset = 0x02052800,
37b24484c1SV sujith kumar Reddy };
38b24484c1SV sujith kumar Reddy
398a8e1b90SAjit Kumar Pandey static struct snd_soc_acpi_codecs amp_rt1019 = {
408a8e1b90SAjit Kumar Pandey .num_codecs = 1,
418a8e1b90SAjit Kumar Pandey .codecs = {"10EC1019"}
428a8e1b90SAjit Kumar Pandey };
438a8e1b90SAjit Kumar Pandey
44eee33bacSAjit Kumar Pandey static struct snd_soc_acpi_codecs amp_max = {
45eee33bacSAjit Kumar Pandey .num_codecs = 1,
46eee33bacSAjit Kumar Pandey .codecs = {"MX98360A"}
47eee33bacSAjit Kumar Pandey };
48eee33bacSAjit Kumar Pandey
498a8e1b90SAjit Kumar Pandey static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = {
508a8e1b90SAjit Kumar Pandey {
518a8e1b90SAjit Kumar Pandey .id = "10EC5682",
52abdcf728SAjit Kumar Pandey .drv_name = "acp3xalc56821019",
538a8e1b90SAjit Kumar Pandey .machine_quirk = snd_soc_acpi_codec_list,
548a8e1b90SAjit Kumar Pandey .quirk_data = &_rt1019,
558a8e1b90SAjit Kumar Pandey },
568a8e1b90SAjit Kumar Pandey {
57eee33bacSAjit Kumar Pandey .id = "RTL5682",
58eee33bacSAjit Kumar Pandey .drv_name = "acp3xalc5682sm98360",
59eee33bacSAjit Kumar Pandey .machine_quirk = snd_soc_acpi_codec_list,
60eee33bacSAjit Kumar Pandey .quirk_data = &_max,
61eee33bacSAjit Kumar Pandey },
62eee33bacSAjit Kumar Pandey {
63eee33bacSAjit Kumar Pandey .id = "RTL5682",
64eee33bacSAjit Kumar Pandey .drv_name = "acp3xalc5682s1019",
65eee33bacSAjit Kumar Pandey .machine_quirk = snd_soc_acpi_codec_list,
66eee33bacSAjit Kumar Pandey .quirk_data = &_rt1019,
67eee33bacSAjit Kumar Pandey },
68eee33bacSAjit Kumar Pandey {
698a8e1b90SAjit Kumar Pandey .id = "AMDI1019",
708a8e1b90SAjit Kumar Pandey .drv_name = "renoir-acp",
718a8e1b90SAjit Kumar Pandey },
728a8e1b90SAjit Kumar Pandey {},
738a8e1b90SAjit Kumar Pandey };
748a8e1b90SAjit Kumar Pandey
7558c8c843SAjit Kumar Pandey static struct snd_soc_dai_driver acp_renoir_dai[] = {
7658c8c843SAjit Kumar Pandey {
7758c8c843SAjit Kumar Pandey .name = "acp-i2s-sp",
7858c8c843SAjit Kumar Pandey .id = I2S_SP_INSTANCE,
7958c8c843SAjit Kumar Pandey .playback = {
8058c8c843SAjit Kumar Pandey .stream_name = "I2S SP Playback",
8158c8c843SAjit Kumar Pandey .rates = SNDRV_PCM_RATE_8000_96000,
8258c8c843SAjit Kumar Pandey .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
8358c8c843SAjit Kumar Pandey SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
8458c8c843SAjit Kumar Pandey .channels_min = 2,
8558c8c843SAjit Kumar Pandey .channels_max = 8,
8658c8c843SAjit Kumar Pandey .rate_min = 8000,
8758c8c843SAjit Kumar Pandey .rate_max = 96000,
8858c8c843SAjit Kumar Pandey },
8958c8c843SAjit Kumar Pandey .capture = {
9058c8c843SAjit Kumar Pandey .stream_name = "I2S SP Capture",
9158c8c843SAjit Kumar Pandey .rates = SNDRV_PCM_RATE_8000_48000,
9258c8c843SAjit Kumar Pandey .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
9358c8c843SAjit Kumar Pandey SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
9458c8c843SAjit Kumar Pandey .channels_min = 2,
9558c8c843SAjit Kumar Pandey .channels_max = 2,
9658c8c843SAjit Kumar Pandey .rate_min = 8000,
9758c8c843SAjit Kumar Pandey .rate_max = 48000,
9858c8c843SAjit Kumar Pandey },
9958c8c843SAjit Kumar Pandey .ops = &asoc_acp_cpu_dai_ops,
10058c8c843SAjit Kumar Pandey },
10158c8c843SAjit Kumar Pandey {
10258c8c843SAjit Kumar Pandey .name = "acp-i2s-bt",
10358c8c843SAjit Kumar Pandey .id = I2S_BT_INSTANCE,
10458c8c843SAjit Kumar Pandey .playback = {
10558c8c843SAjit Kumar Pandey .stream_name = "I2S BT Playback",
10658c8c843SAjit Kumar Pandey .rates = SNDRV_PCM_RATE_8000_96000,
10758c8c843SAjit Kumar Pandey .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
10858c8c843SAjit Kumar Pandey SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
10958c8c843SAjit Kumar Pandey .channels_min = 2,
11058c8c843SAjit Kumar Pandey .channels_max = 8,
11158c8c843SAjit Kumar Pandey .rate_min = 8000,
11258c8c843SAjit Kumar Pandey .rate_max = 96000,
11358c8c843SAjit Kumar Pandey },
11458c8c843SAjit Kumar Pandey .capture = {
11558c8c843SAjit Kumar Pandey .stream_name = "I2S BT Capture",
11658c8c843SAjit Kumar Pandey .rates = SNDRV_PCM_RATE_8000_48000,
11758c8c843SAjit Kumar Pandey .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
11858c8c843SAjit Kumar Pandey SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
11958c8c843SAjit Kumar Pandey .channels_min = 2,
12058c8c843SAjit Kumar Pandey .channels_max = 2,
12158c8c843SAjit Kumar Pandey .rate_min = 8000,
12258c8c843SAjit Kumar Pandey .rate_max = 48000,
12358c8c843SAjit Kumar Pandey },
12458c8c843SAjit Kumar Pandey .ops = &asoc_acp_cpu_dai_ops,
12558c8c843SAjit Kumar Pandey },
126def6dc25SAjit Kumar Pandey {
127def6dc25SAjit Kumar Pandey .name = "acp-pdm-dmic",
128def6dc25SAjit Kumar Pandey .id = DMIC_INSTANCE,
129def6dc25SAjit Kumar Pandey .capture = {
130def6dc25SAjit Kumar Pandey .rates = SNDRV_PCM_RATE_8000_48000,
131def6dc25SAjit Kumar Pandey .formats = SNDRV_PCM_FMTBIT_S32_LE,
132def6dc25SAjit Kumar Pandey .channels_min = 2,
133def6dc25SAjit Kumar Pandey .channels_max = 2,
134def6dc25SAjit Kumar Pandey .rate_min = 8000,
135def6dc25SAjit Kumar Pandey .rate_max = 48000,
136def6dc25SAjit Kumar Pandey },
137def6dc25SAjit Kumar Pandey .ops = &acp_dmic_dai_ops,
138def6dc25SAjit Kumar Pandey },
13958c8c843SAjit Kumar Pandey };
14058c8c843SAjit Kumar Pandey
1416a75585aSAjit Kumar Pandey
renoir_audio_probe(struct platform_device * pdev)14258c8c843SAjit Kumar Pandey static int renoir_audio_probe(struct platform_device *pdev)
14358c8c843SAjit Kumar Pandey {
14458c8c843SAjit Kumar Pandey struct device *dev = &pdev->dev;
1456a75585aSAjit Kumar Pandey struct acp_chip_info *chip;
14658c8c843SAjit Kumar Pandey struct acp_dev_data *adata;
14758c8c843SAjit Kumar Pandey struct resource *res;
1486a75585aSAjit Kumar Pandey int ret;
1496a75585aSAjit Kumar Pandey
1506a75585aSAjit Kumar Pandey chip = dev_get_platdata(&pdev->dev);
1516a75585aSAjit Kumar Pandey if (!chip || !chip->base) {
1526a75585aSAjit Kumar Pandey dev_err(&pdev->dev, "ACP chip data is NULL\n");
1536a75585aSAjit Kumar Pandey return -ENODEV;
1546a75585aSAjit Kumar Pandey }
1556a75585aSAjit Kumar Pandey
1566a75585aSAjit Kumar Pandey if (chip->acp_rev != ACP3X_DEV) {
1576a75585aSAjit Kumar Pandey dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev);
1586a75585aSAjit Kumar Pandey return -ENODEV;
1596a75585aSAjit Kumar Pandey }
1606a75585aSAjit Kumar Pandey
16158c8c843SAjit Kumar Pandey adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
16258c8c843SAjit Kumar Pandey if (!adata)
16358c8c843SAjit Kumar Pandey return -ENOMEM;
16458c8c843SAjit Kumar Pandey
16558c8c843SAjit Kumar Pandey res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem");
16658c8c843SAjit Kumar Pandey if (!res) {
16758c8c843SAjit Kumar Pandey dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
16858c8c843SAjit Kumar Pandey return -ENODEV;
16958c8c843SAjit Kumar Pandey }
17058c8c843SAjit Kumar Pandey
17158c8c843SAjit Kumar Pandey adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
17258c8c843SAjit Kumar Pandey if (!adata->acp_base)
17358c8c843SAjit Kumar Pandey return -ENOMEM;
17458c8c843SAjit Kumar Pandey
175899a9a7fSDan Carpenter ret = platform_get_irq_byname(pdev, "acp_dai_irq");
176899a9a7fSDan Carpenter if (ret < 0)
177899a9a7fSDan Carpenter return ret;
178899a9a7fSDan Carpenter adata->i2s_irq = ret;
17958c8c843SAjit Kumar Pandey
18058c8c843SAjit Kumar Pandey adata->dev = dev;
18158c8c843SAjit Kumar Pandey adata->dai_driver = acp_renoir_dai;
18258c8c843SAjit Kumar Pandey adata->num_dai = ARRAY_SIZE(acp_renoir_dai);
183b24484c1SV sujith kumar Reddy adata->rsrc = &rsrc;
18458c8c843SAjit Kumar Pandey
185e646b51fSAjit Kumar Pandey adata->machines = snd_soc_acpi_amd_acp_machines;
186e646b51fSAjit Kumar Pandey acp_machine_select(adata);
187e646b51fSAjit Kumar Pandey
18858c8c843SAjit Kumar Pandey dev_set_drvdata(dev, adata);
189*fc11d326SSyed Saba Kareem acp_enable_interrupts(adata);
19058c8c843SAjit Kumar Pandey acp_platform_register(dev);
19158c8c843SAjit Kumar Pandey
19258c8c843SAjit Kumar Pandey return 0;
19358c8c843SAjit Kumar Pandey }
19458c8c843SAjit Kumar Pandey
renoir_audio_remove(struct platform_device * pdev)195da8a3cebSUwe Kleine-König static void renoir_audio_remove(struct platform_device *pdev)
19658c8c843SAjit Kumar Pandey {
19758c8c843SAjit Kumar Pandey struct device *dev = &pdev->dev;
198b24484c1SV sujith kumar Reddy struct acp_dev_data *adata = dev_get_drvdata(dev);
1996a75585aSAjit Kumar Pandey
200*fc11d326SSyed Saba Kareem acp_disable_interrupts(adata);
20158c8c843SAjit Kumar Pandey acp_platform_unregister(dev);
20258c8c843SAjit Kumar Pandey }
20358c8c843SAjit Kumar Pandey
20458c8c843SAjit Kumar Pandey static struct platform_driver renoir_driver = {
20558c8c843SAjit Kumar Pandey .probe = renoir_audio_probe,
206da8a3cebSUwe Kleine-König .remove_new = renoir_audio_remove,
20758c8c843SAjit Kumar Pandey .driver = {
20858c8c843SAjit Kumar Pandey .name = "acp_asoc_renoir",
20958c8c843SAjit Kumar Pandey },
21058c8c843SAjit Kumar Pandey };
21158c8c843SAjit Kumar Pandey
21258c8c843SAjit Kumar Pandey module_platform_driver(renoir_driver);
21358c8c843SAjit Kumar Pandey
21458c8c843SAjit Kumar Pandey MODULE_DESCRIPTION("AMD ACP Renoir Driver");
21558c8c843SAjit Kumar Pandey MODULE_IMPORT_NS(SND_SOC_ACP_COMMON);
21658c8c843SAjit Kumar Pandey MODULE_LICENSE("Dual BSD/GPL");
21758c8c843SAjit Kumar Pandey MODULE_ALIAS("platform:" DRV_NAME);
218