Lines Matching +full:clkdiv +full:- +full:-
1 // SPDX-License-Identifier: GPL-2.0-only
7 #include <linux/clk-provider.h>
24 struct clkdiv { struct
33 static inline struct clkdiv *to_clkdiv(struct clk_hw *hw) in to_clkdiv() argument
35 return container_of(hw, struct clkdiv, hw); in to_clkdiv()
43 return 1 << (div_factor - 1); in div_factor_to_div()
51 static bool is_spmi_pmic_clkdiv_enabled(struct clkdiv *clkdiv) in is_spmi_pmic_clkdiv_enabled() argument
55 regmap_read(clkdiv->regmap, clkdiv->base + REG_EN_CTL, &val); in is_spmi_pmic_clkdiv_enabled()
61 __spmi_pmic_clkdiv_set_enable_state(struct clkdiv *clkdiv, bool enable, in __spmi_pmic_clkdiv_set_enable_state() argument
65 unsigned int ns = clkdiv->cxo_period_ns; in __spmi_pmic_clkdiv_set_enable_state()
68 ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_EN_CTL, in __spmi_pmic_clkdiv_set_enable_state()
81 static int spmi_pmic_clkdiv_set_enable_state(struct clkdiv *clkdiv, bool enable) in spmi_pmic_clkdiv_set_enable_state() argument
85 regmap_read(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, &div_factor); in spmi_pmic_clkdiv_set_enable_state()
88 return __spmi_pmic_clkdiv_set_enable_state(clkdiv, enable, div_factor); in spmi_pmic_clkdiv_set_enable_state()
93 struct clkdiv *clkdiv = to_clkdiv(hw); in clk_spmi_pmic_div_enable() local
97 spin_lock_irqsave(&clkdiv->lock, flags); in clk_spmi_pmic_div_enable()
98 ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, true); in clk_spmi_pmic_div_enable()
99 spin_unlock_irqrestore(&clkdiv->lock, flags); in clk_spmi_pmic_div_enable()
106 struct clkdiv *clkdiv = to_clkdiv(hw); in clk_spmi_pmic_div_disable() local
109 spin_lock_irqsave(&clkdiv->lock, flags); in clk_spmi_pmic_div_disable()
110 spmi_pmic_clkdiv_set_enable_state(clkdiv, false); in clk_spmi_pmic_div_disable()
111 spin_unlock_irqrestore(&clkdiv->lock, flags); in clk_spmi_pmic_div_disable()
129 struct clkdiv *clkdiv = to_clkdiv(hw); in clk_spmi_pmic_div_recalc_rate() local
132 regmap_read(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, &div_factor); in clk_spmi_pmic_div_recalc_rate()
141 struct clkdiv *clkdiv = to_clkdiv(hw); in clk_spmi_pmic_div_set_rate() local
147 spin_lock_irqsave(&clkdiv->lock, flags); in clk_spmi_pmic_div_set_rate()
148 enabled = is_spmi_pmic_clkdiv_enabled(clkdiv); in clk_spmi_pmic_div_set_rate()
150 ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, false); in clk_spmi_pmic_div_set_rate()
155 ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1, in clk_spmi_pmic_div_set_rate()
161 ret = __spmi_pmic_clkdiv_set_enable_state(clkdiv, true, in clk_spmi_pmic_div_set_rate()
165 spin_unlock_irqrestore(&clkdiv->lock, flags); in clk_spmi_pmic_div_set_rate()
180 struct clkdiv clks[] __counted_by(nclks);
187 int idx = clkspec->args[0] - 1; /* Start at 1 instead of 0 */ in spmi_pmic_div_clk_hw_get()
189 if (idx < 0 || idx >= cc->nclks) { in spmi_pmic_div_clk_hw_get()
191 __func__, clkspec->args[0], cc->nclks); in spmi_pmic_div_clk_hw_get()
192 return ERR_PTR(-EINVAL); in spmi_pmic_div_clk_hw_get()
195 return &cc->clks[idx].hw; in spmi_pmic_div_clk_hw_get()
202 struct clkdiv *clkdiv; in spmi_pmic_clkdiv_probe() local
205 struct device *dev = &pdev->dev; in spmi_pmic_clkdiv_probe()
206 struct device_node *of_node = dev->of_node; in spmi_pmic_clkdiv_probe()
218 regmap = dev_get_regmap(dev->parent, NULL); in spmi_pmic_clkdiv_probe()
221 return -EINVAL; in spmi_pmic_clkdiv_probe()
224 ret = of_property_read_u32(of_node, "qcom,num-clkdivs", &nclks); in spmi_pmic_clkdiv_probe()
226 dev_err(dev, "qcom,num-clkdivs property reading failed, ret=%d\n", in spmi_pmic_clkdiv_probe()
232 return -EINVAL; in spmi_pmic_clkdiv_probe()
236 return -ENOMEM; in spmi_pmic_clkdiv_probe()
237 cc->nclks = nclks; in spmi_pmic_clkdiv_probe()
242 if (ret != -EPROBE_DEFER) in spmi_pmic_clkdiv_probe()
254 for (i = 0, clkdiv = cc->clks; i < nclks; i++) { in spmi_pmic_clkdiv_probe()
257 spin_lock_init(&clkdiv[i].lock); in spmi_pmic_clkdiv_probe()
258 clkdiv[i].base = start + i * 0x100; in spmi_pmic_clkdiv_probe()
259 clkdiv[i].regmap = regmap; in spmi_pmic_clkdiv_probe()
260 clkdiv[i].cxo_period_ns = NSEC_PER_SEC / cxo_hz; in spmi_pmic_clkdiv_probe()
261 clkdiv[i].hw.init = &init; in spmi_pmic_clkdiv_probe()
263 ret = devm_clk_hw_register(dev, &clkdiv[i].hw); in spmi_pmic_clkdiv_probe()
272 { .compatible = "qcom,spmi-clkdiv" },
279 .name = "qcom,spmi-pmic-clkdiv",
286 MODULE_DESCRIPTION("QCOM SPMI PMIC clkdiv driver");