1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Shared helper functions for devices from the ADAU family
4 *
5 * Copyright 2011-2016 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 */
8
9#include <linux/gcd.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12
13#include "adau-utils.h"
14
15int adau_calc_pll_cfg(unsigned int freq_in, unsigned int freq_out,
16	uint8_t regs[5])
17{
18	unsigned int r, n, m, i, j;
19	unsigned int div;
20
21	if (!freq_out) {
22		r = 0;
23		n = 0;
24		m = 0;
25		div = 0;
26	} else {
27		if (freq_out % freq_in != 0) {
28			div = DIV_ROUND_UP(freq_in, 13500000);
29			freq_in /= div;
30			r = freq_out / freq_in;
31			i = freq_out % freq_in;
32			j = gcd(i, freq_in);
33			n = i / j;
34			m = freq_in / j;
35			div--;
36		} else {
37			r = freq_out / freq_in;
38			n = 0;
39			m = 0;
40			div = 0;
41		}
42		if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
43			return -EINVAL;
44	}
45
46	regs[0] = m >> 8;
47	regs[1] = m & 0xff;
48	regs[2] = n >> 8;
49	regs[3] = n & 0xff;
50	regs[4] = (r << 3) | (div << 1);
51	if (m != 0)
52		regs[4] |= 1; /* Fractional mode */
53
54	return 0;
55}
56EXPORT_SYMBOL_GPL(adau_calc_pll_cfg);
57
58MODULE_DESCRIPTION("ASoC ADAU audio CODECs shared helper functions");
59MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
60MODULE_LICENSE("GPL v2");
61