From: Peter Ujfalusi <peter.ujfalusi@ti.com>
To: Mark Brown <broonie@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>,
dmurphy@ti.com
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH v2 19/23] ASoC: tas2552: Correct the PLL configuration
Date: Fri, 5 Jun 2015 09:53:57 +0300 [thread overview]
Message-ID: <55714785.6090707@ti.com> (raw)
In-Reply-To: <1433423075-14142-20-git-send-email-peter.ujfalusi@ti.com>
On 06/04/2015 04:04 PM, Peter Ujfalusi wrote:
> Do not restrict the sampling rate to 44.1/48KHz. The pll_clk clock should
> be (sampling rate * 512) in all cases.
> Correct the J.D calculation (the D part was incorrectly calculated).
> Restore PLL enable status after we are done with the configuration.
> Implement hardware constraint handling towards the pll_clkin:
> if D != 0 (in J.D) then 1.1MHz <= pll_clkin <= 9.2MHz needs to be checked.
> If the PLL setup does not met with this constraint, fall back to BCLK as
> reference clock, if BCLK fails, use the internal 1.8MHz clock.
>
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
> sound/soc/codecs/tas2552.c | 141 ++++++++++++++++++++++++++++++---------------
> sound/soc/codecs/tas2552.h | 7 +--
> 2 files changed, 96 insertions(+), 52 deletions(-)
>
> diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
> index 891e2c529df3..01230395b61d 100644
> --- a/sound/soc/codecs/tas2552.c
> +++ b/sound/soc/codecs/tas2552.c
> @@ -77,7 +77,9 @@ struct tas2552_data {
> struct gpio_desc *enable_gpio;
> unsigned char regs[TAS2552_VBAT_DATA];
> unsigned int pll_clkin;
> + int pll_clk_id;
> unsigned int pdm_clk;
> + int pdm_clk_id;
>
> unsigned int dai_fmt;
> unsigned int tdm_delay;
> @@ -158,16 +160,93 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
> }
> #endif
>
> +static int tas2552_setup_pll(struct snd_soc_codec *codec,
> + struct snd_pcm_hw_params *params)
> +{
> + struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
> + bool bypass_pll = false;
> + unsigned int pll_clk = params_rate(params) * 512;
> + unsigned int pll_clkin = tas2552->pll_clkin;
> + u8 pll_enable;
> +
> + if (!pll_clkin) {
> + if (tas2552->pll_clk_id != TAS2552_PLL_CLKIN_BCLK)
> + return -EINVAL;
> +
> + pll_clkin = snd_soc_params_to_bclk(params);
> + pll_clkin += tas2552->tdm_delay;
> + }
> +
> + pll_enable = snd_soc_read(codec, TAS2552_CFG_2) & TAS2552_PLL_ENABLE;
> + snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
> +
> + if (pll_clkin == pll_clk)
> + bypass_pll = true;
> +
> + if (bypass_pll) {
> + /* By pass the PLL configuration */
> + snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
> + TAS2552_PLL_BYPASS, TAS2552_PLL_BYPASS);
> + } else {
> + /* Fill in the PLL control registers for J & D
> + * pll_clk = (.5 * pll_clkin * J.D) / 2^p
> + * Need to fill in J and D here based on incoming freq
> + */
> + unsigned int d;
> + u8 j;
> + u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK;
> + u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
> +
> + p = (p >> 7);
> +
> +recalc:
> + j = (pll_clk * 2 * (1 << p)) / pll_clkin;
> + d = (pll_clk * 2 * (1 << p)) % pll_clkin;
> + d /= (pll_clkin / 10000);
> +
> + if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) {
> + if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) {
> + pll_clkin = 1800000;
> + pll_sel = (TAS2552_PLL_CLKIN_1_8_FIXED << 3) &
> + TAS2552_PLL_SRC_MASK;
> + } else {
> + pll_clkin = snd_soc_params_to_bclk(params);
> + pll_clkin += tas2552->tdm_delay;
> + pll_sel = (TAS2552_PLL_CLKIN_BCLK << 3) &
> + TAS2552_PLL_SRC_MASK;
> + }
> + goto recalc;
> + }
> +
> + snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_PLL_SRC_MASK,
> + pll_sel);
> +
> + snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
> + TAS2552_PLL_J_MASK, j);
> + snd_soc_write(codec, TAS2552_PLL_CTRL_2,
> + (d >> 7) & TAS2552_PLL_D_UPPER_MASK);
This bit shift is not correct, it should be 8... I carried it over from the
old code and it worked since In some of my tests I was using bitclock as
reference (D ends up as 0).
Mark, if you apply the series up this patch, I will resend the rest as v3 with
the fixed shift - I will create a macro for upper and lower, it will look a
bit better.
> + snd_soc_write(codec, TAS2552_PLL_CTRL_3,
> + d & TAS2552_PLL_D_LOWER_MASK);
> +
> + /* PLL in use */
> + snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
> + TAS2552_PLL_BYPASS, 0);
> + }
> +
> + /* Restore PLL status */
> + snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
> + pll_enable);
> +
> + return 0;
> +}
> +
> static int tas2552_hw_params(struct snd_pcm_substream *substream,
> struct snd_pcm_hw_params *params,
> struct snd_soc_dai *dai)
> {
> struct snd_soc_codec *codec = dai->codec;
> struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
> - int sample_rate, pll_clk;
> - int d;
> int cpf;
> - u8 p, j;
> u8 ser_ctrl1_reg, wclk_rate;
>
> switch (params_width(params)) {
> @@ -245,49 +324,7 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
> snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
> wclk_rate);
>
> - if (!tas2552->pll_clkin)
> - return -EINVAL;
> -
> - snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
> -
> - if (tas2552->pll_clkin == TAS2552_245MHZ_CLK ||
> - tas2552->pll_clkin == TAS2552_225MHZ_CLK) {
> - /* By pass the PLL configuration */
> - snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
> - TAS2552_PLL_BYPASS_MASK,
> - TAS2552_PLL_BYPASS);
> - } else {
> - /* Fill in the PLL control registers for J & D
> - * PLL_CLK = (.5 * freq * J.D) / 2^p
> - * Need to fill in J and D here based on incoming freq
> - */
> - p = snd_soc_read(codec, TAS2552_PLL_CTRL_1);
> - p = (p >> 7);
> - sample_rate = params_rate(params);
> -
> - if (sample_rate == 48000)
> - pll_clk = TAS2552_245MHZ_CLK;
> - else if (sample_rate == 44100)
> - pll_clk = TAS2552_225MHZ_CLK;
> - else {
> - dev_vdbg(codec->dev, "Substream sample rate is not found %i\n",
> - params_rate(params));
> - return -EINVAL;
> - }
> -
> - j = (pll_clk * 2 * (1 << p)) / tas2552->pll_clkin;
> - d = (pll_clk * 2 * (1 << p)) % tas2552->pll_clkin;
> -
> - snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
> - TAS2552_PLL_J_MASK, j);
> - snd_soc_write(codec, TAS2552_PLL_CTRL_2,
> - (d >> 7) & TAS2552_PLL_D_UPPER_MASK);
> - snd_soc_write(codec, TAS2552_PLL_CTRL_3,
> - d & TAS2552_PLL_D_LOWER_MASK);
> -
> - }
> -
> - return 0;
> + return tas2552_setup_pll(codec, params);
> }
>
> #define TAS2552_DAI_FMT_MASK (TAS2552_BCLKDIR | \
> @@ -370,12 +407,21 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
>
> switch (clk_id) {
> case TAS2552_PLL_CLKIN_MCLK:
> - case TAS2552_PLL_CLKIN_BCLK:
> case TAS2552_PLL_CLKIN_IVCLKIN:
> + if (freq < 512000 || freq > 24576000) {
> + /* out of range PLL_CLKIN, fall back to use BCLK */
> + dev_warn(codec->dev, "Out of range PLL_CLKIN: %u\n",
> + freq);
> + clk_id = TAS2552_PLL_CLKIN_BCLK;
> + freq = 0;
> + }
> + /* fall through */
> + case TAS2552_PLL_CLKIN_BCLK:
> case TAS2552_PLL_CLKIN_1_8_FIXED:
> mask = TAS2552_PLL_SRC_MASK;
> val = (clk_id << 3) & mask; /* bit 4:5 in the register */
> reg = TAS2552_CFG_1;
> + tas2552->pll_clk_id = clk_id;
> tas2552->pll_clkin = freq;
> break;
> case TAS2552_PDM_CLK_PLL:
> @@ -385,6 +431,7 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
> mask = TAS2552_PDM_CLK_SEL_MASK;
> val = (clk_id >> 1) & mask; /* bit 0:1 in the register */
> reg = TAS2552_PDM_CFG;
> + tas2552->pdm_clk_id = clk_id;
> tas2552->pdm_clk = freq;
> break;
> default:
> diff --git a/sound/soc/codecs/tas2552.h b/sound/soc/codecs/tas2552.h
> index bbb820495516..f04d9e6db0aa 100644
> --- a/sound/soc/codecs/tas2552.h
> +++ b/sound/soc/codecs/tas2552.h
> @@ -128,12 +128,9 @@
> #define TAS2552_APT_THRESH_2_1_7 (0x11 << 2)
>
> /* PLL Control Register */
> -#define TAS2552_245MHZ_CLK 24576000
> -#define TAS2552_225MHZ_CLK 22579200
> -#define TAS2552_PLL_J_MASK 0x7f
> +#define TAS2552_PLL_J_MASK 0x7f
> #define TAS2552_PLL_D_UPPER_MASK 0x3f
> #define TAS2552_PLL_D_LOWER_MASK 0xff
> -#define TAS2552_PLL_BYPASS_MASK 0x80
> -#define TAS2552_PLL_BYPASS 0x80
> +#define TAS2552_PLL_BYPASS (1 << 7)
>
> #endif
>
--
Péter
next prev parent reply other threads:[~2015-06-05 6:54 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-04 13:04 [PATCH v2 00/23] ASoC: tas2552: Fixes, cleanups and improvements Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 01/23] ASoC: tas2552: Make the enable-gpio really optional Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 02/23] ASoC: tas2552: Fix kernel crash when the codec is loaded but not part of a card Peter Ujfalusi
2015-06-04 16:25 ` Mark Brown
2015-06-05 6:57 ` Peter Ujfalusi
2015-06-04 16:50 ` Mark Brown
2015-06-04 13:04 ` [PATCH v2 03/23] ASoC: tas2552: Fix kernel crash caused by wrong kcontrol entry Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 04/23] ASoC: tas2552: Correct PDM configuration register bit definitions Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 05/23] ASoC: tas2552: Correct CFG1 " Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 06/23] ASoC: tas2552: Simplify the tas2552_mute function Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 07/23] ASoC: tas2552: Simplify and reverse the functionality of tas2552_sw_shutdown Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 08/23] ASoC: tas2552: Rename mclk parameter to pll_clkin to match with the datasheet Peter Ujfalusi
2015-06-04 16:51 ` Mark Brown
2015-06-04 13:04 ` [PATCH v2 09/23] DT/sound: bindings header file for tas2552 codec Peter Ujfalusi
2015-06-05 17:54 ` Mark Brown
2015-06-04 13:04 ` [PATCH v2 10/23] ASoC: tas2552: Add support for pll and pdm source clock selection Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 11/23] ASoC: tas2552: Correct dai format support Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 12/23] ASoC: tas2552: Correct and clean up data format and BCLK/WCLK direction Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 13/23] ASoC: tas2552: Add TDM support Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 14/23] ASoC: tas2552: Clean up the Digital - Analog DAPM route definition Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 15/23] ASoC: tas2552: Correct the Speaker Driver Playback Volume (PGA_GAIN) Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 16/23] ASoC: tas2552: Implement startup/stop sequence as per TRM Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 17/23] ASoC: tas2552: Add support for word length configuration Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 18/23] ASoC: tas2552: Configure the WCLK frequency based on the stream Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 19/23] ASoC: tas2552: Correct the PLL configuration Peter Ujfalusi
2015-06-05 6:53 ` Peter Ujfalusi [this message]
2015-06-04 13:04 ` [PATCH v2 20/23] ASoC: tas2552: Add control for selecting DIN source Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 21/23] ASoC: tas2552: Correct Output Data register usage Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 22/23] ASoC: tas2552: Correct Boost Auto-Pass Through Control " Peter Ujfalusi
2015-06-04 13:04 ` [PATCH v2 23/23] ASoC: tas2552: Code, define alignment changes for uniformity Peter Ujfalusi
2015-06-05 17:53 ` [PATCH v2 00/23] ASoC: tas2552: Fixes, cleanups and improvements Mark Brown
2015-06-08 7:52 ` Peter Ujfalusi
2015-06-08 9:24 ` Mark Brown
2015-06-08 9:54 ` Peter Ujfalusi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55714785.6090707@ti.com \
--to=peter.ujfalusi@ti.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=dmurphy@ti.com \
--cc=lgirdwood@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox