Lines Matching +full:clk +full:- +full:pwm

1 // SPDX-License-Identifier: GPL-2.0
3 * Clock based PWM controller
7 * This is an "adapter" driver that allows PWM consumers to use
8 * system clocks with duty cycle control as PWM outputs.
11 * - Due to the fact that exact behavior depends on the underlying
13 * - Underlying clock may not be able to give 0% or 100% duty cycle
15 * - When the PWM is disabled, the clock will be disabled as well,
17 * - The clk API doesn't expose the necessary calls to implement
27 #include <linux/clk.h>
28 #include <linux/pwm.h>
31 struct clk *clk; member
40 static int pwm_clk_apply(struct pwm_chip *chip, struct pwm_device *pwm, in pwm_clk_apply() argument
46 u64 period = state->period; in pwm_clk_apply()
47 u64 duty_cycle = state->duty_cycle; in pwm_clk_apply()
49 if (!state->enabled) { in pwm_clk_apply()
50 if (pwm->state.enabled) { in pwm_clk_apply()
51 clk_disable(pcchip->clk); in pwm_clk_apply()
52 pcchip->clk_enabled = false; in pwm_clk_apply()
55 } else if (!pwm->state.enabled) { in pwm_clk_apply()
56 ret = clk_enable(pcchip->clk); in pwm_clk_apply()
59 pcchip->clk_enabled = true; in pwm_clk_apply()
63 * We have to enable the clk before setting the rate and duty_cycle, in pwm_clk_apply()
64 * that however results in a window where the clk is on with a in pwm_clk_apply()
70 ret = clk_set_rate(pcchip->clk, rate); in pwm_clk_apply()
74 if (state->polarity == PWM_POLARITY_INVERSED) in pwm_clk_apply()
75 duty_cycle = period - duty_cycle; in pwm_clk_apply()
77 return clk_set_duty_cycle(pcchip->clk, duty_cycle, period); in pwm_clk_apply()
90 chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*pcchip)); in pwm_clk_probe()
95 pcchip->clk = devm_clk_get_prepared(&pdev->dev, NULL); in pwm_clk_probe()
96 if (IS_ERR(pcchip->clk)) in pwm_clk_probe()
97 return dev_err_probe(&pdev->dev, PTR_ERR(pcchip->clk), in pwm_clk_probe()
100 chip->ops = &pwm_clk_ops; in pwm_clk_probe()
104 return dev_err_probe(&pdev->dev, ret, "Failed to add pwm chip\n"); in pwm_clk_probe()
117 if (pcchip->clk_enabled) in pwm_clk_remove()
118 clk_disable(pcchip->clk); in pwm_clk_remove()
122 { .compatible = "clk-pwm", },
129 .name = "pwm-clk",
137 MODULE_ALIAS("platform:pwm-clk");
139 MODULE_DESCRIPTION("Clock based PWM driver");