linux/sound/soc/codecs/adau-utils.c
Lars-Peter Clausen 0eadaa9ce2 ASoC: adau: Factor out shared PLL configuration code
Multiple devices from the ADAU family share the same PLL structure and
configuration register layout. Introduce a new helper module that can be
used to calculated the PLL configuration registers based on a specified
input frequency and the desired output frequency of the PLL.

The ADAU1761/ADAU1781 and ADAU1373 drivers are updated to make use of this
new helper module. But future drivers for additional devices from the ADAU
family are also expected to make use of it.

In anticipation of sharing more infrastructure code between different
devices from the ADAU family the new module is called adau-utils.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-06-09 18:41:41 +01:00

62 lines
1.2 KiB
C

/*
* Shared helper functions for devices from the ADAU family
*
* Copyright 2011-2016 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/gcd.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include "adau-utils.h"
int adau_calc_pll_cfg(unsigned int freq_in, unsigned int freq_out,
uint8_t regs[5])
{
unsigned int r, n, m, i, j;
unsigned int div;
if (!freq_out) {
r = 0;
n = 0;
m = 0;
div = 0;
} else {
if (freq_out % freq_in != 0) {
div = DIV_ROUND_UP(freq_in, 13500000);
freq_in /= div;
r = freq_out / freq_in;
i = freq_out % freq_in;
j = gcd(i, freq_in);
n = i / j;
m = freq_in / j;
div--;
} else {
r = freq_out / freq_in;
n = 0;
m = 0;
div = 0;
}
if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
return -EINVAL;
}
regs[0] = m >> 8;
regs[1] = m & 0xff;
regs[2] = n >> 8;
regs[3] = n & 0xff;
regs[4] = (r << 3) | (div << 1);
if (m != 0)
regs[4] |= 1; /* Fractional mode */
return 0;
}
EXPORT_SYMBOL_GPL(adau_calc_pll_cfg);
MODULE_DESCRIPTION("ASoC ADAU audio CODECs shared helper functions");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL v2");