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 * Machine Driver Legacy 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 #include "acp3x-es83xx/acp3x-es83xx.h" 24 25 static struct acp_card_drvdata rt5682_rt1019_data = { 26 .hs_cpu_id = I2S_SP, 27 .amp_cpu_id = I2S_SP, 28 .dmic_cpu_id = DMIC, 29 .hs_codec_id = RT5682, 30 .amp_codec_id = RT1019, 31 .dmic_codec_id = DMIC, 32 .tdm_mode = false, 33 }; 34 35 static struct acp_card_drvdata rt5682s_max_data = { 36 .hs_cpu_id = I2S_SP, 37 .amp_cpu_id = I2S_SP, 38 .dmic_cpu_id = DMIC, 39 .hs_codec_id = RT5682S, 40 .amp_codec_id = MAX98360A, 41 .dmic_codec_id = DMIC, 42 .tdm_mode = false, 43 }; 44 45 static struct acp_card_drvdata rt5682s_rt1019_data = { 46 .hs_cpu_id = I2S_SP, 47 .amp_cpu_id = I2S_SP, 48 .dmic_cpu_id = DMIC, 49 .hs_codec_id = RT5682S, 50 .amp_codec_id = RT1019, 51 .dmic_codec_id = DMIC, 52 .tdm_mode = false, 53 }; 54 55 static struct acp_card_drvdata es83xx_rn_data = { 56 .hs_cpu_id = I2S_SP, 57 .dmic_cpu_id = DMIC, 58 .hs_codec_id = ES83XX, 59 .dmic_codec_id = DMIC, 60 .platform = RENOIR, 61 }; 62 63 static struct acp_card_drvdata max_nau8825_data = { 64 .hs_cpu_id = I2S_HS, 65 .amp_cpu_id = I2S_HS, 66 .dmic_cpu_id = DMIC, 67 .hs_codec_id = NAU8825, 68 .amp_codec_id = MAX98360A, 69 .dmic_codec_id = DMIC, 70 .soc_mclk = true, 71 .platform = REMBRANDT, 72 .tdm_mode = false, 73 }; 74 75 static struct acp_card_drvdata rt5682s_rt1019_rmb_data = { 76 .hs_cpu_id = I2S_HS, 77 .amp_cpu_id = I2S_HS, 78 .dmic_cpu_id = DMIC, 79 .hs_codec_id = RT5682S, 80 .amp_codec_id = RT1019, 81 .dmic_codec_id = DMIC, 82 .soc_mclk = true, 83 .platform = REMBRANDT, 84 .tdm_mode = false, 85 }; 86 87 static struct acp_card_drvdata acp_dmic_data = { 88 .dmic_cpu_id = DMIC, 89 .dmic_codec_id = DMIC, 90 }; 91 92 static bool acp_asoc_init_ops(struct acp_card_drvdata *priv) 93 { 94 bool has_ops = false; 95 96 if (priv->hs_codec_id == ES83XX) { 97 has_ops = true; 98 acp3x_es83xx_init_ops(&priv->ops); 99 } 100 return has_ops; 101 } 102 103 static int acp_asoc_suspend_pre(struct snd_soc_card *card) 104 { 105 int ret; 106 107 ret = acp_ops_suspend_pre(card); 108 if (ret == 1) 109 return 0; 110 else 111 return ret; 112 } 113 114 static int acp_asoc_resume_post(struct snd_soc_card *card) 115 { 116 int ret; 117 118 ret = acp_ops_resume_post(card); 119 if (ret == 1) 120 return 0; 121 else 122 return ret; 123 } 124 125 static int acp_asoc_probe(struct platform_device *pdev) 126 { 127 struct snd_soc_card *card = NULL; 128 struct device *dev = &pdev->dev; 129 const struct dmi_system_id *dmi_id; 130 struct acp_card_drvdata *acp_card_drvdata; 131 int ret; 132 133 if (!pdev->id_entry) { 134 ret = -EINVAL; 135 goto out; 136 } 137 138 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 139 if (!card) { 140 ret = -ENOMEM; 141 goto out; 142 } 143 144 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data; 145 acp_card_drvdata = card->drvdata; 146 acp_card_drvdata->acpi_mach = (struct snd_soc_acpi_mach *)pdev->dev.platform_data; 147 card->dev = dev; 148 card->owner = THIS_MODULE; 149 card->name = pdev->id_entry->name; 150 151 acp_asoc_init_ops(card->drvdata); 152 153 /* If widgets and controls are not set in specific callback, 154 * they will be added per-codec in acp-mach-common.c 155 */ 156 ret = acp_ops_configure_widgets(card); 157 if (ret < 0) { 158 dev_err(&pdev->dev, 159 "Cannot configure widgets for card (%s): %d\n", 160 card->name, ret); 161 goto out; 162 } 163 card->suspend_pre = acp_asoc_suspend_pre; 164 card->resume_post = acp_asoc_resume_post; 165 166 ret = acp_ops_probe(card); 167 if (ret < 0) { 168 dev_err(&pdev->dev, 169 "Cannot probe card (%s): %d\n", 170 card->name, ret); 171 goto out; 172 } 173 if (!strcmp(pdev->name, "acp-pdm-mach")) 174 acp_card_drvdata->platform = *((int *)dev->platform_data); 175 176 dmi_id = dmi_first_match(acp_quirk_table); 177 if (dmi_id && dmi_id->driver_data) 178 acp_card_drvdata->tdm_mode = dmi_id->driver_data; 179 180 ret = acp_legacy_dai_links_create(card); 181 if (ret) { 182 dev_err(&pdev->dev, 183 "Cannot create dai links for card (%s): %d\n", 184 card->name, ret); 185 goto out; 186 } 187 188 ret = devm_snd_soc_register_card(&pdev->dev, card); 189 if (ret) { 190 dev_err(&pdev->dev, 191 "devm_snd_soc_register_card(%s) failed: %d\n", 192 card->name, ret); 193 goto out; 194 } 195 out: 196 return ret; 197 } 198 199 static const struct platform_device_id board_ids[] = { 200 { 201 .name = "acp3xalc56821019", 202 .driver_data = (kernel_ulong_t)&rt5682_rt1019_data, 203 }, 204 { 205 .name = "acp3xalc5682sm98360", 206 .driver_data = (kernel_ulong_t)&rt5682s_max_data, 207 }, 208 { 209 .name = "acp3xalc5682s1019", 210 .driver_data = (kernel_ulong_t)&rt5682s_rt1019_data, 211 }, 212 { 213 .name = "acp3x-es83xx", 214 .driver_data = (kernel_ulong_t)&es83xx_rn_data, 215 }, 216 { 217 .name = "rmb-nau8825-max", 218 .driver_data = (kernel_ulong_t)&max_nau8825_data, 219 }, 220 { 221 .name = "rmb-rt5682s-rt1019", 222 .driver_data = (kernel_ulong_t)&rt5682s_rt1019_rmb_data, 223 }, 224 { 225 .name = "acp-pdm-mach", 226 .driver_data = (kernel_ulong_t)&acp_dmic_data, 227 }, 228 { } 229 }; 230 static struct platform_driver acp_asoc_audio = { 231 .driver = { 232 .pm = &snd_soc_pm_ops, 233 .name = "acp_mach", 234 }, 235 .probe = acp_asoc_probe, 236 .id_table = board_ids, 237 }; 238 239 module_platform_driver(acp_asoc_audio); 240 241 MODULE_IMPORT_NS(SND_SOC_AMD_MACH); 242 MODULE_DESCRIPTION("ACP chrome audio support"); 243 MODULE_ALIAS("platform:acp3xalc56821019"); 244 MODULE_ALIAS("platform:acp3xalc5682sm98360"); 245 MODULE_ALIAS("platform:acp3xalc5682s1019"); 246 MODULE_ALIAS("platform:acp3x-es83xx"); 247 MODULE_ALIAS("platform:rmb-nau8825-max"); 248 MODULE_ALIAS("platform:rmb-rt5682s-rt1019"); 249 MODULE_ALIAS("platform:acp-pdm-mach"); 250 MODULE_LICENSE("GPL v2"); 251