Unverified Commit 5146b6a9 authored by Sebastian Reichel's avatar Sebastian Reichel Committed by Mark Brown
Browse files

ASoC: da7213: add default clock handling



This adds default clock/PLL configuration to the driver
for usage with generic drivers like simple-card for usage
with a fixed rate clock.

Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: default avatarAdam Thomson <Adam.Thomson.Opensource@diasemi.com>
Link: https://lore.kernel.org/r/20200626164623.87894-1-sebastian.reichel@collabora.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 68d1abe1
Loading
Loading
Loading
Loading
+78 −5
Original line number Diff line number Diff line
@@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
	u8 dai_ctrl = 0;
	u8 fs;

@@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
	switch (params_rate(params)) {
	case 8000:
		fs = DA7213_SR_8000;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
		break;
	case 11025:
		fs = DA7213_SR_11025;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
		break;
	case 12000:
		fs = DA7213_SR_12000;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
		break;
	case 16000:
		fs = DA7213_SR_16000;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
		break;
	case 22050:
		fs = DA7213_SR_22050;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
		break;
	case 32000:
		fs = DA7213_SR_32000;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
		break;
	case 44100:
		fs = DA7213_SR_44100;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
		break;
	case 48000:
		fs = DA7213_SR_48000;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
		break;
	case 88200:
		fs = DA7213_SR_88200;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
		break;
	case 96000:
		fs = DA7213_SR_96000;
		da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
		break;
	default:
		return -EINVAL;
@@ -1392,7 +1403,7 @@ static int da7213_set_component_sysclk(struct snd_soc_component *component,
}

/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
static int da7213_set_component_pll(struct snd_soc_component *component,
static int _da7213_set_component_pll(struct snd_soc_component *component,
				     int pll_id, int source,
				     unsigned int fref, unsigned int fout)
{
@@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct snd_soc_component *component,
	return 0;
}

static int da7213_set_component_pll(struct snd_soc_component *component,
				    int pll_id, int source,
				    unsigned int fref, unsigned int fout)
{
	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
	da7213->fixed_clk_auto_pll = false;

	return _da7213_set_component_pll(component, pll_id, source, fref, fout);
}

/* DAI operations */
static const struct snd_soc_dai_ops da7213_dai_ops = {
	.hw_params	= da7213_hw_params,
@@ -1532,6 +1553,50 @@ static struct snd_soc_dai_driver da7213_dai = {
	.symmetric_rates = 1,
};

static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable)
{
	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
	int mode;

	if (!da7213->fixed_clk_auto_pll)
		return 0;

	da7213->mclk_rate = clk_get_rate(da7213->mclk);

	if (enable) {
		/* Slave mode needs SRM for non-harmonic frequencies */
		if (da7213->master)
			mode = DA7213_SYSCLK_PLL;
		else
			mode = DA7213_SYSCLK_PLL_SRM;

		/* PLL is not required for harmonic frequencies */
		switch (da7213->out_rate) {
		case DA7213_PLL_FREQ_OUT_90316800:
			if (da7213->mclk_rate == 11289600 ||
			    da7213->mclk_rate == 22579200 ||
			    da7213->mclk_rate == 45158400)
				mode = DA7213_SYSCLK_MCLK;
			break;
		case DA7213_PLL_FREQ_OUT_98304000:
			if (da7213->mclk_rate == 12288000 ||
			    da7213->mclk_rate == 24576000 ||
			    da7213->mclk_rate == 49152000)
				mode = DA7213_SYSCLK_MCLK;

			break;
		default:
			return -1;
		}
	} else {
		/* Disable PLL in standby */
		mode = DA7213_SYSCLK_MCLK;
	}

	return _da7213_set_component_pll(component, 0, mode,
					 da7213->mclk_rate, da7213->out_rate);
}

static int da7213_set_bias_level(struct snd_soc_component *component,
				 enum snd_soc_bias_level level)
{
@@ -1551,6 +1616,8 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
						"Failed to enable mclk\n");
					return ret;
				}

				da7213_set_auto_pll(component, true);
			}
		}
		break;
@@ -1562,9 +1629,11 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
					    DA7213_VMID_EN | DA7213_BIAS_EN);
		} else {
			/* Remove MCLK */
			if (da7213->mclk)
			if (da7213->mclk) {
				da7213_set_auto_pll(component, false);
				clk_disable_unprepare(da7213->mclk);
			}
		}
		break;
	case SND_SOC_BIAS_OFF:
		/* Disable VMID reference & master bias */
@@ -1693,7 +1762,6 @@ static struct da7213_platform_data
	return pdata;
}


static int da7213_probe(struct snd_soc_component *component)
{
	struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
@@ -1829,6 +1897,11 @@ static int da7213_probe(struct snd_soc_component *component)
			return PTR_ERR(da7213->mclk);
		else
			da7213->mclk = NULL;
	} else {
		/* Do automatic PLL handling assuming fixed clock until
		 * set_pll() has been called. This makes the codec usable
		 * with the simple-audio-card driver. */
		da7213->fixed_clk_auto_pll = true;
	}

	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -535,10 +535,12 @@ struct da7213_priv {
	struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
	struct clk *mclk;
	unsigned int mclk_rate;
	unsigned int out_rate;
	int clk_src;
	bool master;
	bool alc_calib_auto;
	bool alc_en;
	bool fixed_clk_auto_pll;
	struct da7213_platform_data *pdata;
};