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 .tdm_mode = false, 32 }; 33 34 static struct acp_card_drvdata sof_rt5682_max_data = { 35 .hs_cpu_id = I2S_SP, 36 .amp_cpu_id = I2S_SP, 37 .dmic_cpu_id = DMIC, 38 .hs_codec_id = RT5682, 39 .amp_codec_id = MAX98360A, 40 .dmic_codec_id = DMIC, 41 .tdm_mode = false, 42 }; 43 44 static struct acp_card_drvdata sof_rt5682s_rt1019_data = { 45 .hs_cpu_id = I2S_SP, 46 .amp_cpu_id = I2S_SP, 47 .dmic_cpu_id = DMIC, 48 .hs_codec_id = RT5682S, 49 .amp_codec_id = RT1019, 50 .dmic_codec_id = DMIC, 51 .platform = RENOIR, 52 .tdm_mode = false, 53 }; 54 55 static struct acp_card_drvdata sof_rt5682s_max_data = { 56 .hs_cpu_id = I2S_SP, 57 .amp_cpu_id = I2S_SP, 58 .dmic_cpu_id = DMIC, 59 .hs_codec_id = RT5682S, 60 .amp_codec_id = MAX98360A, 61 .dmic_codec_id = DMIC, 62 .platform = RENOIR, 63 .tdm_mode = false, 64 }; 65 66 static struct acp_card_drvdata sof_nau8825_data = { 67 .hs_cpu_id = I2S_HS, 68 .amp_cpu_id = I2S_HS, 69 .dmic_cpu_id = DMIC, 70 .hs_codec_id = NAU8825, 71 .amp_codec_id = MAX98360A, 72 .dmic_codec_id = DMIC, 73 .platform = REMBRANDT, 74 .soc_mclk = true, 75 .tdm_mode = false, 76 }; 77 78 static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { 79 .hs_cpu_id = I2S_HS, 80 .amp_cpu_id = I2S_HS, 81 .dmic_cpu_id = DMIC, 82 .hs_codec_id = RT5682S, 83 .amp_codec_id = RT1019, 84 .dmic_codec_id = DMIC, 85 .platform = REMBRANDT, 86 .soc_mclk = true, 87 .tdm_mode = false, 88 }; 89 90 static struct acp_card_drvdata sof_nau8821_max98388_data = { 91 .hs_cpu_id = I2S_SP, 92 .amp_cpu_id = I2S_HS, 93 .bt_cpu_id = I2S_BT, 94 .dmic_cpu_id = NONE, 95 .hs_codec_id = NAU8821, 96 .amp_codec_id = MAX98388, 97 .bt_codec_id = NONE, 98 .dmic_codec_id = NONE, 99 .soc_mclk = true, 100 .tdm_mode = false, 101 }; 102 103 static int acp_sof_probe(struct platform_device *pdev) 104 { 105 struct snd_soc_card *card = NULL; 106 struct device *dev = &pdev->dev; 107 const struct dmi_system_id *dmi_id; 108 struct acp_card_drvdata *acp_card_drvdata; 109 int ret; 110 111 if (!pdev->id_entry) 112 return -EINVAL; 113 114 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 115 if (!card) 116 return -ENOMEM; 117 118 card->dev = dev; 119 card->owner = THIS_MODULE; 120 card->name = pdev->id_entry->name; 121 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data; 122 /* Widgets and controls added per-codec in acp-mach-common.c */ 123 124 acp_card_drvdata = card->drvdata; 125 dmi_id = dmi_first_match(acp_quirk_table); 126 if (dmi_id && dmi_id->driver_data) 127 acp_card_drvdata->tdm_mode = dmi_id->driver_data; 128 129 acp_sofdsp_dai_links_create(card); 130 131 ret = devm_snd_soc_register_card(&pdev->dev, card); 132 if (ret) { 133 dev_err(&pdev->dev, 134 "devm_snd_soc_register_card(%s) failed: %d\n", 135 card->name, ret); 136 return ret; 137 } 138 139 return 0; 140 } 141 142 static const struct platform_device_id board_ids[] = { 143 { 144 .name = "rt5682-rt1019", 145 .driver_data = (kernel_ulong_t)&sof_rt5682_rt1019_data 146 }, 147 { 148 .name = "rt5682-max", 149 .driver_data = (kernel_ulong_t)&sof_rt5682_max_data 150 }, 151 { 152 .name = "rt5682s-max", 153 .driver_data = (kernel_ulong_t)&sof_rt5682s_max_data 154 }, 155 { 156 .name = "rt5682s-rt1019", 157 .driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data 158 }, 159 { 160 .name = "nau8825-max", 161 .driver_data = (kernel_ulong_t)&sof_nau8825_data 162 }, 163 { 164 .name = "rt5682s-hs-rt1019", 165 .driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data 166 }, 167 { 168 .name = "nau8821-max", 169 .driver_data = (kernel_ulong_t)&sof_nau8821_max98388_data 170 }, 171 { } 172 }; 173 static struct platform_driver acp_asoc_audio = { 174 .driver = { 175 .name = "sof_mach", 176 .pm = &snd_soc_pm_ops, 177 }, 178 .probe = acp_sof_probe, 179 .id_table = board_ids, 180 }; 181 182 module_platform_driver(acp_asoc_audio); 183 184 MODULE_IMPORT_NS(SND_SOC_AMD_MACH); 185 MODULE_DESCRIPTION("ACP chrome SOF audio support"); 186 MODULE_ALIAS("platform:rt5682-rt1019"); 187 MODULE_ALIAS("platform:rt5682-max"); 188 MODULE_ALIAS("platform:rt5682s-max"); 189 MODULE_ALIAS("platform:rt5682s-rt1019"); 190 MODULE_ALIAS("platform:nau8825-max"); 191 MODULE_ALIAS("platform:rt5682s-hs-rt1019"); 192 MODULE_ALIAS("platform:nau8821-max"); 193 MODULE_LICENSE("GPL v2"); 194