Загрузка данных


    /* PLL Configuration if required */
    if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
        uint64_t out;
        uint32_t t;
        uint32_t div2 = 0;
        uint32_t in = mclk_freq;
        uint32_t int_div, frac_div;

        if (mclk_freq > 17000000) {
            div2 = 1;
            in = mclk_freq / 2;
        } else {
            div2 = 0;
            in = mclk_freq;
        }

        /* Select target upstream VCO clock layout based on sampling grid framework */
        if (sys_fs == 44100) {
            out = 180633600ULL;
        } else {
            out = 196608000ULL;
        }

        /* 
         * Execution steps identical to Linux source code:
         * 1. do_div calculates remainder into 't', and overwrites 'out' with (out / in)
         */
        t = do_div(out, in);
        int_div = (uint32_t)out;

        /* 2. Scale the extracted remainder factor and extract fractional dividers scaling */
        t *= 2048U;
        frac_div = do_div(t, 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);
        
        /* Apply dynamic state modifications to integrated dividers gates */
        sgtl5000_update_reg(dev, SGTL5000_CHIP_CLK_TOP_CTRL, 
                           SGTL5000_INPUT_FREQ_DIV2, 
                           div2 ? SGTL5000_INPUT_FREQ_DIV2 : 0);
        
        /* Secure hardware activation power for core VCO structures */
        sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_POWER, 
                           SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP, 
                           SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);

        /* Required by hardware manual sequence: write clock controls after loop activation */
        sgtl5000_write_reg(dev, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
    } else {
        /* Otherwise, write clock controls before dynamic loop power-down triggers */
        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);
    }