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

Commit c36b2fc7 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: Clean up WM8974 PLL configuration



Don't use a static for WM8974 PLL factors - we don't support more than
one device so it won't happen but no sense in leaving the race condition
hanging around.  Also, pre_div is a single bit and it's a bit simpler if
we move the handling of the factor of 4 in the output into the
coefficient setup.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 25cbf465
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -330,36 +330,38 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
}

struct pll_ {
	unsigned int pre_div:4; /* prescale - 1 */
	unsigned int pre_div:1;
	unsigned int n:4;
	unsigned int k;
};

static struct pll_ pll_div;

/* The size in bits of the pll divide multiplied by 10
 * to allow rounding later */
#define FIXED_PLL_SIZE ((1 << 24) * 10)

static void pll_factors(unsigned int target, unsigned int source)
static void pll_factors(struct pll_ *pll_div,
			unsigned int target, unsigned int source)
{
	unsigned long long Kpart;
	unsigned int K, Ndiv, Nmod;

	/* There is a fixed divide by 4 in the output path */
	target *= 4;

	Ndiv = target / source;
	if (Ndiv < 6) {
		source >>= 1;
		pll_div.pre_div = 1;
		source /= 2;
		pll_div->pre_div = 1;
		Ndiv = target / source;
	} else
		pll_div.pre_div = 0;
		pll_div->pre_div = 0;

	if ((Ndiv < 6) || (Ndiv > 12))
		printk(KERN_WARNING
			"WM8974 N value %u outwith recommended range!\n",
			Ndiv);

	pll_div.n = Ndiv;
	pll_div->n = Ndiv;
	Nmod = target % source;
	Kpart = FIXED_PLL_SIZE * (long long)Nmod;

@@ -374,13 +376,14 @@ static void pll_factors(unsigned int target, unsigned int source)
	/* Move down to proper range now rounding is done */
	K /= 10;

	pll_div.k = K;
	pll_div->k = K;
}

static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
		int pll_id, unsigned int freq_in, unsigned int freq_out)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct pll_ pll_div;
	u16 reg;

	if (freq_in == 0 || freq_out == 0) {
@@ -394,7 +397,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
		return 0;
	}

	pll_factors(freq_out*4, freq_in);
	pll_factors(&pll_div, freq_out, freq_in);

	wm8974_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
	wm8974_write(codec, WM8974_PLLK1, pll_div.k >> 18);