Lines Matching +full:rate +full:- +full:lp +full:- +full:ms

1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #include <linux/clk-provider.h>
55 u32 m_frac; /* 29-bit Fractional part of multiplier M */
64 return regmap_update_bits(data->regmap, SI514_REG_CONTROL, in si514_enable_output()
88 err = regmap_read(data->regmap, SI514_REG_CONTROL, &val); in si514_is_prepared()
102 err = regmap_bulk_read(data->regmap, SI514_REG_M_FRAC1, in si514_get_muldiv()
107 settings->m_frac = reg[0] | reg[1] << 8 | reg[2] << 16 | in si514_get_muldiv()
109 settings->m_int = (reg[4] & 0x3f) << 3 | reg[3] >> 5; in si514_get_muldiv()
110 settings->ls_div_bits = (reg[6] >> 4) & 0x07; in si514_get_muldiv()
111 settings->hs_div = (reg[6] & 0x03) << 8 | reg[5]; in si514_get_muldiv()
118 u8 lp; in si514_set_muldiv() local
124 if (settings->m_int < 65 || in si514_set_muldiv()
125 (settings->m_int == 65 && settings->m_frac <= 139575831)) in si514_set_muldiv()
126 lp = 0x22; in si514_set_muldiv()
128 else if (settings->m_int < 67 || in si514_set_muldiv()
129 (settings->m_int == 67 && settings->m_frac <= 461581994)) in si514_set_muldiv()
130 lp = 0x23; in si514_set_muldiv()
132 else if (settings->m_int < 72 || in si514_set_muldiv()
133 (settings->m_int == 72 && settings->m_frac <= 503383578)) in si514_set_muldiv()
134 lp = 0x33; in si514_set_muldiv()
136 else if (settings->m_int < 75 || in si514_set_muldiv()
137 (settings->m_int == 75 && settings->m_frac <= 452724474)) in si514_set_muldiv()
138 lp = 0x34; in si514_set_muldiv()
140 lp = 0x44; in si514_set_muldiv()
142 err = regmap_write(data->regmap, SI514_REG_LP, lp); in si514_set_muldiv()
146 reg[0] = settings->m_frac; in si514_set_muldiv()
147 reg[1] = settings->m_frac >> 8; in si514_set_muldiv()
148 reg[2] = settings->m_frac >> 16; in si514_set_muldiv()
149 reg[3] = settings->m_frac >> 24 | settings->m_int << 5; in si514_set_muldiv()
150 reg[4] = settings->m_int >> 3; in si514_set_muldiv()
151 reg[5] = settings->hs_div; in si514_set_muldiv()
152 reg[6] = (settings->hs_div >> 8) | (settings->ls_div_bits << 4); in si514_set_muldiv()
154 err = regmap_bulk_write(data->regmap, SI514_REG_HS_DIV, reg + 5, 2); in si514_set_muldiv()
161 return regmap_bulk_write(data->regmap, SI514_REG_M_FRAC1, reg, 5); in si514_set_muldiv()
174 return -EINVAL; in si514_calc_muldiv()
179 settings->ls_div_bits = 0; in si514_calc_muldiv()
189 settings->ls_div_bits = res; in si514_calc_muldiv()
194 settings->hs_div = DIV_ROUND_UP(FVCO_MIN >> 1, ls_freq) << 1; in si514_calc_muldiv()
196 /* M = LS_DIV x HS_DIV x frequency / F_XO (in fixed-point) */ in si514_calc_muldiv()
197 m = ((u64)(ls_freq * settings->hs_div) << 29) + (FXO / 2); in si514_calc_muldiv()
199 settings->m_frac = (u32)m & (BIT(29) - 1); in si514_calc_muldiv()
200 settings->m_int = (u32)(m >> 29); in si514_calc_muldiv()
208 u64 m = settings->m_frac | ((u64)settings->m_int << 29); in si514_calc_rate()
209 u32 d = settings->hs_div * BIT(settings->ls_div_bits); in si514_calc_rate()
223 dev_err(&data->i2c_client->dev, "unable to retrieve settings\n"); in si514_recalc_rate()
230 static long si514_round_rate(struct clk_hw *hw, unsigned long rate, in si514_round_rate() argument
236 if (!rate) in si514_round_rate()
239 err = si514_calc_muldiv(&settings, rate); in si514_round_rate()
251 static int si514_set_rate(struct clk_hw *hw, unsigned long rate, in si514_set_rate() argument
259 err = si514_calc_muldiv(&settings, rate); in si514_set_rate()
263 err = regmap_read(data->regmap, SI514_REG_CONTROL, &old_oe_state); in si514_set_rate()
274 err = regmap_write(data->regmap, SI514_REG_CONTROL, SI514_CONTROL_FCAL); in si514_set_rate()
278 /* Applying a new frequency can take up to 10ms */ in si514_set_rate()
336 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); in si514_probe()
338 return -ENOMEM; in si514_probe()
343 data->hw.init = &init; in si514_probe()
344 data->i2c_client = client; in si514_probe()
346 if (of_property_read_string(client->dev.of_node, "clock-output-names", in si514_probe()
348 init.name = client->dev.of_node->name; in si514_probe()
350 data->regmap = devm_regmap_init_i2c(client, &si514_regmap_config); in si514_probe()
351 if (IS_ERR(data->regmap)) { in si514_probe()
352 dev_err(&client->dev, "failed to allocate register map\n"); in si514_probe()
353 return PTR_ERR(data->regmap); in si514_probe()
358 err = devm_clk_hw_register(&client->dev, &data->hw); in si514_probe()
360 dev_err(&client->dev, "clock registration failed\n"); in si514_probe()
363 err = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_simple_get, in si514_probe()
364 &data->hw); in si514_probe()
366 dev_err(&client->dev, "unable to add clk provider\n"); in si514_probe()