Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
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

  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