From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from fldsmtpe03.verizon.com ([140.108.26.142]:59238 "EHLO fldsmtpe03.verizon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932311AbdDDTfB (ORCPT ); Tue, 4 Apr 2017 15:35:01 -0400 From: alexander.levin@verizon.com To: "gregkh@linuxfoundation.org" CC: "stable@vger.kernel.org" Subject: [PATCH for 4.9 73/98] ASoC: Intel: cht_bsw_rt5645: add Baytrail MCLK support Date: Tue, 4 Apr 2017 19:32:29 +0000 Message-ID: <20170404193158.19041-74-alexander.levin@verizon.com> References: <20170404193158.19041-1-alexander.levin@verizon.com> In-Reply-To: <20170404193158.19041-1-alexander.levin@verizon.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Pierre-Louis Bossart [ Upstream commit a50477e55fff69e1028f25624ee9fc9182d59b1f ] The existing code assumes a 19.2 MHz MCLK as the default hardware configuration. This is valid for CherryTrail but not for Baytrail. Add explicit MCLK configuration to set the 19.2 clock on/off depending on DAPM events. This is a prerequisite step to enable devices with Baytrail and RT5645 such as Asus X205TA Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/cht_bsw_rt5645.c | 84 ++++++++++++++++++++++++++++-= ---- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boar= ds/cht_bsw_rt5645.c index 5b3418a..9052561 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -45,6 +48,7 @@ struct cht_mc_private { struct snd_soc_jack jack; struct cht_acpi_card *acpi_card; char codec_name[16]; + struct clk *mclk; }; =20 static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *c= ard) @@ -65,6 +69,7 @@ static int platform_clock_control(struct snd_soc_dapm_wid= get *w, struct snd_soc_dapm_context *dapm =3D w->dapm; struct snd_soc_card *card =3D dapm->card; struct snd_soc_dai *codec_dai; + struct cht_mc_private *ctx =3D snd_soc_card_get_drvdata(card); int ret; =20 codec_dai =3D cht_get_codec_dai(card); @@ -73,19 +78,30 @@ static int platform_clock_control(struct snd_soc_dapm_w= idget *w, return -EIO; } =20 - if (!SND_SOC_DAPM_EVENT_OFF(event)) - return 0; + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (ctx->mclk) { + ret =3D clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(card->dev, + "could not configure MCLK state"); + return ret; + } + } + } else { + /* Set codec sysclk source to its internal clock because codec PLL will + * be off when idle and MCLK will also be off when codec is + * runtime suspended. Codec needs clock for jack detection and button + * press. MCLK is turned off with clock framework or ACPI. + */ + ret =3D snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, + 48000 * 512, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } =20 - /* Set codec sysclk source to its internal clock because codec PLL will - * be off when idle and MCLK will also be off by ACPI when codec is - * runtime suspended. Codec needs clock for jack detection and button - * press. - */ - ret =3D snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "can't set codec sysclk: %d\n", ret); - return ret; + if (ctx->mclk) + clk_disable_unprepare(ctx->mclk); } =20 return 0; @@ -97,7 +113,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets= [] =3D { SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_POST_PMD), + platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; =20 static const struct snd_soc_dapm_route cht_rt5645_audio_map[] =3D { @@ -225,6 +241,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *= runtime) =20 rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); =20 + if (ctx->mclk) { + /* + * 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 =3D clk_prepare_enable(ctx->mclk); + if (!ret) + clk_disable_unprepare(ctx->mclk); + + ret =3D clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); + + if (ret) + dev_err(runtime->dev, "unable to set MCLK rate\n"); + } return ret; } =20 @@ -349,6 +385,18 @@ static struct cht_acpi_card snd_soc_cards[] =3D { =20 static char cht_rt5640_codec_name[16]; /* i2c-:00 with HID being 8 ch= ars */ =20 +static bool is_valleyview(void) +{ + static const struct x86_cpu_id cpu_ids[] =3D { + { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ + {} + }; + + if (!x86_match_cpu(cpu_ids)) + return false; + return true; +} + static int snd_cht_mc_probe(struct platform_device *pdev) { int ret_val =3D 0; @@ -401,6 +449,16 @@ static int snd_cht_mc_probe(struct platform_device *pd= ev) cht_dailink[dai_index].codec_name =3D cht_rt5640_codec_name; } =20 + if (is_valleyview()) { + drv->mclk =3D devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(drv->mclk)) { + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %ld\n", + PTR_ERR(drv->mclk)); + return PTR_ERR(drv->mclk); + } + } + snd_soc_card_set_drvdata(card, drv); ret_val =3D devm_snd_soc_register_card(&pdev->dev, card); if (ret_val) { --=20 2.9.3