• Home
  • Raw
  • Download

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

1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/pwm/pwm-vt8500.c
15 #include <linux/pwm.h>
17 #include <linux/clk.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
53 struct clk *clk; member
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()
188 { .compatible = "via,vt8500-pwm", },
197 struct device_node *np = pdev->dev.of_node; in vt8500_pwm_probe()
201 dev_err(&pdev->dev, "invalid devicetree node\n"); in vt8500_pwm_probe()
202 return -EINVAL; in vt8500_pwm_probe()
205 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); in vt8500_pwm_probe()
207 return -ENOMEM; in vt8500_pwm_probe()
209 chip->chip.dev = &pdev->dev; in vt8500_pwm_probe()
210 chip->chip.ops = &vt8500_pwm_ops; in vt8500_pwm_probe()
211 chip->chip.of_xlate = of_pwm_xlate_with_flags; in vt8500_pwm_probe()
212 chip->chip.of_pwm_n_cells = 3; in vt8500_pwm_probe()
213 chip->chip.base = -1; in vt8500_pwm_probe()
214 chip->chip.npwm = VT8500_NR_PWMS; in vt8500_pwm_probe()
216 chip->clk = devm_clk_get(&pdev->dev, NULL); in vt8500_pwm_probe()
217 if (IS_ERR(chip->clk)) { in vt8500_pwm_probe()
218 dev_err(&pdev->dev, "clock source not specified\n"); in vt8500_pwm_probe()
219 return PTR_ERR(chip->clk); in vt8500_pwm_probe()
223 chip->base = devm_ioremap_resource(&pdev->dev, r); in vt8500_pwm_probe()
224 if (IS_ERR(chip->base)) in vt8500_pwm_probe()
225 return PTR_ERR(chip->base); in vt8500_pwm_probe()
227 ret = clk_prepare(chip->clk); in vt8500_pwm_probe()
229 dev_err(&pdev->dev, "failed to prepare clock\n"); in vt8500_pwm_probe()
233 ret = pwmchip_add(&chip->chip); in vt8500_pwm_probe()
235 dev_err(&pdev->dev, "failed to add PWM chip\n"); in vt8500_pwm_probe()
236 clk_unprepare(chip->clk); in vt8500_pwm_probe()
250 return -ENODEV; in vt8500_pwm_remove()
252 clk_unprepare(chip->clk); in vt8500_pwm_remove()
254 return pwmchip_remove(&chip->chip); in vt8500_pwm_remove()
261 .name = "vt8500-pwm",
267 MODULE_DESCRIPTION("VT8500 PWM Driver");