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, 2023 Advanced Micro Devices, Inc. 7 // 8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> 9 // 10 11 /* 12 * SOF Machine Driver Support for ACP HW block 13 */ 14 15 #include <sound/core.h> 16 #include <sound/pcm_params.h> 17 #include <sound/soc-acpi.h> 18 #include <sound/soc-dapm.h> 19 #include <linux/dmi.h> 20 #include <linux/module.h> 21 22 #include "acp-mach.h" 23 24 static struct acp_card_drvdata sof_rt5682_rt1019_data = { 25 .hs_cpu_id = I2S_SP, 26 .amp_cpu_id = I2S_SP, 27 .dmic_cpu_id = DMIC, 28 .hs_codec_id = RT5682, 29 .amp_codec_id = RT1019, 30 .dmic_codec_id = DMIC, 31 }; 32 33 static struct acp_card_drvdata sof_rt5682_max_data = { 34 .hs_cpu_id = I2S_SP, 35 .amp_cpu_id = I2S_SP, 36 .dmic_cpu_id = DMIC, 37 .hs_codec_id = RT5682, 38 .amp_codec_id = MAX98360A, 39 .dmic_codec_id = DMIC, 40 }; 41 42 static struct acp_card_drvdata sof_rt5682s_rt1019_data = { 43 .hs_cpu_id = I2S_SP, 44 .amp_cpu_id = I2S_SP, 45 .dmic_cpu_id = DMIC, 46 .hs_codec_id = RT5682S, 47 .amp_codec_id = RT1019, 48 .dmic_codec_id = DMIC, 49 }; 50 51 static struct acp_card_drvdata sof_rt5682s_max_data = { 52 .hs_cpu_id = I2S_SP, 53 .amp_cpu_id = I2S_SP, 54 .dmic_cpu_id = DMIC, 55 .hs_codec_id = RT5682S, 56 .amp_codec_id = MAX98360A, 57 .dmic_codec_id = DMIC, 58 }; 59 60 static struct acp_card_drvdata sof_nau8825_data = { 61 .hs_cpu_id = I2S_HS, 62 .amp_cpu_id = I2S_HS, 63 .dmic_cpu_id = DMIC, 64 .hs_codec_id = NAU8825, 65 .amp_codec_id = MAX98360A, 66 .dmic_codec_id = DMIC, 67 .soc_mclk = true, 68 }; 69 70 static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { 71 .hs_cpu_id = I2S_HS, 72 .amp_cpu_id = I2S_HS, 73 .dmic_cpu_id = DMIC, 74 .hs_codec_id = RT5682S, 75 .amp_codec_id = RT1019, 76 .dmic_codec_id = DMIC, 77 .soc_mclk = true, 78 }; 79 80 static struct acp_card_drvdata sof_nau8821_max98388_data = { 81 .hs_cpu_id = I2S_SP, 82 .amp_cpu_id = I2S_HS, 83 .bt_cpu_id = I2S_BT, 84 .hs_codec_id = NAU8821, 85 .amp_codec_id = MAX98388, 86 .soc_mclk = true, 87 }; 88 89 static int acp_sof_probe(struct platform_device *pdev) 90 { 91 struct snd_soc_card *card = NULL; 92 struct device *dev = &pdev->dev; 93 struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev); 94 const struct dmi_system_id *dmi_id; 95 struct acp_card_drvdata *acp_card_drvdata; 96 int ret; 97 98 if (!pdev->id_entry) 99 return -EINVAL; 100 101 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 102 if (!card) 103 return -ENOMEM; 104 105 card->dev = dev; 106 card->owner = THIS_MODULE; 107 card->name = pdev->id_entry->name; 108 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data; 109 /* Widgets and controls added per-codec in acp-mach-common.c */ 110 111 acp_card_drvdata = card->drvdata; 112 dmi_id = dmi_first_match(acp_quirk_table); 113 if (dmi_id && dmi_id->driver_data) 114 acp_card_drvdata->tdm_mode = dmi_id->driver_data; 115 116 acp_card_drvdata->acp_rev = mach->mach_params.subsystem_rev; 117 ret = acp_sofdsp_dai_links_create(card); 118 if (ret) 119 return dev_err_probe(&pdev->dev, ret, "Failed to create DAI links\n"); 120 121 ret = devm_snd_soc_register_card(&pdev->dev, card); 122 if (ret) 123 return dev_err_probe(&pdev->dev, ret, 124 "Failed to register card(%s)\n", card->name); 125 return 0; 126 } 127 128 static const struct platform_device_id board_ids[] = { 129 { 130 .name = "rt5682-rt1019", 131 .driver_data = (kernel_ulong_t)&sof_rt5682_rt1019_data 132 }, 133 { 134 .name = "rt5682-max", 135 .driver_data = (kernel_ulong_t)&sof_rt5682_max_data 136 }, 137 { 138 .name = "rt5682s-max", 139 .driver_data = (kernel_ulong_t)&sof_rt5682s_max_data 140 }, 141 { 142 .name = "rt5682s-rt1019", 143 .driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data 144 }, 145 { 146 .name = "nau8825-max", 147 .driver_data = (kernel_ulong_t)&sof_nau8825_data 148 }, 149 { 150 .name = "rt5682s-hs-rt1019", 151 .driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data 152 }, 153 { 154 .name = "nau8821-max", 155 .driver_data = (kernel_ulong_t)&sof_nau8821_max98388_data 156 }, 157 { } 158 }; 159 MODULE_DEVICE_TABLE(platform, board_ids); 160 161 static struct platform_driver acp_asoc_audio = { 162 .driver = { 163 .name = "sof_mach", 164 .pm = &snd_soc_pm_ops, 165 }, 166 .probe = acp_sof_probe, 167 .id_table = board_ids, 168 }; 169 170 module_platform_driver(acp_asoc_audio); 171 172 MODULE_IMPORT_NS(SND_SOC_AMD_MACH); 173 MODULE_DESCRIPTION("ACP SOF Machine Driver"); 174 MODULE_LICENSE("GPL v2"); 175