Lines Matching +full:pwm +full:- +full:enable
1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/pwm/pwm-vt8500.c
15 #include <linux/pwm.h>
31 #define REG_CTRL(pwm) (((pwm) << 4) + 0x00) argument
32 #define REG_SCALAR(pwm) (((pwm) << 4) + 0x04) argument
33 #define REG_PERIOD(pwm) (((pwm) << 4) + 0x08) argument
34 #define REG_DUTY(pwm) (((pwm) << 4) + 0x0C) argument
64 while ((readl(vt8500->base + REG_STATUS) & mask) && --loops) in pwm_busy_wait()
68 dev_warn(vt8500->chip.dev, "Waiting for status bits 0x%x to clear timed out\n", in pwm_busy_wait()
72 static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in vt8500_pwm_config() argument
81 err = clk_enable(vt8500->clk); in vt8500_pwm_config()
83 dev_err(chip->dev, "failed to enable clock\n"); in vt8500_pwm_config()
87 c = clk_get_rate(vt8500->clk); in vt8500_pwm_config()
94 prescale = (period_cycles - 1) / 4096; in vt8500_pwm_config()
95 pv = period_cycles / (prescale + 1) - 1; in vt8500_pwm_config()
100 clk_disable(vt8500->clk); in vt8500_pwm_config()
101 return -EINVAL; in vt8500_pwm_config()
108 writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); in vt8500_pwm_config()
109 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); in vt8500_pwm_config()
111 writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm)); in vt8500_pwm_config()
112 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE); in vt8500_pwm_config()
114 writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm)); in vt8500_pwm_config()
115 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE); in vt8500_pwm_config()
117 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_config()
119 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_config()
120 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_config()
122 clk_disable(vt8500->clk); in vt8500_pwm_config()
126 static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in vt8500_pwm_enable() argument
132 err = clk_enable(vt8500->clk); in vt8500_pwm_enable()
134 dev_err(chip->dev, "failed to enable clock\n"); in vt8500_pwm_enable()
138 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_enable()
140 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_enable()
141 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_enable()
146 static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in vt8500_pwm_disable() argument
151 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_disable()
153 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_disable()
154 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_disable()
156 clk_disable(vt8500->clk); in vt8500_pwm_disable()
160 struct pwm_device *pwm, in vt8500_pwm_set_polarity() argument
166 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_set_polarity()
173 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm)); in vt8500_pwm_set_polarity()
174 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE); in vt8500_pwm_set_polarity()
180 .enable = vt8500_pwm_enable,
188 { .compatible = "via,vt8500-pwm", },
196 struct device_node *np = pdev->dev.of_node; in vt8500_pwm_probe()
200 dev_err(&pdev->dev, "invalid devicetree node\n"); in vt8500_pwm_probe()
201 return -EINVAL; in vt8500_pwm_probe()
204 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); in vt8500_pwm_probe()
206 return -ENOMEM; in vt8500_pwm_probe()
208 chip->chip.dev = &pdev->dev; in vt8500_pwm_probe()
209 chip->chip.ops = &vt8500_pwm_ops; in vt8500_pwm_probe()
210 chip->chip.npwm = VT8500_NR_PWMS; in vt8500_pwm_probe()
212 chip->clk = devm_clk_get(&pdev->dev, NULL); in vt8500_pwm_probe()
213 if (IS_ERR(chip->clk)) { in vt8500_pwm_probe()
214 dev_err(&pdev->dev, "clock source not specified\n"); in vt8500_pwm_probe()
215 return PTR_ERR(chip->clk); in vt8500_pwm_probe()
218 chip->base = devm_platform_ioremap_resource(pdev, 0); in vt8500_pwm_probe()
219 if (IS_ERR(chip->base)) in vt8500_pwm_probe()
220 return PTR_ERR(chip->base); in vt8500_pwm_probe()
222 ret = clk_prepare(chip->clk); in vt8500_pwm_probe()
224 dev_err(&pdev->dev, "failed to prepare clock\n"); in vt8500_pwm_probe()
228 ret = pwmchip_add(&chip->chip); in vt8500_pwm_probe()
230 dev_err(&pdev->dev, "failed to add PWM chip\n"); in vt8500_pwm_probe()
231 clk_unprepare(chip->clk); in vt8500_pwm_probe()
243 pwmchip_remove(&chip->chip); in vt8500_pwm_remove()
245 clk_unprepare(chip->clk); in vt8500_pwm_remove()
254 .name = "vt8500-pwm",
260 MODULE_DESCRIPTION("VT8500 PWM Driver");