Commit | Line | Data |
---|---|---|
58c8c843 AKP |
1 | // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) |
2 | // | |
3 | // This file is provided under a dual BSD/GPLv2 license. When using or | |
4 | // redistributing this file, you may do so under either license. | |
5 | // | |
6 | // Copyright(c) 2021 Advanced Micro Devices, Inc. | |
7 | // | |
8 | // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> | |
9 | // | |
10 | ||
11 | /* | |
12 | * Hardware interface for Renoir ACP block | |
13 | */ | |
14 | ||
15 | #include <linux/platform_device.h> | |
16 | #include <linux/module.h> | |
17 | #include <linux/err.h> | |
18 | #include <linux/io.h> | |
19 | #include <sound/pcm_params.h> | |
20 | #include <sound/soc.h> | |
21 | #include <sound/soc-dai.h> | |
22 | #include <linux/dma-mapping.h> | |
23 | ||
24 | #include "amd.h" | |
25 | ||
26 | #define DRV_NAME "acp_asoc_renoir" | |
27 | ||
8a8e1b90 AKP |
28 | static struct snd_soc_acpi_codecs amp_rt1019 = { |
29 | .num_codecs = 1, | |
30 | .codecs = {"10EC1019"} | |
31 | }; | |
32 | ||
33 | static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp_machines[] = { | |
34 | { | |
35 | .id = "10EC5682", | |
36 | .drv_name = "rn_rt5682_rt1019", | |
37 | .machine_quirk = snd_soc_acpi_codec_list, | |
38 | .quirk_data = &_rt1019, | |
39 | }, | |
40 | { | |
41 | .id = "AMDI1019", | |
42 | .drv_name = "renoir-acp", | |
43 | }, | |
44 | {}, | |
45 | }; | |
46 | ||
58c8c843 AKP |
47 | static struct snd_soc_dai_driver acp_renoir_dai[] = { |
48 | { | |
49 | .name = "acp-i2s-sp", | |
50 | .id = I2S_SP_INSTANCE, | |
51 | .playback = { | |
52 | .stream_name = "I2S SP Playback", | |
53 | .rates = SNDRV_PCM_RATE_8000_96000, | |
54 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | | |
55 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, | |
56 | .channels_min = 2, | |
57 | .channels_max = 8, | |
58 | .rate_min = 8000, | |
59 | .rate_max = 96000, | |
60 | }, | |
61 | .capture = { | |
62 | .stream_name = "I2S SP Capture", | |
63 | .rates = SNDRV_PCM_RATE_8000_48000, | |
64 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | | |
65 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, | |
66 | .channels_min = 2, | |
67 | .channels_max = 2, | |
68 | .rate_min = 8000, | |
69 | .rate_max = 48000, | |
70 | }, | |
71 | .ops = &asoc_acp_cpu_dai_ops, | |
72 | .probe = &asoc_acp_i2s_probe, | |
73 | }, | |
74 | { | |
75 | .name = "acp-i2s-bt", | |
76 | .id = I2S_BT_INSTANCE, | |
77 | .playback = { | |
78 | .stream_name = "I2S BT Playback", | |
79 | .rates = SNDRV_PCM_RATE_8000_96000, | |
80 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | | |
81 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, | |
82 | .channels_min = 2, | |
83 | .channels_max = 8, | |
84 | .rate_min = 8000, | |
85 | .rate_max = 96000, | |
86 | }, | |
87 | .capture = { | |
88 | .stream_name = "I2S BT Capture", | |
89 | .rates = SNDRV_PCM_RATE_8000_48000, | |
90 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | | |
91 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, | |
92 | .channels_min = 2, | |
93 | .channels_max = 2, | |
94 | .rate_min = 8000, | |
95 | .rate_max = 48000, | |
96 | }, | |
97 | .ops = &asoc_acp_cpu_dai_ops, | |
98 | .probe = &asoc_acp_i2s_probe, | |
99 | }, | |
100 | }; | |
101 | ||
102 | static int renoir_audio_probe(struct platform_device *pdev) | |
103 | { | |
104 | struct device *dev = &pdev->dev; | |
105 | struct acp_dev_data *adata; | |
106 | struct resource *res; | |
107 | ||
108 | adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); | |
109 | if (!adata) | |
110 | return -ENOMEM; | |
111 | ||
112 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); | |
113 | if (!res) { | |
114 | dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); | |
115 | return -ENODEV; | |
116 | } | |
117 | ||
118 | adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | |
119 | if (!adata->acp_base) | |
120 | return -ENOMEM; | |
121 | ||
122 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); | |
123 | if (!res) { | |
124 | dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); | |
125 | return -ENODEV; | |
126 | } | |
127 | ||
128 | adata->i2s_irq = res->start; | |
129 | adata->dev = dev; | |
130 | adata->dai_driver = acp_renoir_dai; | |
131 | adata->num_dai = ARRAY_SIZE(acp_renoir_dai); | |
132 | ||
e646b51f AKP |
133 | adata->machines = snd_soc_acpi_amd_acp_machines; |
134 | acp_machine_select(adata); | |
135 | ||
58c8c843 AKP |
136 | dev_set_drvdata(dev, adata); |
137 | acp_platform_register(dev); | |
138 | ||
139 | return 0; | |
140 | } | |
141 | ||
142 | static int renoir_audio_remove(struct platform_device *pdev) | |
143 | { | |
144 | struct device *dev = &pdev->dev; | |
145 | ||
146 | acp_platform_unregister(dev); | |
147 | return 0; | |
148 | } | |
149 | ||
150 | static struct platform_driver renoir_driver = { | |
151 | .probe = renoir_audio_probe, | |
152 | .remove = renoir_audio_remove, | |
153 | .driver = { | |
154 | .name = "acp_asoc_renoir", | |
155 | }, | |
156 | }; | |
157 | ||
158 | module_platform_driver(renoir_driver); | |
159 | ||
160 | MODULE_DESCRIPTION("AMD ACP Renoir Driver"); | |
161 | MODULE_IMPORT_NS(SND_SOC_ACP_COMMON); | |
162 | MODULE_LICENSE("Dual BSD/GPL"); | |
163 | MODULE_ALIAS("platform:" DRV_NAME); |