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, "21D0"), 53 } 54 }, 55 { 56 .driver_data = &acp6x_card, 57 .matches = { 58 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 59 DMI_MATCH(DMI_PRODUCT_NAME, "21D0"), 60 } 61 }, 62 { 63 .driver_data = &acp6x_card, 64 .matches = { 65 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 66 DMI_MATCH(DMI_PRODUCT_NAME, "21D1"), 67 } 68 }, 69 { 70 .driver_data = &acp6x_card, 71 .matches = { 72 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 73 DMI_MATCH(DMI_PRODUCT_NAME, "21D2"), 74 } 75 }, 76 { 77 .driver_data = &acp6x_card, 78 .matches = { 79 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 80 DMI_MATCH(DMI_PRODUCT_NAME, "21D3"), 81 } 82 }, 83 { 84 .driver_data = &acp6x_card, 85 .matches = { 86 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 87 DMI_MATCH(DMI_PRODUCT_NAME, "21D4"), 88 } 89 }, 90 { 91 .driver_data = &acp6x_card, 92 .matches = { 93 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 94 DMI_MATCH(DMI_PRODUCT_NAME, "21D5"), 95 } 96 }, 97 { 98 .driver_data = &acp6x_card, 99 .matches = { 100 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 101 DMI_MATCH(DMI_PRODUCT_NAME, "21CF"), 102 } 103 }, 104 { 105 .driver_data = &acp6x_card, 106 .matches = { 107 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 108 DMI_MATCH(DMI_PRODUCT_NAME, "21CG"), 109 } 110 }, 111 { 112 .driver_data = &acp6x_card, 113 .matches = { 114 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 115 DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"), 116 } 117 }, 118 { 119 .driver_data = &acp6x_card, 120 .matches = { 121 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 122 DMI_MATCH(DMI_PRODUCT_NAME, "21CR"), 123 } 124 }, 125 { 126 .driver_data = &acp6x_card, 127 .matches = { 128 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 129 DMI_MATCH(DMI_PRODUCT_NAME, "21CM"), 130 } 131 }, 132 { 133 .driver_data = &acp6x_card, 134 .matches = { 135 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 136 DMI_MATCH(DMI_PRODUCT_NAME, "21CN"), 137 } 138 }, 139 { 140 .driver_data = &acp6x_card, 141 .matches = { 142 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 143 DMI_MATCH(DMI_PRODUCT_NAME, "21CH"), 144 } 145 }, 146 { 147 .driver_data = &acp6x_card, 148 .matches = { 149 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 150 DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"), 151 } 152 }, 153 { 154 .driver_data = &acp6x_card, 155 .matches = { 156 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 157 DMI_MATCH(DMI_PRODUCT_NAME, "21CK"), 158 } 159 }, 160 { 161 .driver_data = &acp6x_card, 162 .matches = { 163 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 164 DMI_MATCH(DMI_PRODUCT_NAME, "21CL"), 165 } 166 }, 167 { 168 .driver_data = &acp6x_card, 169 .matches = { 170 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 171 DMI_MATCH(DMI_PRODUCT_NAME, "21EM"), 172 } 173 }, 174 { 175 .driver_data = &acp6x_card, 176 .matches = { 177 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 178 DMI_MATCH(DMI_PRODUCT_NAME, "21EN"), 179 } 180 }, 181 { 182 .driver_data = &acp6x_card, 183 .matches = { 184 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 185 DMI_MATCH(DMI_PRODUCT_NAME, "21J5"), 186 } 187 }, 188 { 189 .driver_data = &acp6x_card, 190 .matches = { 191 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 192 DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), 193 } 194 }, 195 { 196 .driver_data = &acp6x_card, 197 .matches = { 198 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 199 DMI_MATCH(DMI_PRODUCT_NAME, "82"), 200 } 201 }, 202 { 203 .driver_data = &acp6x_card, 204 .matches = { 205 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), 206 DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"), 207 } 208 }, 209 { 210 .driver_data = &acp6x_card, 211 .matches = { 212 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), 213 DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"), 214 } 215 }, 216 { 217 .driver_data = &acp6x_card, 218 .matches = { 219 DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"), 220 DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), 221 } 222 }, 223 { 224 .driver_data = &acp6x_card, 225 .matches = { 226 DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"), 227 DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"), 228 } 229 }, 230 { 231 .driver_data = &acp6x_card, 232 .matches = { 233 DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"), 234 DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"), 235 } 236 }, 237 { 238 .driver_data = &acp6x_card, 239 .matches = { 240 DMI_MATCH(DMI_BOARD_VENDOR, "Razer"), 241 DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"), 242 } 243 }, 244 { 245 .driver_data = &acp6x_card, 246 .matches = { 247 DMI_MATCH(DMI_BOARD_VENDOR, "RB"), 248 DMI_MATCH(DMI_PRODUCT_NAME, "Swift SFA16-41"), 249 } 250 }, 251 { 252 .driver_data = &acp6x_card, 253 .matches = { 254 DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"), 255 DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"), 256 } 257 }, 258 { 259 .driver_data = &acp6x_card, 260 .matches = { 261 DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 262 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"), 263 } 264 }, 265 { 266 .driver_data = &acp6x_card, 267 .matches = { 268 DMI_MATCH(DMI_BOARD_VENDOR, "HP"), 269 DMI_MATCH(DMI_BOARD_NAME, "8A43"), 270 } 271 }, 272 {} 273 }; 274 275 static int acp6x_probe(struct platform_device *pdev) 276 { 277 const struct dmi_system_id *dmi_id; 278 struct acp6x_pdm *machine = NULL; 279 struct snd_soc_card *card; 280 struct acpi_device *adev; 281 int ret; 282 283 /* check the parent device's firmware node has _DSD or not */ 284 adev = ACPI_COMPANION(pdev->dev.parent); 285 if (adev) { 286 const union acpi_object *obj; 287 288 if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) && 289 obj->integer.value == 1) 290 platform_set_drvdata(pdev, &acp6x_card); 291 } 292 293 /* check for any DMI overrides */ 294 dmi_id = dmi_first_match(yc_acp_quirk_table); 295 if (dmi_id) 296 platform_set_drvdata(pdev, dmi_id->driver_data); 297 298 card = platform_get_drvdata(pdev); 299 if (!card) 300 return -ENODEV; 301 dev_info(&pdev->dev, "Enabling ACP DMIC support via %s", dmi_id ? "DMI" : "ACPI"); 302 acp6x_card.dev = &pdev->dev; 303 304 snd_soc_card_set_drvdata(card, machine); 305 ret = devm_snd_soc_register_card(&pdev->dev, card); 306 if (ret) { 307 return dev_err_probe(&pdev->dev, ret, 308 "snd_soc_register_card(%s) failed\n", 309 card->name); 310 } 311 return 0; 312 } 313 314 static struct platform_driver acp6x_mach_driver = { 315 .driver = { 316 .name = "acp_yc_mach", 317 .pm = &snd_soc_pm_ops, 318 }, 319 .probe = acp6x_probe, 320 }; 321 322 module_platform_driver(acp6x_mach_driver); 323 324 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 325 MODULE_LICENSE("GPL v2"); 326 MODULE_ALIAS("platform:" DRV_NAME); 327