Linux driver sgtl5000:
/* if using pll, please check manual 6.4.2 for detail */
if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
u64 out, t;
int div2;
int pll_ctl;
unsigned int in, int_div, frac_div;
if (sgtl5000->sysclk > 17000000) {
div2 = 1;
in = sgtl5000->sysclk / 2;
} else {
div2 = 0;
in = sgtl5000->sysclk;
}
if (sys_fs == 44100)
out = 180633600;
else
out = 196608000;
t = do_div(out, in);
int_div = out;
t *= 2048;
do_div(t, in);
frac_div = t;
pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
snd_soc_component_write(component, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
if (div2)
snd_soc_component_update_bits(component,
SGTL5000_CHIP_CLK_TOP_CTRL,
SGTL5000_INPUT_FREQ_DIV2,
SGTL5000_INPUT_FREQ_DIV2);
else
snd_soc_component_update_bits(component,
SGTL5000_CHIP_CLK_TOP_CTRL,
SGTL5000_INPUT_FREQ_DIV2,
0);
/* power up pll */
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
/* if using pll, clk_ctrl must be set after pll power up */
snd_soc_component_write(component, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
} else {
/* otherwise, clk_ctrl must be set before pll power down */
snd_soc_component_write(component, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
/* power down pll */
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
0);
}
Zephyr sgtl5000:
/* PLL Configuration if required */
if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
uint64_t out;
int div2 = 0;
uint32_t in = mclk_freq;
if (mclk_freq > 17000000) {
div2 = 1;
in = mclk_freq / 2;
}
else {
div2 = 0;
in = mclk_freq;
}
out = (sys_fs == 44100) ? 180633600ULL : 196608000ULL;
uint32_t int_div = (uint32_t)(out / in);
uint32_t frac_div = (uint32_t)(((out % in) * 2048ULL) / in);
uint32_t pll_ctl = (int_div << SGTL5000_PLL_INT_DIV_SHIFT) | (frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT);
sgtl5000_write_reg(dev, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
sgtl5000_update_reg(dev, SGTL5000_CHIP_CLK_TOP_CTRL, SGTL5000_INPUT_FREQ_DIV2, div2 ? SGTL5000_INPUT_FREQ_DIV2 : 0);
sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_POWER, SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP, SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
sgtl5000_write_reg(dev, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
} else {
sgtl5000_write_reg(dev, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_POWER, SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP, 0);
}
Я считаю, что тут неправильно перенесён код