Merge branches 'clk-baikal', 'clk-broadcom', 'clk-vc5' and 'clk-versaclock' into...
[platform/kernel/linux-starfive.git] / sound / soc / amd / yc / acp6x-mach.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Machine driver for AMD Yellow Carp platform using DMIC
4  *
5  * Copyright 2021 Advanced Micro Devices, Inc.
6  */
7
8 #include <sound/soc.h>
9 #include <sound/soc-dapm.h>
10 #include <linux/module.h>
11 #include <sound/pcm.h>
12 #include <sound/pcm_params.h>
13 #include <linux/io.h>
14 #include <linux/dmi.h>
15 #include <linux/acpi.h>
16
17 #include "acp6x.h"
18
19 #define DRV_NAME "acp_yc_mach"
20
21 SND_SOC_DAILINK_DEF(acp6x_pdm,
22                     DAILINK_COMP_ARRAY(COMP_CPU("acp_yc_pdm_dma.0")));
23
24 SND_SOC_DAILINK_DEF(dmic_codec,
25                     DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
26                                                   "dmic-hifi")));
27
28 SND_SOC_DAILINK_DEF(pdm_platform,
29                     DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_yc_pdm_dma.0")));
30
31 static struct snd_soc_dai_link acp6x_dai_pdm[] = {
32         {
33                 .name = "acp6x-dmic-capture",
34                 .stream_name = "DMIC capture",
35                 .capture_only = 1,
36                 SND_SOC_DAILINK_REG(acp6x_pdm, dmic_codec, pdm_platform),
37         },
38 };
39
40 static struct snd_soc_card acp6x_card = {
41         .name = "acp6x",
42         .owner = THIS_MODULE,
43         .dai_link = acp6x_dai_pdm,
44         .num_links = 1,
45 };
46
47 static const struct dmi_system_id yc_acp_quirk_table[] = {
48         {
49                 .driver_data = &acp6x_card,
50                 .matches = {
51                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
52                         DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
53                 }
54         },
55         {
56                 .driver_data = &acp6x_card,
57                 .matches = {
58                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
59                         DMI_MATCH(DMI_PRODUCT_NAME, "21D3"),
60                 }
61         },
62         {
63                 .driver_data = &acp6x_card,
64                 .matches = {
65                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
66                         DMI_MATCH(DMI_PRODUCT_NAME, "21D4"),
67                 }
68         },
69         {
70                 .driver_data = &acp6x_card,
71                 .matches = {
72                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
73                         DMI_MATCH(DMI_PRODUCT_NAME, "21D5"),
74                 }
75         },
76         {
77                 .driver_data = &acp6x_card,
78                 .matches = {
79                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
80                         DMI_MATCH(DMI_PRODUCT_NAME, "21CF"),
81                 }
82         },
83         {
84                 .driver_data = &acp6x_card,
85                 .matches = {
86                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
87                         DMI_MATCH(DMI_PRODUCT_NAME, "21CG"),
88                 }
89         },
90         {
91                 .driver_data = &acp6x_card,
92                 .matches = {
93                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
94                         DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"),
95                 }
96         },
97         {
98                 .driver_data = &acp6x_card,
99                 .matches = {
100                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
101                         DMI_MATCH(DMI_PRODUCT_NAME, "21CR"),
102                 }
103         },
104         {
105                 .driver_data = &acp6x_card,
106                 .matches = {
107                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
108                         DMI_MATCH(DMI_PRODUCT_NAME, "21CM"),
109                 }
110         },
111         {
112                 .driver_data = &acp6x_card,
113                 .matches = {
114                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
115                         DMI_MATCH(DMI_PRODUCT_NAME, "21CN"),
116                 }
117         },
118         {
119                 .driver_data = &acp6x_card,
120                 .matches = {
121                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
122                         DMI_MATCH(DMI_PRODUCT_NAME, "21CH"),
123                 }
124         },
125         {
126                 .driver_data = &acp6x_card,
127                 .matches = {
128                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
129                         DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"),
130                 }
131         },
132         {
133                 .driver_data = &acp6x_card,
134                 .matches = {
135                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
136                         DMI_MATCH(DMI_PRODUCT_NAME, "21CK"),
137                 }
138         },
139         {
140                 .driver_data = &acp6x_card,
141                 .matches = {
142                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
143                         DMI_MATCH(DMI_PRODUCT_NAME, "21CL"),
144                 }
145         },
146         {
147                 .driver_data = &acp6x_card,
148                 .matches = {
149                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
150                         DMI_MATCH(DMI_PRODUCT_NAME, "21EM"),
151                 }
152         },
153         {
154                 .driver_data = &acp6x_card,
155                 .matches = {
156                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
157                         DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
158                 }
159         },
160         {
161                 .driver_data = &acp6x_card,
162                 .matches = {
163                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
164                         DMI_MATCH(DMI_PRODUCT_NAME, "21J5"),
165                 }
166         },
167         {
168                 .driver_data = &acp6x_card,
169                 .matches = {
170                         DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
171                         DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
172                 }
173         },
174         {}
175 };
176
177 static int acp6x_probe(struct platform_device *pdev)
178 {
179         const struct dmi_system_id *dmi_id;
180         struct acp6x_pdm *machine = NULL;
181         struct snd_soc_card *card;
182         struct acpi_device *adev;
183         int ret;
184
185         /* check the parent device's firmware node has _DSD or not */
186         adev = ACPI_COMPANION(pdev->dev.parent);
187         if (adev) {
188                 const union acpi_object *obj;
189
190                 if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
191                     obj->integer.value == 1)
192                         platform_set_drvdata(pdev, &acp6x_card);
193         }
194
195         /* check for any DMI overrides */
196         dmi_id = dmi_first_match(yc_acp_quirk_table);
197         if (dmi_id)
198                 platform_set_drvdata(pdev, dmi_id->driver_data);
199
200         card = platform_get_drvdata(pdev);
201         if (!card)
202                 return -ENODEV;
203         dev_info(&pdev->dev, "Enabling ACP DMIC support via %s", dmi_id ? "DMI" : "ACPI");
204         acp6x_card.dev = &pdev->dev;
205
206         snd_soc_card_set_drvdata(card, machine);
207         ret = devm_snd_soc_register_card(&pdev->dev, card);
208         if (ret) {
209                 return dev_err_probe(&pdev->dev, ret,
210                                 "snd_soc_register_card(%s) failed\n",
211                                 card->name);
212         }
213         return 0;
214 }
215
216 static struct platform_driver acp6x_mach_driver = {
217         .driver = {
218                 .name = "acp_yc_mach",
219                 .pm = &snd_soc_pm_ops,
220         },
221         .probe = acp6x_probe,
222 };
223
224 module_platform_driver(acp6x_mach_driver);
225
226 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
227 MODULE_LICENSE("GPL v2");
228 MODULE_ALIAS("platform:" DRV_NAME);