Lines Matching +full:cs2000 +full:- +full:cp
1 // SPDX-License-Identifier: GPL-2.0
3 * CS2000 -- CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier
8 #include <linux/clk-provider.h>
25 #define Ratio_Val(x, nth) ((x >> (24 - (8 * nth))) & 0xFF)
26 #define Val_Ratio(x, nth) ((x & 0xFF) << (24 - (8 * nth)))
71 #define priv_to_client(priv) (priv->client)
72 #define priv_to_dev(priv) (&(priv_to_client(priv)->dev))
119 { .compatible = "cirrus,cs2000-cp", },
125 { "cs2000-cp", },
134 ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, ENDEV1, in cs2000_enable_dev_config()
139 ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, ENDEV2, in cs2000_enable_dev_config()
144 ret = regmap_update_bits(priv->regmap, FUNC_CFG1, CLKSKIPEN, in cs2000_enable_dev_config()
145 (enable && priv->clk_skip) ? CLKSKIPEN : 0); in cs2000_enable_dev_config()
164 return -EINVAL; in cs2000_ref_clk_bound_rate()
166 return regmap_update_bits(priv->regmap, FUNC_CFG1, in cs2000_ref_clk_bound_rate()
178 ret = regmap_read(priv->regmap, DEVICE_CTRL, &val); in cs2000_wait_pll_lock()
188 return -ETIMEDOUT; in cs2000_wait_pll_lock()
194 return regmap_update_bits(priv->regmap, DEVICE_CTRL, in cs2000_clk_out_enable()
241 return -EINVAL; in cs2000_ratio_set()
243 val = cs2000_rate_to_ratio(rate_in, rate_out, priv->lf_ratio); in cs2000_ratio_set()
245 ret = regmap_write(priv->regmap, in cs2000_ratio_set()
263 ret = regmap_read(priv->regmap, Ratio_Add(ch, i), &tmp); in cs2000_ratio_get()
279 return -EINVAL; in cs2000_ratio_select()
281 ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, RSEL_MASK, RSEL(ch)); in cs2000_ratio_select()
285 fracnsrc = priv->dynamic_mode ? FRACNSRC_DYNAMIC : FRACNSRC_STATIC; in cs2000_ratio_select()
287 ret = regmap_update_bits(priv->regmap, DEVICE_CFG2, in cs2000_ratio_select()
305 return cs2000_ratio_to_rate(ratio, parent_rate, priv->lf_ratio); in cs2000_recalc_rate()
314 ratio = cs2000_rate_to_ratio(*parent_rate, rate, priv->lf_ratio); in cs2000_round_rate()
316 return cs2000_ratio_to_rate(ratio, *parent_rate, priv->lf_ratio); in cs2000_round_rate()
326 * | It is recommended that the 12.20 High-Resolution format be in cs2000_select_ratio_mode()
334 priv->lf_ratio = priv->dynamic_mode && ((rate / parent_rate) > 4096); in cs2000_select_ratio_mode()
336 return regmap_update_bits(priv->regmap, FUNC_CFG2, LFRATIO_MASK, in cs2000_select_ratio_mode()
337 priv->lf_ratio ? LFRATIO_20_12 : LFRATIO_12_20); in cs2000_select_ratio_mode()
346 ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, FREEZE); in __cs2000_set_rate()
362 ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, 0); in __cs2000_set_rate()
366 priv->saved_rate = rate; in __cs2000_set_rate()
367 priv->saved_parent_rate = parent_rate; in __cs2000_set_rate()
386 priv->saved_rate, in cs2000_set_saved_rate()
387 priv->saved_parent_rate); in cs2000_set_saved_rate()
427 return priv->dynamic_mode ? CLK_IN : REF_CLK; in cs2000_get_parent()
447 return -EPROBE_DEFER; in cs2000_clk_get()
452 return -EPROBE_DEFER; in cs2000_clk_get()
454 priv->clk_in = clk_in; in cs2000_clk_get()
455 priv->ref_clk = ref_clk; in cs2000_clk_get()
463 struct device_node *np = dev->of_node; in cs2000_clk_register()
465 const char *name = np->name; in cs2000_clk_register()
472 of_property_read_string(np, "clock-output-names", &name); in cs2000_clk_register()
474 priv->dynamic_mode = of_property_read_bool(np, "cirrus,dynamic-mode"); in cs2000_clk_register()
476 priv->dynamic_mode ? "dynamic" : "static"); in cs2000_clk_register()
478 of_property_read_u32(np, "cirrus,aux-output-source", &aux_out); in cs2000_clk_register()
479 ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, in cs2000_clk_register()
484 priv->clk_skip = of_property_read_bool(np, "cirrus,clock-skip"); in cs2000_clk_register()
486 ref_clk_rate = clk_get_rate(priv->ref_clk); in cs2000_clk_register()
491 if (priv->dynamic_mode) { in cs2000_clk_register()
492 /* Default to low-frequency mode to allow for large ratios */ in cs2000_clk_register()
493 priv->lf_ratio = true; in cs2000_clk_register()
505 parent_names[CLK_IN] = __clk_get_name(priv->clk_in); in cs2000_clk_register()
506 parent_names[REF_CLK] = __clk_get_name(priv->ref_clk); in cs2000_clk_register()
514 priv->hw.init = &init; in cs2000_clk_register()
516 ret = clk_hw_register(dev, &priv->hw); in cs2000_clk_register()
520 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); in cs2000_clk_register()
522 clk_hw_unregister(&priv->hw); in cs2000_clk_register()
536 ret = regmap_read(priv->regmap, DEVICE_ID, &val); in cs2000_version_print()
540 /* CS2000 should be 0x0 */ in cs2000_version_print()
542 return -EIO; in cs2000_version_print()
552 return -EIO; in cs2000_version_print()
555 dev_info(dev, "revision - %s\n", revision); in cs2000_version_print()
564 struct device_node *np = dev->of_node; in cs2000_remove()
568 clk_hw_unregister(&priv->hw); in cs2000_remove()
574 struct device *dev = &client->dev; in cs2000_probe()
579 return -ENOMEM; in cs2000_probe()
581 priv->client = client; in cs2000_probe()
584 priv->regmap = devm_regmap_init_i2c(client, &cs2000_regmap_config); in cs2000_probe()
585 if (IS_ERR(priv->regmap)) in cs2000_probe()
586 return PTR_ERR(priv->regmap); in cs2000_probe()
621 .name = "cs2000-cp",
632 MODULE_DESCRIPTION("CS2000-CP driver");