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(req->best_parent_rate, req->rate, in cs2000_determine_rate()
315 priv->lf_ratio); in cs2000_determine_rate()
317 req->rate = cs2000_ratio_to_rate(ratio, req->best_parent_rate, in cs2000_determine_rate()
318 priv->lf_ratio); in cs2000_determine_rate()
330 * | It is recommended that the 12.20 High-Resolution format be in cs2000_select_ratio_mode()
338 priv->lf_ratio = priv->dynamic_mode && ((rate / parent_rate) > 4096); in cs2000_select_ratio_mode()
340 return regmap_update_bits(priv->regmap, FUNC_CFG2, LFRATIO_MASK, in cs2000_select_ratio_mode()
341 priv->lf_ratio ? LFRATIO_20_12 : LFRATIO_12_20); in cs2000_select_ratio_mode()
350 ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, FREEZE); in __cs2000_set_rate()
366 ret = regmap_update_bits(priv->regmap, GLOBAL_CFG, FREEZE, 0); in __cs2000_set_rate()
370 priv->saved_rate = rate; in __cs2000_set_rate()
371 priv->saved_parent_rate = parent_rate; in __cs2000_set_rate()
390 priv->saved_rate, in cs2000_set_saved_rate()
391 priv->saved_parent_rate); in cs2000_set_saved_rate()
431 return priv->dynamic_mode ? CLK_IN : REF_CLK; in cs2000_get_parent()
451 return -EPROBE_DEFER; in cs2000_clk_get()
456 return -EPROBE_DEFER; in cs2000_clk_get()
458 priv->clk_in = clk_in; in cs2000_clk_get()
459 priv->ref_clk = ref_clk; in cs2000_clk_get()
467 struct device_node *np = dev->of_node; in cs2000_clk_register()
469 const char *name = np->name; in cs2000_clk_register()
476 of_property_read_string(np, "clock-output-names", &name); in cs2000_clk_register()
478 priv->dynamic_mode = of_property_read_bool(np, "cirrus,dynamic-mode"); in cs2000_clk_register()
480 priv->dynamic_mode ? "dynamic" : "static"); in cs2000_clk_register()
482 of_property_read_u32(np, "cirrus,aux-output-source", &aux_out); in cs2000_clk_register()
483 ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, in cs2000_clk_register()
488 priv->clk_skip = of_property_read_bool(np, "cirrus,clock-skip"); in cs2000_clk_register()
490 ref_clk_rate = clk_get_rate(priv->ref_clk); in cs2000_clk_register()
495 if (priv->dynamic_mode) { in cs2000_clk_register()
496 /* Default to low-frequency mode to allow for large ratios */ in cs2000_clk_register()
497 priv->lf_ratio = true; in cs2000_clk_register()
509 parent_names[CLK_IN] = __clk_get_name(priv->clk_in); in cs2000_clk_register()
510 parent_names[REF_CLK] = __clk_get_name(priv->ref_clk); in cs2000_clk_register()
518 priv->hw.init = &init; in cs2000_clk_register()
520 ret = clk_hw_register(dev, &priv->hw); in cs2000_clk_register()
524 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); in cs2000_clk_register()
526 clk_hw_unregister(&priv->hw); in cs2000_clk_register()
540 ret = regmap_read(priv->regmap, DEVICE_ID, &val); in cs2000_version_print()
544 /* CS2000 should be 0x0 */ in cs2000_version_print()
546 return -EIO; in cs2000_version_print()
556 return -EIO; in cs2000_version_print()
559 dev_info(dev, "revision - %s\n", revision); in cs2000_version_print()
568 struct device_node *np = dev->of_node; in cs2000_remove()
572 clk_hw_unregister(&priv->hw); in cs2000_remove()
578 struct device *dev = &client->dev; in cs2000_probe()
583 return -ENOMEM; in cs2000_probe()
585 priv->client = client; in cs2000_probe()
588 priv->regmap = devm_regmap_init_i2c(client, &cs2000_regmap_config); in cs2000_probe()
589 if (IS_ERR(priv->regmap)) in cs2000_probe()
590 return PTR_ERR(priv->regmap); in cs2000_probe()
625 .name = "cs2000-cp",
636 MODULE_DESCRIPTION("CS2000-CP driver");