use device_api::clock::Hertz;
use tock_registers::register_bitfields;

#[derive(Debug)]
pub(crate) struct WrpllData {
    pub(crate) divr: u32,
    pub(crate) divf: u32,
    pub(crate) divq: u32,
    pub(crate) int_feedback: bool,
}

register_bitfields! {
    u32,
    pub PllCfg [
        PLLR            OFFSET(0)   NUMBITS(6)  [],
        PLLF            OFFSET(6)   NUMBITS(9)  [],
        PLLQ            OFFSET(15)  NUMBITS(3)  [],
        PLLBYPASS       OFFSET(24)  NUMBITS(1)  [],
        PLLFSEBYPASS    OFFSET(25)  NUMBITS(1)  [],
        PLLLOCK         OFFSET(31)  NUMBITS(1)  [],
    ]
}

impl WrpllData {
    fn fbdiv(&self) -> u32 {
        if self.int_feedback { 2 } else { 1 }
    }

    pub(crate) fn output_rate(&self, input_rate: Hertz) -> Hertz {
        let fbdiv = self.fbdiv();
        let n = input_rate * fbdiv * (self.divf + 1);
        let n = n / (self.divr + 1);
        n >> self.divq
    }
}
