[PATCH] CHROMIUM:ASOC: amd: Add Machine driver Support for rt5682s codec

From: V sujith kumar Reddy
Date: Mon Jan 17 2022 - 07:06:52 EST


Add sound card support with rt5682s as headset codec and max98357 as
speaker amp codec on Raven based chrome platform

Signed-off-by: V sujith kumar Reddy <vsujithkumar.reddy@xxxxxxx>
---
sound/soc/amd/Kconfig | 1 +
sound/soc/amd/acp3x-rt5682-max9836.c | 111 ++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index 7a9e45094f37..5eb855eb4b7e 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -36,6 +36,7 @@ config SND_SOC_AMD_RV_RT5682_MACH
select SND_SOC_MAX98357A
select SND_SOC_CROS_EC_CODEC
select I2C_CROS_EC_TUNNEL
+ select SND_SOC_RT5682S
select SND_SOC_RT1015
select SND_SOC_RT1015P
depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC && GPIOLIB
diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c
index dad70436d063..9b74b2a8da26 100644
--- a/sound/soc/amd/acp3x-rt5682-max9836.c
+++ b/sound/soc/amd/acp3x-rt5682-max9836.c
@@ -20,6 +20,7 @@
#include <linux/acpi.h>

#include "raven/acp3x.h"
+#include "../codecs/rt5682s.h"
#include "../codecs/rt5682.h"
#include "../codecs/rt1015.h"

@@ -39,6 +40,77 @@ enum {
EC,
};

+static int acp3x_5682s_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_component *component = codec_dai->component;
+
+ dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
+
+ /* set rt5682s dai fmt */
+ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
+ | SND_SOC_DAIFMT_NB_NF
+ | SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "Failed to set rt5682s dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ /* set codec PLL */
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
+ PCO_PLAT_CLK, RT5682_PLL_FREQ);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set rt5682s PLL: %d\n", ret);
+ return ret;
+ }
+
+ /* Set codec sysclk */
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
+ RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "Failed to set rt5682s SYSCLK: %d\n", ret);
+ return ret;
+ }
+
+ /* Set tdm/i2s1 master bclk ratio */
+ ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "Failed to set rt5682s tdm bclk ratio: %d\n", ret);
+ return ret;
+ }
+
+ rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk");
+ rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk");
+
+ ret = snd_soc_card_jack_new(card, "Headset Jack",
+ SND_JACK_HEADSET | SND_JACK_LINEOUT |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &pco_jack, NULL, 0);
+ if (ret) {
+ dev_err(card->dev, "HP jack creation failed %d\n", ret);
+ return ret;
+ }
+
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+ ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
+ if (ret) {
+ dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
@@ -271,6 +343,8 @@ SND_SOC_DAILINK_DEF(acp3x_i2s,
SND_SOC_DAILINK_DEF(acp3x_bt,
DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.2")));

+SND_SOC_DAILINK_DEF(rt5682s,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
SND_SOC_DAILINK_DEF(rt5682,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
SND_SOC_DAILINK_DEF(max,
@@ -458,6 +532,19 @@ static struct snd_soc_card acp3x_1015p = {
.num_controls = ARRAY_SIZE(acp3x_mc_1015p_controls),
};

+static struct snd_soc_card acp3x_5682s = {
+ .name = "acp3xrt5682s98357",
+ .owner = THIS_MODULE,
+ .dai_link = acp3x_dai,
+ .num_links = ARRAY_SIZE(acp3x_dai),
+ .dapm_widgets = acp3x_1015p_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp3x_1015p_widgets),
+ .dapm_routes = acp3x_1015p_route,
+ .num_dapm_routes = ARRAY_SIZE(acp3x_1015p_route),
+ .controls = acp3x_mc_1015p_controls,
+ .num_controls = ARRAY_SIZE(acp3x_mc_1015p_controls),
+};
+
void *soc_is_rltk_max(struct device *dev)
{
const struct acpi_device_id *match;
@@ -468,6 +555,27 @@ void *soc_is_rltk_max(struct device *dev)
return (void *)match->driver_data;
}

+static void card_hs_dai_link_present(struct snd_soc_dai_link *links,
+ const char *card_name)
+{
+ if (!strcmp(card_name, "acp3xrt5682s98357")) {
+ links[0].name = "acp3x-5682s-play";
+ links[0].stream_name = "Playback";
+ links[0].dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM;
+
+ links[0].codecs = rt5682s;
+ links[0].num_codecs = ARRAY_SIZE(rt5682s);
+ links[0].init = acp3x_5682s_init;
+ links[0].dpcm_playback = 1;
+ links[0].dpcm_capture = 1;
+ links[0].cpus = acp3x_i2s;
+ links[0].num_cpus = ARRAY_SIZE(acp3x_i2s);
+ links[0].platforms = platform;
+ links[0].num_platforms = ARRAY_SIZE(platform);
+ }
+}
+
static void card_spk_dai_link_present(struct snd_soc_dai_link *links,
const char *card_name)
{
@@ -497,7 +605,7 @@ static int acp3x_probe(struct platform_device *pdev)
machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL);
if (!machine)
return -ENOMEM;
-
+ card_hs_dai_link_present(card->dai_link, card->name);
card_spk_dai_link_present(card->dai_link, card->name);
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
@@ -523,6 +631,7 @@ static const struct acpi_device_id acp3x_audio_acpi_match[] = {
{ "AMDI5682", (unsigned long)&acp3x_5682},
{ "AMDI1015", (unsigned long)&acp3x_1015},
{ "10021015", (unsigned long)&acp3x_1015p},
+ { "10029835", (unsigned long)&acp3x_5682s},
{},
};
MODULE_DEVICE_TABLE(acpi, acp3x_audio_acpi_match);
--
2.25.1