246 lines · c
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 or4// 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 block13 */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 25static 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 35static 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 45static 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 55static 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 63static 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 75static 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 87static struct acp_card_drvdata acp_dmic_data = {88 .dmic_cpu_id = DMIC,89 .dmic_codec_id = DMIC,90};91 92static 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 103static 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 else111 return ret;112}113 114static 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 else122 return ret;123}124 125static 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.c155 */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 }195out:196 return ret;197}198 199static 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};230MODULE_DEVICE_TABLE(platform, board_ids);231 232static struct platform_driver acp_asoc_audio = {233 .driver = {234 .pm = &snd_soc_pm_ops,235 .name = "acp_mach",236 },237 .probe = acp_asoc_probe,238 .id_table = board_ids,239};240 241module_platform_driver(acp_asoc_audio);242 243MODULE_IMPORT_NS(SND_SOC_AMD_MACH);244MODULE_DESCRIPTION("ACP chrome audio support");245MODULE_LICENSE("GPL v2");246