From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom
---
kernel/sound/soc/intel/boards/bdw-rt5677.c | 183 +++++++++++++++++++++++++++++++++------------
1 files changed, 135 insertions(+), 48 deletions(-)
diff --git a/kernel/sound/soc/intel/boards/bdw-rt5677.c b/kernel/sound/soc/intel/boards/bdw-rt5677.c
index efcfd90..7a3e773 100644
--- a/kernel/sound/soc/intel/boards/bdw-rt5677.c
+++ b/kernel/sound/soc/intel/boards/bdw-rt5677.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* ASoC machine driver for Intel Broadwell platforms with RT5677 codec
*
* Copyright (c) 2014, The Chromium OS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/acpi.h>
@@ -26,9 +15,7 @@
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <sound/jack.h>
-
-#include "../common/sst-dsp.h"
-#include "../haswell/sst-haswell-ipc.h"
+#include <sound/soc-acpi.h>
#include "../../codecs/rt5677.h"
@@ -84,6 +71,11 @@
/* CODEC BE connections */
{"SSP0 CODEC IN", NULL, "AIF1 Capture"},
{"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
+ {"DSP Capture", NULL, "DSP Buffer"},
+
+ /* DSP Clock Connections */
+ { "DSP Buffer", NULL, "SSP0 CODEC IN" },
+ { "SSP0 CODEC IN", NULL, "DSPTX" },
};
static const struct snd_kcontrol_new bdw_rt5677_controls[] = {
@@ -145,13 +137,13 @@
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *channels = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_CHANNELS);
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *chan = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
/* The ADSP will covert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
- channels->min = channels->max = 2;
+ chan->min = chan->max = 2;
/* set SSP0 to 16 bit */
params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
@@ -161,8 +153,8 @@
static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000,
@@ -175,34 +167,67 @@
return ret;
}
-static const struct snd_soc_ops bdw_rt5677_ops = {
- .hw_params = bdw_rt5677_hw_params,
-};
-
-static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
+static int bdw_rt5677_dsp_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
{
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
- struct sst_pdata *pdata = dev_get_platdata(component->dev);
- struct sst_hsw *broadwell = pdata->dsp;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
- /* Set ADSP SSP port settings */
- ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0,
- SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
- SST_HSW_DEVICE_CLOCK_MASTER, 9);
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, 24576000,
+ SND_SOC_CLOCK_IN);
if (ret < 0) {
- dev_err(rtd->dev, "error: failed to set device config\n");
+ dev_err(rtd->dev, "can't set codec sysclk configuration\n");
+ return ret;
+ }
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT5677_PLL1_S_MCLK,
+ 24000000, 24576000);
+ if (ret < 0) {
+ dev_err(rtd->dev, "can't set codec pll configuration\n");
return ret;
}
return 0;
}
+static const struct snd_soc_ops bdw_rt5677_ops = {
+ .hw_params = bdw_rt5677_hw_params,
+};
+
+static const struct snd_soc_ops bdw_rt5677_dsp_ops = {
+ .hw_params = bdw_rt5677_dsp_hw_params,
+};
+
+static const unsigned int channels[] = {
+ 2,
+};
+
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
+ .count = ARRAY_SIZE(channels),
+ .list = channels,
+ .mask = 0,
+};
+
+static int bdw_rt5677_fe_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ /* Board supports stereo configuration only */
+ runtime->hw.channels_max = 2;
+ return snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &constraints_channels);
+}
+
+static const struct snd_soc_ops bdw_rt5677_fe_ops = {
+ .startup = bdw_rt5677_fe_startup,
+};
+
static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
{
struct bdw_rt5677_priv *bdw_rt5677 =
snd_soc_card_get_drvdata(rtd->card);
- struct snd_soc_component *component = rtd->codec_dai->component;
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
int ret;
@@ -216,10 +241,15 @@
rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER |
RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
RT5677_CLK_SEL_I2S1_ASRC);
+ /* Enable codec ASRC function for Mono ADC L.
+ * The ASRC clock source is clk_sys2_asrc.
+ */
+ rt5677_sel_asrc_clk_src(component, RT5677_AD_MONO_L_FILTER,
+ RT5677_CLK_SEL_SYS2);
/* Request rt5677 GPIO for headphone amp control */
- bdw_rt5677->gpio_hp_en = devm_gpiod_get(component->dev, "headphone-enable",
- GPIOD_OUT_LOW);
+ bdw_rt5677->gpio_hp_en = gpiod_get(component->dev, "headphone-enable",
+ GPIOD_OUT_LOW);
if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
dev_err(component->dev, "Can't find HP_AMP_SHDN_L gpio\n");
return PTR_ERR(bdw_rt5677->gpio_hp_en);
@@ -253,24 +283,65 @@
return 0;
}
+static void bdw_rt5677_exit(struct snd_soc_pcm_runtime *rtd)
+{
+ struct bdw_rt5677_priv *bdw_rt5677 =
+ snd_soc_card_get_drvdata(rtd->card);
+
+ /*
+ * The .exit() can be reached without going through the .init()
+ * so explicitly test if the gpiod is valid
+ */
+ if (!IS_ERR_OR_NULL(bdw_rt5677->gpio_hp_en))
+ gpiod_put(bdw_rt5677->gpio_hp_en);
+}
+
/* broadwell digital audio interface glue - connects codec <--> CPU */
+SND_SOC_DAILINK_DEF(dummy,
+ DAILINK_COMP_ARRAY(COMP_DUMMY()));
+
+SND_SOC_DAILINK_DEF(fe,
+ DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio")));
+
+SND_SOC_DAILINK_DEF(be,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-aif1")));
+
+SND_SOC_DAILINK_DEF(ssp0_port,
+ DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port")));
+
+/* Wake on voice interface */
+SND_SOC_DAILINK_DEFS(dsp,
+ DAILINK_COMP_ARRAY(COMP_CPU("spi-RT5677AA:00")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-dspbuffer")),
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("spi-RT5677AA:00")));
+
static struct snd_soc_dai_link bdw_rt5677_dais[] = {
/* Front End DAI links */
{
.name = "System PCM",
.stream_name = "System Playback/Capture",
- .cpu_dai_name = "System Pin",
- .platform_name = "haswell-pcm-audio",
+ .nonatomic = 1,
.dynamic = 1,
- .codec_name = "snd-soc-dummy",
- .codec_dai_name = "snd-soc-dummy-dai",
- .init = bdw_rt5677_rtd_init,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST
},
.dpcm_capture = 1,
.dpcm_playback = 1,
+ .ops = &bdw_rt5677_fe_ops,
+ SND_SOC_DAILINK_REG(fe, dummy, platform),
+ },
+
+ /* Non-DPCM links */
+ {
+ .name = "Codec DSP",
+ .stream_name = "Wake on Voice",
+ .capture_only = 1,
+ .ops = &bdw_rt5677_dsp_ops,
+ SND_SOC_DAILINK_REG(dsp),
},
/* Back End DAI links */
@@ -278,20 +349,17 @@
/* SSP0 - Codec */
.name = "Codec",
.id = 0,
- .cpu_dai_name = "snd-soc-dummy-dai",
- .platform_name = "snd-soc-dummy",
.no_pcm = 1,
- .codec_name = "i2c-RT5677CE:00",
- .codec_dai_name = "rt5677-aif1",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
- .ignore_suspend = 1,
.ignore_pmdown_time = 1,
.be_hw_params_fixup = broadwell_ssp0_fixup,
.ops = &bdw_rt5677_ops,
.dpcm_playback = 1,
.dpcm_capture = 1,
.init = bdw_rt5677_init,
+ .exit = bdw_rt5677_exit,
+ SND_SOC_DAILINK_REG(ssp0_port, be, platform),
},
};
@@ -319,9 +387,19 @@
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bdw rt5677" /* card name will be 'sof-bdw rt5677' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "bdw-rt5677"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* ASoC machine driver for Broadwell DSP + RT5677 */
static struct snd_soc_card bdw_rt5677_card = {
- .name = "bdw-rt5677",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = bdw_rt5677_dais,
.num_links = ARRAY_SIZE(bdw_rt5677_dais),
@@ -339,6 +417,8 @@
static int bdw_rt5677_probe(struct platform_device *pdev)
{
struct bdw_rt5677_priv *bdw_rt5677;
+ struct snd_soc_acpi_mach *mach;
+ int ret;
bdw_rt5677_card.dev = &pdev->dev;
@@ -350,6 +430,13 @@
return -ENOMEM;
}
+ /* override plaform name, if required */
+ mach = pdev->dev.platform_data;
+ ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card,
+ mach->mach_params.platform);
+ if (ret)
+ return ret;
+
snd_soc_card_set_drvdata(&bdw_rt5677_card, bdw_rt5677);
return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5677_card);
--
Gitblit v1.6.2