Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f975ca46 authored by Nicolin Chen's avatar Nicolin Chen Committed by Mark Brown
Browse files

ASoC: fsl_esai: Bypass divider settings if clock requirement is not changed



We don't need to change those dividers if bclk and mclk remains the same
directions and values.

Signed-off-by: default avatarNicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 3e185238
Loading
Loading
Loading
Loading
+20 −3
Original line number Original line Diff line number Diff line
@@ -39,6 +39,8 @@
 * @fifo_depth: depth of tx/rx FIFO
 * @fifo_depth: depth of tx/rx FIFO
 * @slot_width: width of each DAI slot
 * @slot_width: width of each DAI slot
 * @hck_rate: clock rate of desired HCKx clock
 * @hck_rate: clock rate of desired HCKx clock
 * @sck_rate: clock rate of desired SCKx clock
 * @hck_dir: the direction of HCKx pads
 * @sck_div: if using PSR/PM dividers for SCKx clock
 * @sck_div: if using PSR/PM dividers for SCKx clock
 * @slave_mode: if fully using DAI slave mode
 * @slave_mode: if fully using DAI slave mode
 * @synchronous: if using tx/rx synchronous mode
 * @synchronous: if using tx/rx synchronous mode
@@ -55,6 +57,8 @@ struct fsl_esai {
	u32 fifo_depth;
	u32 fifo_depth;
	u32 slot_width;
	u32 slot_width;
	u32 hck_rate[2];
	u32 hck_rate[2];
	u32 sck_rate[2];
	bool hck_dir[2];
	bool sck_div[2];
	bool sck_div[2];
	bool slave_mode;
	bool slave_mode;
	bool synchronous;
	bool synchronous;
@@ -213,6 +217,10 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
	unsigned long clk_rate;
	unsigned long clk_rate;
	int ret;
	int ret;


	/* Bypass divider settings if the requirement doesn't change */
	if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
		return 0;

	/* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
	/* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
	esai_priv->sck_div[tx] = true;
	esai_priv->sck_div[tx] = true;


@@ -272,6 +280,7 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
	esai_priv->sck_div[tx] = false;
	esai_priv->sck_div[tx] = false;


out:
out:
	esai_priv->hck_dir[tx] = dir;
	esai_priv->hck_rate[tx] = freq;
	esai_priv->hck_rate[tx] = freq;


	regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
	regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
@@ -289,9 +298,10 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
	u32 hck_rate = esai_priv->hck_rate[tx];
	u32 hck_rate = esai_priv->hck_rate[tx];
	u32 sub, ratio = hck_rate / freq;
	u32 sub, ratio = hck_rate / freq;
	int ret;


	/* Don't apply for fully slave mode*/
	/* Don't apply for fully slave mode or unchanged bclk */
	if (esai_priv->slave_mode)
	if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq)
		return 0;
		return 0;


	if (ratio * freq > hck_rate)
	if (ratio * freq > hck_rate)
@@ -313,8 +323,15 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
		return -EINVAL;
		return -EINVAL;
	}
	}


	return fsl_esai_divisor_cal(dai, tx, ratio, true,
	ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
			esai_priv->sck_div[tx] ? 0 : ratio);
			esai_priv->sck_div[tx] ? 0 : ratio);
	if (ret)
		return ret;

	/* Save current bclk rate */
	esai_priv->sck_rate[tx] = freq;

	return 0;
}
}


static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,