Lines Matching +full:pwm +full:- +full:active +full:- +full:state
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ECAP PWM driver
5 * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
14 #include <linux/pwm.h>
49 static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, in ecap_pwm_config() argument
57 c = pc->clk_rate; in ecap_pwm_config()
66 c = pc->clk_rate; in ecap_pwm_config()
74 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_config()
79 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_config()
82 /* Update active registers if not running */ in ecap_pwm_config()
83 writel(duty_cycles, pc->mmio_base + CAP2); in ecap_pwm_config()
84 writel(period_cycles, pc->mmio_base + CAP1); in ecap_pwm_config()
88 * compare values. This helps current PWM period to in ecap_pwm_config()
91 writel(duty_cycles, pc->mmio_base + CAP4); in ecap_pwm_config()
92 writel(period_cycles, pc->mmio_base + CAP3); in ecap_pwm_config()
96 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_config()
99 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_config()
107 static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, in ecap_pwm_set_polarity() argument
115 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_set_polarity()
118 /* Duty cycle defines LOW period of PWM */ in ecap_pwm_set_polarity()
121 /* Duty cycle defines HIGH period of PWM */ in ecap_pwm_set_polarity()
124 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_set_polarity()
131 static int ecap_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) in ecap_pwm_enable() argument
136 /* Leave clock enabled on enabling PWM */ in ecap_pwm_enable()
143 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_enable()
145 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_enable()
150 static void ecap_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) in ecap_pwm_disable() argument
159 value = readw(pc->mmio_base + ECCTL2); in ecap_pwm_disable()
161 writew(value, pc->mmio_base + ECCTL2); in ecap_pwm_disable()
163 /* Disable clock on PWM disable */ in ecap_pwm_disable()
167 static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, in ecap_pwm_apply() argument
168 const struct pwm_state *state) in ecap_pwm_apply() argument
171 int enabled = pwm->state.enabled; in ecap_pwm_apply()
173 if (state->polarity != pwm->state.polarity) { in ecap_pwm_apply()
176 ecap_pwm_disable(chip, pwm); in ecap_pwm_apply()
180 err = ecap_pwm_set_polarity(chip, pwm, state->polarity); in ecap_pwm_apply()
185 if (!state->enabled) { in ecap_pwm_apply()
187 ecap_pwm_disable(chip, pwm); in ecap_pwm_apply()
191 if (state->period > NSEC_PER_SEC) in ecap_pwm_apply()
192 return -ERANGE; in ecap_pwm_apply()
194 err = ecap_pwm_config(chip, pwm, state->duty_cycle, in ecap_pwm_apply()
195 state->period, enabled); in ecap_pwm_apply()
200 return ecap_pwm_enable(chip, pwm); in ecap_pwm_apply()
210 { .compatible = "ti,am3352-ecap" },
211 { .compatible = "ti,am33xx-ecap" },
218 struct device_node *np = pdev->dev.of_node; in ecap_pwm_probe()
224 chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*pc)); in ecap_pwm_probe()
229 clk = devm_clk_get(&pdev->dev, "fck"); in ecap_pwm_probe()
231 if (of_device_is_compatible(np, "ti,am33xx-ecap")) { in ecap_pwm_probe()
232 dev_warn(&pdev->dev, "Binding is obsolete.\n"); in ecap_pwm_probe()
233 clk = devm_clk_get(pdev->dev.parent, "fck"); in ecap_pwm_probe()
238 dev_err(&pdev->dev, "failed to get clock\n"); in ecap_pwm_probe()
242 pc->clk_rate = clk_get_rate(clk); in ecap_pwm_probe()
243 if (!pc->clk_rate) { in ecap_pwm_probe()
244 dev_err(&pdev->dev, "failed to get clock rate\n"); in ecap_pwm_probe()
245 return -EINVAL; in ecap_pwm_probe()
248 chip->ops = &ecap_pwm_ops; in ecap_pwm_probe()
250 pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); in ecap_pwm_probe()
251 if (IS_ERR(pc->mmio_base)) in ecap_pwm_probe()
252 return PTR_ERR(pc->mmio_base); in ecap_pwm_probe()
254 ret = devm_pwmchip_add(&pdev->dev, chip); in ecap_pwm_probe()
256 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); in ecap_pwm_probe()
261 pm_runtime_enable(&pdev->dev); in ecap_pwm_probe()
268 pm_runtime_disable(&pdev->dev); in ecap_pwm_remove()
276 pc->ctx.ecctl2 = readw(pc->mmio_base + ECCTL2); in ecap_pwm_save_context()
277 pc->ctx.cap4 = readl(pc->mmio_base + CAP4); in ecap_pwm_save_context()
278 pc->ctx.cap3 = readl(pc->mmio_base + CAP3); in ecap_pwm_save_context()
286 writel(pc->ctx.cap3, pc->mmio_base + CAP3); in ecap_pwm_restore_context()
287 writel(pc->ctx.cap4, pc->mmio_base + CAP4); in ecap_pwm_restore_context()
288 writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2); in ecap_pwm_restore_context()
294 struct pwm_device *pwm = chip->pwms; in ecap_pwm_suspend() local
298 /* Disable explicitly if PWM is running */ in ecap_pwm_suspend()
299 if (pwm_is_enabled(pwm)) in ecap_pwm_suspend()
308 struct pwm_device *pwm = chip->pwms; in ecap_pwm_resume() local
310 /* Enable explicitly if PWM was running */ in ecap_pwm_resume()
311 if (pwm_is_enabled(pwm)) in ecap_pwm_resume()
331 MODULE_DESCRIPTION("ECAP PWM driver");