Lines Matching +full:clk +full:- +full:pwm
1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/pwm/pwm-vt8500.c
16 #include <linux/pwm.h>
18 #include <linux/clk.h>
28 #define REG_CTRL(pwm) (((pwm) << 4) + 0x00) argument
29 #define REG_SCALAR(pwm) (((pwm) << 4) + 0x04) argument
30 #define REG_PERIOD(pwm) (((pwm) << 4) + 0x08) argument
31 #define REG_DUTY(pwm) (((pwm) << 4) + 0x0C) argument
50 struct clk *clk; member
61 while ((readl(vt8500->base + REG_STATUS) & mask) && --loops) in vt8500_pwm_busy_wait()
65 dev_warn(vt8500->chip.dev, "Waiting for status bits 0x%x to clear timed out\n", in vt8500_pwm_busy_wait()
69 static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in vt8500_pwm_config() argument
78 err = clk_enable(vt8500->clk); in vt8500_pwm_config()
80 dev_err(chip->dev, "failed to enable clock\n"); in vt8500_pwm_config()
84 c = clk_get_rate(vt8500->clk); in vt8500_pwm_config()
91 prescale = (period_cycles - 1) / 4096; in vt8500_pwm_config()
92 pv = period_cycles / (prescale + 1) - 1; in vt8500_pwm_config()
97 clk_disable(vt8500->clk); in vt8500_pwm_config()
98 return -EINVAL; in vt8500_pwm_config()
105 writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); in vt8500_pwm_config()
106 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); in vt8500_pwm_config()
108 writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm)); in vt8500_pwm_config()
109 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE); in vt8500_pwm_config()
111 writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm)); in vt8500_pwm_config()
112 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE); in vt8500_pwm_config()
114 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_config()
116 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_config()
117 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_config()
119 clk_disable(vt8500->clk); in vt8500_pwm_config()
123 static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in vt8500_pwm_enable() argument
129 err = clk_enable(vt8500->clk); in vt8500_pwm_enable()
131 dev_err(chip->dev, "failed to enable clock\n"); in vt8500_pwm_enable()
135 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_enable()
137 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_enable()
138 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_enable()
143 static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in vt8500_pwm_disable() argument
148 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_disable()
150 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_disable()
151 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_disable()
153 clk_disable(vt8500->clk); in vt8500_pwm_disable()
157 struct pwm_device *pwm, in vt8500_pwm_set_polarity() argument
163 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_set_polarity()
170 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_set_polarity()
171 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_set_polarity()
176 static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in vt8500_pwm_apply() argument
180 bool enabled = pwm->state.enabled; in vt8500_pwm_apply()
182 if (state->polarity != pwm->state.polarity) { in vt8500_pwm_apply()
184 * Changing the polarity of a running PWM is only allowed when in vt8500_pwm_apply()
185 * the PWM driver implements ->apply(). in vt8500_pwm_apply()
188 vt8500_pwm_disable(chip, pwm); in vt8500_pwm_apply()
193 err = vt8500_pwm_set_polarity(chip, pwm, state->polarity); in vt8500_pwm_apply()
198 if (!state->enabled) { in vt8500_pwm_apply()
200 vt8500_pwm_disable(chip, pwm); in vt8500_pwm_apply()
206 * We cannot skip calling ->config even if state->period == in vt8500_pwm_apply()
207 * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle in vt8500_pwm_apply()
209 * pwm_apply_might_sleep because of !state->enabled and so the two values in in vt8500_pwm_apply()
210 * pwm->state might not be configured in hardware. in vt8500_pwm_apply()
212 err = vt8500_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); in vt8500_pwm_apply()
217 err = vt8500_pwm_enable(chip, pwm); in vt8500_pwm_apply()
228 { .compatible = "via,vt8500-pwm", },
236 struct device_node *np = pdev->dev.of_node; in vt8500_pwm_probe()
240 dev_err(&pdev->dev, "invalid devicetree node\n"); in vt8500_pwm_probe()
241 return -EINVAL; in vt8500_pwm_probe()
244 vt8500 = devm_kzalloc(&pdev->dev, sizeof(*vt8500), GFP_KERNEL); in vt8500_pwm_probe()
246 return -ENOMEM; in vt8500_pwm_probe()
248 vt8500->chip.dev = &pdev->dev; in vt8500_pwm_probe()
249 vt8500->chip.ops = &vt8500_pwm_ops; in vt8500_pwm_probe()
250 vt8500->chip.npwm = VT8500_NR_PWMS; in vt8500_pwm_probe()
252 vt8500->clk = devm_clk_get(&pdev->dev, NULL); in vt8500_pwm_probe()
253 if (IS_ERR(vt8500->clk)) { in vt8500_pwm_probe()
254 dev_err(&pdev->dev, "clock source not specified\n"); in vt8500_pwm_probe()
255 return PTR_ERR(vt8500->clk); in vt8500_pwm_probe()
258 vt8500->base = devm_platform_ioremap_resource(pdev, 0); in vt8500_pwm_probe()
259 if (IS_ERR(vt8500->base)) in vt8500_pwm_probe()
260 return PTR_ERR(vt8500->base); in vt8500_pwm_probe()
262 ret = clk_prepare(vt8500->clk); in vt8500_pwm_probe()
264 dev_err(&pdev->dev, "failed to prepare clock\n"); in vt8500_pwm_probe()
268 ret = pwmchip_add(&vt8500->chip); in vt8500_pwm_probe()
270 dev_err(&pdev->dev, "failed to add PWM chip\n"); in vt8500_pwm_probe()
271 clk_unprepare(vt8500->clk); in vt8500_pwm_probe()
283 pwmchip_remove(&vt8500->chip); in vt8500_pwm_remove()
285 clk_unprepare(vt8500->clk); in vt8500_pwm_remove()
292 .name = "vt8500-pwm",
298 MODULE_DESCRIPTION("VT8500 PWM Driver");