[alsa-devel] [PATCH 1/2] ASoC: Intel: sof-rt5682: add MCLK support for BYT platform
From: Xun Zhang xun2.zhang@intel.com
The sof-rt5682 machine driver currently uses BCLK on BYT/Minnowboard platform. The MCLK signal is available since the Turbot revision, so enable MCLK on BYT/Minnowboard Turbot platform.
Signed-off-by: Xun Zhang xun2.zhang@intel.com Signed-off-by: Bard liao yung-chuan.liao@linux.intel.com --- sound/soc/intel/boards/sof_rt5682.c | 65 ++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index e2e5f97d9920..f3d481b75b15 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -9,6 +9,7 @@ #include <linux/input.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/clk.h> #include <linux/dmi.h> #include <sound/core.h> #include <sound/jack.h> @@ -32,6 +33,7 @@ #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6)) #define SOF_RT5682_SSP_AMP(quirk) \ (((quirk) << SOF_RT5682_SSP_AMP_SHIFT) & SOF_RT5682_SSP_AMP_MASK) +#define SOF_RT5682_MCLK_BYTCHT_EN BIT(9)
/* Default: MCLK on, MCLK 19.2M, SSP0 */ static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | @@ -48,6 +50,7 @@ struct sof_hdmi_pcm { };
struct sof_card_private { + struct clk *mclk; struct snd_soc_jack sof_headset; struct list_head hdmi_pcm_list; }; @@ -59,6 +62,22 @@ static int sof_rt5682_quirk_cb(const struct dmi_system_id *id) }
static const struct dmi_system_id sof_rt5682_quirk_table[] = { + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), + DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max"), + }, + .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)), + }, + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_MATCH(DMI_PRODUCT_NAME, "UP-CHT01"), + }, + .driver_data = (void *)(SOF_RT5682_SSP_CODEC(2)), + }, { .callback = sof_rt5682_quirk_cb, .matches = { @@ -127,6 +146,27 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) RT5682_CLK_SEL_I2S1_ASRC); }
+ if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(ctx->mclk); + if (!ret) + clk_disable_unprepare(ctx->mclk); + + ret = clk_set_rate(ctx->mclk, 19200000); + + if (ret) + dev_err(rtd->dev, "unable to set MCLK rate\n"); + } + /* * Headset buttons map to the google Reference headset. * These can be configured by userspace. @@ -161,10 +201,20 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_dai *codec_dai = rtd->codec_dai; int clk_id, clk_freq, pll_out, ret;
if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { + if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { + ret = clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(rtd->dev, + "could not configure MCLK state"); + return ret; + } + } + clk_id = RT5682_PLL1_S_MCLK; if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) clk_freq = 24000000; @@ -507,7 +557,9 @@ static int sof_audio_probe(struct platform_device *pdev) dmic_num = 0; hdmi_num = 0; /* default quirk for legacy cpu */ - sof_rt5682_quirk = SOF_RT5682_SSP_CODEC(2); + sof_rt5682_quirk = SOF_RT5682_MCLK_EN | + SOF_RT5682_MCLK_BYTCHT_EN | + SOF_RT5682_SSP_CODEC(2); } else { dmic_num = 1; hdmi_num = 3; @@ -515,6 +567,17 @@ static int sof_audio_probe(struct platform_device *pdev)
dmi_check_system(sof_rt5682_quirk_table);
+ /* need to get main clock from pmc */ + if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { + ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + ret = clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(&pdev->dev, + "could not configure MCLK state"); + return ret; + } + } + dev_dbg(&pdev->dev, "sof_rt5682_quirk = %lx\n", sof_rt5682_quirk);
ssp_amp = (sof_rt5682_quirk & SOF_RT5682_SSP_AMP_MASK) >>
From: Keyon Jie yang.jie@linux.intel.com
Change the link name to be "dmic16k", the cpu_dai_name to be "DMIC16k Pin", to be aligned with other machine drivers.
Signed-off-by: Keyon Jie yang.jie@linux.intel.com Signed-off-by: Bard liao yung-chuan.liao@linux.intel.com --- sound/soc/intel/boards/sof_rt5682.c | 34 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index f3d481b75b15..919cf6fafe75 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -377,7 +377,7 @@ static struct snd_soc_dai_link_component max98357a_component[] = { static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, int ssp_codec, int ssp_amp, - int dmic_num, + int dmic_be_num, int hdmi_num) { struct snd_soc_dai_link_component *idisp_components; @@ -437,20 +437,22 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, id++;
/* dmic */ - for (i = 1; i <= dmic_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "dmic%02d", i); - if (!links[id].name) - goto devm_err; + if (dmic_be_num > 0) { + /* at least we have dmic01 */ + links[id].name = "dmic01"; + links[id].cpus->dai_name = "DMIC01 Pin"; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + links[id + 1].name = "dmic16k"; + links[id + 1].cpus->dai_name = "DMIC16k Pin"; + dmic_be_num = 2; + } + }
+ for (i = 0; i < dmic_be_num; i++) { links[id].id = id; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "DMIC%02d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - links[id].codecs = dmic_component; links[id].num_codecs = ARRAY_SIZE(dmic_component); links[id].platforms = platform_component; @@ -545,7 +547,7 @@ static int sof_audio_probe(struct platform_device *pdev) struct snd_soc_dai_link *dai_links; struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_num, hdmi_num; + int dmic_be_num, hdmi_num; int ret, ssp_amp, ssp_codec;
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); @@ -554,14 +556,14 @@ static int sof_audio_probe(struct platform_device *pdev)
if (soc_intel_is_byt() || soc_intel_is_cht()) { is_legacy_cpu = 1; - dmic_num = 0; + dmic_be_num = 0; hdmi_num = 0; /* default quirk for legacy cpu */ sof_rt5682_quirk = SOF_RT5682_MCLK_EN | SOF_RT5682_MCLK_BYTCHT_EN | SOF_RT5682_SSP_CODEC(2); } else { - dmic_num = 1; + dmic_be_num = 2; hdmi_num = 3; }
@@ -586,13 +588,13 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
/* compute number of dai links */ - sof_audio_card_rt5682.num_links = 1 + dmic_num + hdmi_num; + sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) sof_audio_card_rt5682.num_links++;
dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - dmic_num, hdmi_num); + dmic_be_num, hdmi_num); if (!dai_links) return -ENOMEM;
On 6/18/19 2:23 AM, Bard liao wrote:
From: Xun Zhang xun2.zhang@intel.com
The sof-rt5682 machine driver currently uses BCLK on BYT/Minnowboard platform. The MCLK signal is available since the Turbot revision, so enable MCLK on BYT/Minnowboard Turbot platform.
The commit message is not wrong but for more context the MCLK is enabled on all known BYT/CHT platforms except early MinnowBoards and Up where the MCLK is not available on the low-speed/HAT connector.
Signed-off-by: Xun Zhang xun2.zhang@intel.com Signed-off-by: Bard liao yung-chuan.liao@linux.intel.com
if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
ret = clk_prepare_enable(ctx->mclk);
if (ret < 0) {
dev_err(rtd->dev,
"could not configure MCLK state");
return ret;
}
}
Note that we could technically fallback to using the BCLK only in the error case but it's an unlikely scenario which we've never seen, so
Patch 1 and 2
Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
participants (2)
-
Bard liao
-
Pierre-Louis Bossart